VirtualBox

Changeset 85384 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Jul 18, 2020 9:17:43 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
139398
Message:

iprt/path.h: Reimplemented RTPathFindCommon[Ex].

Location:
trunk/src/VBox/Runtime
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/path/RTPathFindCommon.cpp

    r85382 r85384  
    3030*********************************************************************************************************************************/
    3131#include "internal/iprt.h"
     32#include <iprt/path.h>
     33
     34#include <iprt/alloca.h>
    3235#include <iprt/assert.h>
    3336#include <iprt/errcore.h>
    34 #include <iprt/path.h>
     37#include <iprt/mem.h>
     38#include <iprt/string.h>
     39#include <iprt/uni.h>
     40
     41
     42#define RTPATH_TEMPLATE_CPP_H "RTPathFindCommon.cpp.h"
     43#include "rtpath-expand-template.cpp.h"
    3544
    3645
    3746RTDECL(size_t) RTPathFindCommonEx(size_t cPaths, const char * const *papszPaths, uint32_t fFlags)
    3847{
     48    /*
     49     * Validate input.
     50     */
     51    AssertReturn(RTPATH_STR_F_IS_VALID(fFlags, RTPATHFINDCOMMON_F_IGNORE_DOTDOT), 0);
    3952    AssertReturn(cPaths > 0, 0);
    4053    AssertPtrReturn(papszPaths, 0);
    41     AssertReturn(RTPATH_STR_F_IS_VALID(fFlags, 0), 0);
     54    size_t i = cPaths;
     55    while (i-- > 0)
     56        AssertPtrReturn(papszPaths[i], 0);
    4257
    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).
     58    /*
     59     * Duplicate papszPaths so we can have individual positions in each path.
     60     * Use the stack if we haven't got too many paths.
    5661     */
    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 ? '\\' : '/';
     62    void        *pvFree;
     63    const char **papszCopy;
     64    size_t      cbNeeded = cPaths * sizeof(papszCopy[0]);
     65    if (cbNeeded <= _2K)
     66    {
     67        pvFree = NULL;
     68        papszCopy = (const char **)alloca(cbNeeded);
     69    }
     70    else
     71    {
     72        pvFree = RTMemTmpAlloc(cbNeeded);
     73        papszCopy = (const char **)pvFree;
     74    }
     75    AssertReturn(papszCopy, 0);
     76    memcpy(papszCopy, papszPaths, cbNeeded);
    6177
    62     size_t cch = 0;
    63     do
     78    /*
     79     * Invoke the worker for the selected path style.
     80     */
     81    size_t cchRet;
     82    switch (fFlags & RTPATH_STR_F_STYLE_MASK)
    6483    {
    65         for (size_t i = 0; i < cPaths; ++i)
    66         {
    67             const char *pcszPath = papszPaths[i];
    68             if (   pcszPath
    69                 && pcszPath[cch]
    70                 && pcszPath[cch] == pszRef[cch])
    71                 continue;
     84#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
     85        case RTPATH_STR_F_STYLE_HOST:
     86#endif
     87        case RTPATH_STR_F_STYLE_DOS:
     88            cchRet= rtPathFindCommonStyleDos(cPaths, papszCopy, fFlags);
     89            break;
    7290
    73             while (   cch
    74                    && pszRef[--cch] != chNaiveSep) { }
     91#if RTPATH_STYLE != RTPATH_STR_F_STYLE_DOS
     92        case RTPATH_STR_F_STYLE_HOST:
     93#endif
     94        case RTPATH_STR_F_STYLE_UNIX:
     95            cchRet = rtPathFindCommonStyleUnix(cPaths, papszCopy, fFlags);
     96            break;
    7597
    76             return cch ? cch + 1 : 0;
    77         }
    78     } while (++cch);
     98        default:
     99            AssertFailedStmt(cchRet = 0); /* impossible */
     100    }
    79101
    80     return 0;
     102    /*
     103     * Clean up and return.
     104     */
     105    if (pvFree)
     106        RTMemTmpFree(pvFree);
     107    return cchRet;
    81108}
    82109RT_EXPORT_SYMBOL(RTPathFindCommonEx);
  • trunk/src/VBox/Runtime/testcase/tstRTPath.cpp

    r85383 r85384  
    371371        { { "",                     "",                 "",                     NULL, },            RTPATH_STR_F_STYLE_UNIX,
    372372            "" },
     373        { { "",                     "",                 "",                     NULL, },            RTPATH_STR_F_STYLE_DOS,
     374            "" },
    373375        { { "none",                 "none",             "",                     NULL, },            RTPATH_STR_F_STYLE_UNIX,
    374376            "" },
    375         /* Missing start slash. */
     377        { { "none",                 "none",             "",                     NULL, },            RTPATH_STR_F_STYLE_DOS,
     378            "" },
     379        { { "same",                 "same",             "same",                 "same", },          RTPATH_STR_F_STYLE_UNIX,
     380            "same" },
     381        { { "same",                 "same",             "same",                 "same", },          RTPATH_STR_F_STYLE_DOS,
     382            "same" },
     383        /* More complicated. */
    376384        { { "/path/to/stuff1",      "path/to/stuff2",   NULL,                   NULL, },            RTPATH_STR_F_STYLE_UNIX,
    377385            "" },
    378         /* Working stuff. */
    379386        { { "/path/to/stuff1",      "/path/to/stuff2",  "/path/to/stuff3",      NULL, },            RTPATH_STR_F_STYLE_UNIX,
    380387            "/path/to/" },
     
    382389            "/path/" },
    383390        { { "/path/to/stuff1",      "/",                "/path/",               NULL, },            RTPATH_STR_F_STYLE_UNIX,
    384             "" },
     391            "/" },
    385392        { { "/path/to/../stuff1",   "./../",            "/path/to/stuff2/..",   NULL, },            RTPATH_STR_F_STYLE_UNIX,
    386393            "" },
    387 
    388 #if 0 /** @todo */
    389         /* Things that should be working that aren't: */
    390394        { { "a/single/path",        NULL,               NULL,                   NULL, },            RTPATH_STR_F_STYLE_UNIX,
    391395            "a/single/path" },
     
    396400        { { "c:/windows",           "c:\\program files", "C:\\AppData",         NULL, },            RTPATH_STR_F_STYLE_DOS,
    397401            "c:/" },
     402        { { "c:/windows",           "c:windows",        "C:system32",           NULL, },            RTPATH_STR_F_STYLE_DOS,
     403            "c:" },
     404        { { "c:/windows",           "d:windows",        "e:windows",            NULL, },            RTPATH_STR_F_STYLE_DOS,
     405            "" },
    398406        { { "//usr/bin/env",        "/usr//bin/env",   "/usr/bin///env",        "/usr/bin/env", },  RTPATH_STR_F_STYLE_UNIX,
    399407            "//usr/bin/env" },
     
    404412        { { "//./unc/is/weird",     "///./unc/is/weird", NULL,                  NULL, },            RTPATH_STR_F_STYLE_DOS,
    405413            "" },
     414        { { "//system360/share",    "//system370/share", "//system390/share",   NULL, },            RTPATH_STR_F_STYLE_DOS,
     415            "" },
     416        { { "//system370/share1",   "//sysTEM370/share2", "//SYsTeM370/share3", NULL, },            RTPATH_STR_F_STYLE_DOS,
     417            "//system370/" },
     418        { { "//system370/share1",   "Z:/",              NULL,                   NULL, },            RTPATH_STR_F_STYLE_DOS,
     419            "" },
     420        { { "//system370/share1",   "/",                NULL,                   NULL, },            RTPATH_STR_F_STYLE_DOS,
     421            "" },
     422        { { "//system370/share1",   "somedir",          NULL,                   NULL, },            RTPATH_STR_F_STYLE_DOS,
     423            "" },
    406424        { { "/path/to/stuff1",      "path/to/stuff2",   NULL,                   NULL, },            RTPATH_STR_F_STYLE_UNIX | RTPATH_STR_F_NO_START,
    407425            "/path/to/" },
    408426        { { "path/to/stuff1",       "//path\\/to\\stuff2", NULL,                NULL, },            RTPATH_STR_F_STYLE_DOS | RTPATH_STR_F_NO_START,
    409427            "path/to/" },
    410 
    411         /* '..' elements are not supported for now and leads to zero return. */
     428        /* '..' elements are not supported for now and leads to zero return, unless RTPATHFINDCOMMON_F_IGNORE_DOTDOT is given. */
    412429        { { "/usr/bin/env",         "/usr/../usr/bin/env", "/usr/bin/../bin/env", NULL, },          RTPATH_STR_F_STYLE_UNIX,
    413430            "" },
    414431        { { "/lib/",                "/lib/amd64/../lib.so", "/lib/i386/../libdl.so", NULL, },       RTPATH_STR_F_STYLE_UNIX,
    415432            "" },
    416 #endif
     433        { { "/lib/",                "/lib/amd64/../lib.so", "/lib/i386/../libdl.so", NULL, },       RTPATH_STR_F_STYLE_UNIX | RTPATHFINDCOMMON_F_IGNORE_DOTDOT,
     434            "/lib/" },
    417435    };
    418436
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette