VirtualBox

Changeset 45394 in vbox


Ignore:
Timestamp:
Apr 7, 2013 7:03:00 PM (12 years ago)
Author:
vboxsync
Message:

IPRT: A Study in Paths - Chapter 2: The splitting of a path into component strings.

Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/mangling.h

    r45393 r45394  
    953953# define RTPathSetTimesEx                               RT_MANGLER(RTPathSetTimesEx)
    954954# define RTPathSharedLibs                               RT_MANGLER(RTPathSharedLibs)
     955# define RTPathSplit                                    RT_MANGLER(RTPathSplit)
     956# define RTPathSplitATag                                RT_MANGLER(RTPathSplitATag)
     957# define RTPathSplitFree                                RT_MANGLER(RTPathSplitFree)
    955958# define RTPathStartsWith                               RT_MANGLER(RTPathStartsWith)
    956959# define RTPathStartsWithRoot                           RT_MANGLER(RTPathStartsWithRoot)
  • trunk/include/iprt/path.h

    r45391 r45394  
    4848#if !defined(___iprt_param_h) || defined(DOXYGEN_RUNNING)
    4949# define RTPATH_MAX         (4096 + 4)    /* (PATH_MAX + 1) on linux w/ some alignment */
     50#endif
     51
     52/** @def RTPATH_TAG
     53 * The default allocation tag used by the RTPath allocation APIs.
     54 *
     55 * When not defined before the inclusion of iprt/string.h, this will default to
     56 * the pointer to the current file name.  The string API will make of use of
     57 * this as pointer to a volatile but read-only string.
     58 */
     59#ifndef RTPATH_TAG
     60# define RTPATH_TAG     (__FILE__)
    5061#endif
    5162
     
    452463 * @note This is not set for lone root specifications (RTPATH_PROP_UNC,
    453464 *       RTPATH_PROP_ROOT_SLASH, or RTPATH_PROP_VOLUME).
    454  * @note The slash is not counted into the last component.  */
     465 * @note The slash is not counted into the last component. However, it is
     466 *       counted into cchPath. */
    455467#define RTPATH_PROP_DIR_SLASH       UINT16_C(0x0002)
    456468
     
    519531 * (All other components in a split or parsed path requies slashes added.) */
    520532#define RTPATH_PROP_FIRST_NEEDS_NO_SLASH(a_fProps) \
    521     ( (a_fProps) & (RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_VOLUME | RTPATH_PROP_UNC) )
     533    RT_BOOL( (a_fProps) & (RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_VOLUME | RTPATH_PROP_UNC) )
    522534
    523535/** Macro to determin whether there is a root specification of any kind
    524536 * (unix, volumes, unc). */
    525537#define RTPATH_PROP_HAS_ROOT_SPEC(a_fProps) \
    526     ( (a_fProps) & (RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_VOLUME | RTPATH_PROP_UNC) )
     538    RT_BOOL( (a_fProps) & (RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_VOLUME | RTPATH_PROP_UNC) )
    527539
    528540/** @} */
     
    615627     * component lengths and necessary separators.
    616628     * Do NOT use this to index in the source path in case it contains
    617      * unnecessary slashes that RTPathParsed has ignored here. */
     629     * unnecessary slashes that RTPathSplit has ignored here. */
    618630    uint16_t    cchPath;
    619631    /** Reserved (internal use).  */
     
    656668 *                              (variable sized array at the end).  Must be at
    657669 *                              least the size of RTPATHSPLIT.
     670 * @param   fFlags              Combination of RTPATH_STR_F_XXX flags.
     671 *                              Most users will pass 0.
    658672 *
    659673 * @sa      RTPathSplitA, RTPathParse.
    660674 */
    661 RTDECL(int) RTPathSplit(const char *pszPath, PRTPATHSPLIT pSplit, size_t cbSplit);
     675RTDECL(int) RTPathSplit(const char *pszPath, PRTPATHSPLIT pSplit, size_t cbSplit, uint32_t fFlags);
    662676
    663677/**
     
    673687 *                              success.  This must be freed by calling
    674688 *                              RTPathSplitFree().
     689 * @param   fFlags              Combination of RTPATH_STR_F_XXX flags.
     690 *                              Most users will pass 0.
    675691 * @sa      RTPathSplitFree, RTPathSplit, RTPathParse.
    676692 */
    677 RTDECL(int) RTPathSplitA(const char *pszPath, PRTPATHSPLIT *ppSplit);
     693#define  RTPathSplitA(pszPath, ppSplit, fFlags)     RTPathSplitATag(pszPath, ppSplit, fFlags, RTPATH_TAG)
     694
     695/**
     696 * Splits the path into individual component strings, allocating the buffer on
     697 * the default thread heap.
     698 *
     699 * @returns IPRT status code.
     700 * @retval  VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer.
     701 * @retval  VERR_PATH_ZERO_LENGTH if the path is empty.
     702 *
     703 * @param   pszPath             The path to parse.
     704 * @param   ppSplit             Where to return the pointer to the output on
     705 *                              success.  This must be freed by calling
     706 *                              RTPathSplitFree().
     707 * @param   fFlags              Combination of RTPATH_STR_F_XXX flags.
     708 *                              Most users will pass 0.
     709 * @param   pszTag              Allocation tag used for statistics and such.
     710 * @sa      RTPathSplitFree, RTPathSplit, RTPathParse.
     711 */
     712RTDECL(int) RTPathSplitATag(const char *pszPath, PRTPATHSPLIT *ppSplit, uint32_t fFlags, const char *pszTag);
    678713
    679714/**
  • trunk/src/VBox/Runtime/Makefile.kmk

    r45389 r45394  
    366366        common/path/RTPathRealDup.cpp \
    367367        common/path/RTPathRmCmd.cpp \
     368        common/path/RTPathSplit.cpp \
     369        common/path/RTPathSplitA.cpp \
    368370        common/path/RTPathStartsWithRoot.cpp \
    369371        common/path/RTPathStripExt.cpp \
     
    17101712        common/path/RTPathHasExt.cpp \
    17111713        common/path/RTPathHasPath.cpp \
    1712         common/path/RTPathParse.cpp \
    17131714        common/path/RTPathParseSimple.cpp \
    17141715        common/path/RTPathRealDup.cpp \
  • trunk/src/VBox/Runtime/common/path/RTPathParse.cpp.h

    r45391 r45394  
    193193                {
    194194                    if (!(fFlags & RTPATH_STR_F_NO_END))
    195                         fProps |= RTPATH_PROP_DIR_SLASH; /* (not counted) */
     195                    {
     196                        fProps |= RTPATH_PROP_DIR_SLASH; /* (not counted in component, but in cchPath) */
     197                        cchPath++;
     198                    }
    196199                    else
    197200                        fProps |= RTPATH_PROP_EXTRA_SLASHES;
  • trunk/src/VBox/Runtime/testcase/tstRTPath.cpp

    r45391 r45394  
    3939
    4040
    41 static void testParser(RTTEST hTest)
     41static void testParserAndSplitter(RTTEST hTest)
    4242{
    43     RTTestSub(hTest, "RTPathParse");
    44 
    4543    static struct
    4644    {
     
    5351    } const s_aTests[] =
    5452    {
     53        { 2,  5,  5,  "/bin/",            RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_DIR_SLASH,                                                RTPATH_STR_F_STYLE_UNIX },
    5554        { 2, 13,  9,  "C:/Config.sys",    RTPATH_PROP_VOLUME | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,       RTPATH_STR_F_STYLE_DOS },
    5655        { 2, 13, 10,  "C://Config.sys",   RTPATH_PROP_VOLUME | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_DOS },
     
    6564        { 1,  1,  1,  "/",                RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE,                                                                        RTPATH_STR_F_STYLE_UNIX },
    6665        { 2,  4,  4,  "/bin",             RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
    67         { 2,  4,  5,  "/bin/",            RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_DIR_SLASH,                                                RTPATH_STR_F_STYLE_UNIX },
     66        { 2,  5,  5,  "/bin/",            RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_DIR_SLASH,                                                RTPATH_STR_F_STYLE_UNIX },
    6867        { 3,  7,  7,  "/bin/ls",          RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATH_STR_F_STYLE_UNIX },
    6968        { 3,  12, 7,  "/etc/rc.conf",     RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,                            RTPATH_STR_F_STYLE_UNIX },
     
    7271        { 3,  6,  7,  "/.//bin",          RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_DOT_REFS | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
    7372        { 1,  3,  3,  "bin",              RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME,                                                                          RTPATH_STR_F_STYLE_UNIX },
    74         { 1,  3,  4,  "bin/",             RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH,                                                                         RTPATH_STR_F_STYLE_UNIX },
    75         { 1,  3,  7,  "bin////",          RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH | RTPATH_PROP_EXTRA_SLASHES,                                             RTPATH_STR_F_STYLE_UNIX },
     73        { 1,  4,  4,  "bin/",             RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH,                                                                         RTPATH_STR_F_STYLE_UNIX },
     74        { 1,  4,  7,  "bin////",          RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH | RTPATH_PROP_EXTRA_SLASHES,                                             RTPATH_STR_F_STYLE_UNIX },
    7675        { 3, 10, 10,  "bin/../usr",       RTPATH_PROP_RELATIVE | RTPATH_PROP_DOTDOT_REFS | RTPATH_PROP_FILENAME,                                                RTPATH_STR_F_STYLE_UNIX },
    7776        { 4, 11, 11,  "/bin/../usr",      RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE | RTPATH_PROP_DOTDOT_REFS | RTPATH_PROP_FILENAME,                       RTPATH_STR_F_STYLE_UNIX },
     
    9190    {
    9291        RTPATHPARSED    Parsed;
     92        RTPATHSPLIT     Split;
    9393        uint8_t         ab[4096];
    9494    } u;
    9595
     96    RTTestSub(hTest, "RTPathParse");
    9697    for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
    9798    {
     99        memset(&u, i & 1 ? 0xff : 0, sizeof(u));
    98100        int rc = RTPathParse(s_aTests[i].pszPath, &u.Parsed, sizeof(u), s_aTests[i].fFlags);
    99101        if (   rc != VINF_SUCCESS
     
    114116                                 s_aTests[i].offSuffix, u.Parsed.offSuffix,
    115117                                 s_aTests[i].cchPath,   u.Parsed.cchPath);
     118        }
     119    }
     120
     121    RTTestSub(hTest, "RTPathSplit");
     122    for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
     123    {
     124        memset(&u, i & 1 ? 0xff : 0, sizeof(u));
     125        int rc = RTPathSplit(s_aTests[i].pszPath, &u.Split, sizeof(u), s_aTests[i].fFlags);
     126        if (   rc != VINF_SUCCESS
     127            || s_aTests[i].cComps    != u.Split.cComps
     128            || s_aTests[i].fProps    != u.Split.fProps
     129            || s_aTests[i].cchPath   != u.Split.cchPath)
     130        {
     131            RTTestFailed(hTest, "i=%d rc=%Rrc %s", i, rc, s_aTests[i].pszPath);
     132            RTTestFailureDetails(hTest,
     133                                 "  cComps    %u, got %u\n"
     134                                 "  fProps    %#x, got %#x, xor=>%#x\n"
     135                                 "  cchPath   %u, got %u\n"
     136                                 ,
     137                                 s_aTests[i].cComps,    u.Split.cComps,
     138                                 s_aTests[i].fProps,    u.Split.fProps, s_aTests[i].fProps ^ u.Split.fProps,
     139                                 s_aTests[i].cchPath,   u.Split.cchPath);
     140        }
     141        else
     142        {
     143            RTTESTI_CHECK_MSG(*u.Split.pszSuffix == '\0' || *u.Split.pszSuffix == '.', ("%s", u.Split.pszSuffix));
     144            for (uint32_t idxComp = RTPATH_PROP_HAS_ROOT_SPEC(u.Split.fProps); idxComp < u.Split.cComps; idxComp++)
     145                if ( (s_aTests[i].fFlags & RTPATH_STR_F_STYLE_MASK) == RTPATH_STR_F_STYLE_DOS
     146                    ? strpbrk(u.Split.apszComps[idxComp], "/\\")
     147                    : strchr(u.Split.apszComps[idxComp], RTPATH_SLASH) )
     148                    RTTestFailed(hTest, "i=%d idxComp=%d '%s'", i, idxComp, u.Split.apszComps[idxComp]);
     149
     150            PRTPATHSPLIT pSplit = NULL;
     151            RTTESTI_CHECK_RC(rc = RTPathSplitA(s_aTests[i].pszPath, &pSplit, s_aTests[i].fFlags), VINF_SUCCESS);
     152            if (RT_SUCCESS(rc))
     153            {
     154                RTTESTI_CHECK(pSplit);
     155                RTTESTI_CHECK(pSplit->cComps   == u.Split.cComps);
     156                RTTESTI_CHECK(pSplit->fProps   == u.Split.fProps);
     157                RTTESTI_CHECK(pSplit->cchPath  == u.Split.cchPath);
     158                RTTESTI_CHECK(pSplit->cbNeeded == u.Split.cbNeeded);
     159                RTTESTI_CHECK(!strcmp(pSplit->pszSuffix, u.Split.pszSuffix));
     160                for (uint32_t idxComp = 0; idxComp < u.Split.cComps; idxComp++)
     161                    RTTESTI_CHECK(!strcmp(pSplit->apszComps[idxComp], pSplit->apszComps[idxComp]));
     162                RTPathSplitFree(pSplit);
     163            }
    116164        }
    117165    }
     
    702750    }
    703751
    704     testParser(hTest);
     752    testParserAndSplitter(hTest);
    705753
    706754    /*
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