Changeset 85382 in vbox
- Timestamp:
- Jul 18, 2020 11:33:58 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/path.h
r85313 r85382 521 521 522 522 /** 523 * Finds the common path in a given set of paths. 524 * 525 * The paths are not made absolute or real, they are taken as given. 526 * 527 * @returns Length (in characters) of the common path, 0 if not found. 528 * @param cPaths Number of paths in \a papszPaths. 529 * @param papszPaths Array of paths to find common path for. 530 */ 531 RTDECL(size_t) RTPathFindCommon(size_t cPaths, const char * const *papszPaths); 532 533 /** 523 534 * Finds the common path in a given set of paths, extended version. 524 535 * 525 * Note: This does not check paths for existience or other things (e.g. symlinks).536 * The paths are not made absolute or real, they are taken as given. 526 537 * 527 538 * @returns Length (in characters) of the common path, 0 if not found. 528 * @param papcszPaths Array of paths to find common path for. 529 * @param cPaths Number of paths in \a papcszPaths. 530 * @param szSeparator Path separator to use for comparision. 531 */ 532 RTDECL(size_t) RTPathFindCommonEx(const char * const *papcszPaths, size_t cPaths, char szSeparator); 533 534 /** 535 * Finds the common path in a given set of paths. 536 * 537 * Uses the system's native slash as separator. 538 * Note: This does not check paths for existience or other things (e.g. symlinks). 539 * 540 * @returns Length (in characters) of the common path, 0 if not found. 541 * @param papcszPaths Array of paths to find common path for. 542 * @param cPaths Number of paths in \a papcszPaths. 543 */ 544 RTDECL(size_t) RTPathFindCommon(const char * const *papcszPaths, size_t cPaths); 539 * @param cPaths Number of paths in \a papszPaths. 540 * @param papszPaths Array of paths to find common path for. 541 * @param fFlags RTPATH_STR_F_STYLE_XXX. Other RTPATH_STR_F_XXX flags 542 * will be ignored. 543 */ 544 RTDECL(size_t) RTPathFindCommonEx(size_t cPaths, const char * const *papszPaths, uint32_t fFlags); 545 545 546 546 /** -
trunk/src/VBox/GuestHost/DragAndDrop/DnDTransferList.cpp
r85373 r85382 582 582 if (!pList->pszPathRootAbs) 583 583 { 584 size_t cchRootPath = RTPathFindCommon( papcszPaths, cPaths);584 size_t cchRootPath = RTPathFindCommon(cPaths, papcszPaths); 585 585 if (cchRootPath) 586 586 { -
trunk/src/VBox/GuestHost/DragAndDrop/testcase/tstDnDPath.cpp
r85381 r85382 18 18 #include <iprt/assert.h> 19 19 #include <iprt/env.h> 20 #include <iprt/err .h>20 #include <iprt/errcore.h> 21 21 #include <iprt/path.h> 22 22 #include <iprt/string.h> -
trunk/src/VBox/GuestHost/DragAndDrop/testcase/tstDnDTransferObject.cpp
r85381 r85382 18 18 #include <iprt/assert.h> 19 19 #include <iprt/env.h> 20 #include <iprt/err .h>20 #include <iprt/errcore.h> 21 21 #include <iprt/mem.h> 22 22 #include <iprt/string.h> -
trunk/src/VBox/Runtime/common/path/RTPathFindCommon.cpp
r85374 r85382 35 35 36 36 37 RTDECL(size_t) RTPathFindCommonEx( const char * const *papcszPaths, size_t cPaths, char szSeparator)37 RTDECL(size_t) RTPathFindCommonEx(size_t cPaths, const char * const *papszPaths, uint32_t fFlags) 38 38 { 39 Assert PtrReturn(papcszPaths, 0);40 Assert Return(cPaths, 0);41 AssertReturn( szSeparator != '\0', 0);39 AssertReturn(cPaths > 0, 0); 40 AssertPtrReturn(papszPaths, 0); 41 AssertReturn(RTPATH_STR_F_IS_VALID(fFlags, 0), 0); 42 42 43 const char *pcszRef = papcszPaths[0]; /* The reference we're comparing with. */ 43 /** @todo r=bird: Extremely naive code. 44 * - The original idea of taking either '/' or '\\' as separators is very out of 45 * touch with the rest of path.h. On DOS based systems we need to handle both 46 * of those as well as ':'. 47 * - Why compare pszRef with itself? 48 * - Why derefernece pszRef[cch] for each other path. 49 * - Why perform NULL checks for each outer iteration. 50 * - Why perform '\0' check before comparing with pszRef[cch]? 51 * It's sufficient to check if pszRef[cch] is '\0'. 52 * - Why backtrack to the last path separator? It won't return the expected 53 * result for cPaths=1, unless the path ends with a separator. 54 * - Multiple consequtive path separators must be treated as a single one (most 55 * of the time anyways - UNC crap). 56 */ 57 const char *pszRef = papszPaths[0]; /* The reference we're comparing with. */ 58 const char chNaiveSep = (fFlags & RTPATH_STR_F_STYLE_MASK) == RTPATH_STR_F_STYLE_HOST 59 ? RTPATH_SLASH 60 : (fFlags & RTPATH_STR_F_STYLE_MASK) == RTPATH_STR_F_STYLE_DOS ? '\\' : '/'; 44 61 45 62 size_t cch = 0; … … 48 65 for (size_t i = 0; i < cPaths; ++i) 49 66 { 50 const char *pcszPath = pap cszPaths[i];67 const char *pcszPath = papszPaths[i]; 51 68 if ( pcszPath 52 69 && pcszPath[cch] 53 && pcszPath[cch] == p cszRef[cch])70 && pcszPath[cch] == pszRef[cch]) 54 71 continue; 55 72 56 73 while ( cch 57 && p cszRef[--cch] != szSeparator) { }74 && pszRef[--cch] != chNaiveSep) { } 58 75 59 76 return cch ? cch + 1 : 0; 60 77 } 61 } 62 while (++cch); 78 } while (++cch); 63 79 64 80 return 0; … … 67 83 68 84 69 RTDECL(size_t) RTPathFindCommon( const char * const *papcszPaths, size_t cPaths)85 RTDECL(size_t) RTPathFindCommon(size_t cPaths, const char * const *papszPaths) 70 86 { 71 return RTPathFindCommonEx( papcszPaths, cPaths, RTPATH_SLASH);87 return RTPathFindCommonEx(cPaths, papszPaths, RTPATH_STR_F_STYLE_HOST); 72 88 } 73 89 RT_EXPORT_SYMBOL(RTPathFindCommon); -
trunk/src/VBox/Runtime/testcase/tstRTPathFindCommon.cpp
r85312 r85382 46 46 struct 47 47 { 48 char const *papszPath1; 49 char const *papszPath2; 50 char const *papszPath3; 51 char const *papszPatCommon; 48 char const *apszPaths[3]; 49 char const *pszCommon; 50 uint32_t fFlags; 52 51 } aTests[] = 53 52 { 54 53 /* Simple stuff first. */ 55 { "", "", "", ""},56 { "none", "none", "", ""},54 { { "", "", "" }, "", RTPATH_STR_F_STYLE_UNIX }, 55 { { "none", "none", "" }, "", RTPATH_STR_F_STYLE_UNIX }, 57 56 /* Missing start slash. */ 58 { "/path/to/stuff1", "path/to/stuff2", "", ""},57 { { "/path/to/stuff1", "path/to/stuff2", "" }, "", RTPATH_STR_F_STYLE_UNIX }, 59 58 /* Working stuff. */ 60 { "/path/to/stuff1", "/path/to/stuff2", "/path/to/stuff3", "/path/to/"},61 { "/path/to/stuff1", "/path/to/", "/path/", "/path/"},62 { "/path/to/stuff1", "/", "/path/", ""},63 { "/path/to/../stuff1", "./../", "/path/to/stuff2/..", "" }59 { { "/path/to/stuff1", "/path/to/stuff2", "/path/to/stuff3" }, "/path/to/", RTPATH_STR_F_STYLE_UNIX }, 60 { { "/path/to/stuff1", "/path/to/", "/path/" }, "/path/", RTPATH_STR_F_STYLE_UNIX }, 61 { { "/path/to/stuff1", "/", "/path/" }, "", RTPATH_STR_F_STYLE_UNIX }, 62 { { "/path/to/../stuff1", "./../", "/path/to/stuff2/.." }, "", RTPATH_STR_F_STYLE_UNIX }, 64 63 }; 65 64 66 const size_t cNumPaths = 3; /* Number of paths to compare. */ 65 for (size_t i = 0; i < RT_ELEMENTS(aTests); i++) 66 { 67 size_t cPaths = RT_ELEMENTS(aTests[i].apszPaths); 68 while (cPaths > 0 && aTests[i].apszPaths[cPaths - 1] == NULL) 69 cPaths--; 67 70 68 size_t cchRes; 69 for (size_t i = 0; i < RT_ELEMENTS(aTests); i++) 70 RTTEST_CHECK_MSG(hTest, (cchRes = RTPathFindCommonEx((const char * const *)&aTests[i], cNumPaths, '/')) == strlen(aTests[i].papszPatCommon), 71 (hTest, "Test %zu failed: Got %zu, expected %zu\n", i, cchRes, strlen(aTests[i].papszPatCommon))); 71 size_t const cchCommon = RTPathFindCommonEx(cPaths, aTests[i].apszPaths, aTests[i].fFlags); 72 size_t const cchExpect = strlen(aTests[i].pszCommon); 73 if (cchCommon != cchExpect) 74 RTTestFailed(hTest, 75 "Test %zu failed: got %zu, expected %zu (cPaths=%zu: %s %s %s)", i, cchCommon, cchExpect, cPaths, 76 aTests[i].apszPaths[0], aTests[i].apszPaths[1], aTests[i].apszPaths[2]); 77 } 72 78 73 79 /*
Note:
See TracChangeset
for help on using the changeset viewer.