VirtualBox

Ignore:
Timestamp:
Jul 18, 2020 9:17:43 PM (4 years ago)
Author:
vboxsync
Message:

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

File:
1 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);
Note: See TracChangeset for help on using the changeset viewer.

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