VirtualBox

Changeset 45389 in vbox


Ignore:
Timestamp:
Apr 7, 2013 4:11:30 PM (12 years ago)
Author:
vboxsync
Message:

IPRT: A Study in Paths - Chapter 1: The cross platform parser.

Location:
trunk
Files:
2 added
5 edited

Legend:

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

    r45381 r45389  
    655655/** The request function is not implemented. */
    656656#define VERR_NOT_IMPLEMENTED                (-12)
     657/** Invalid flags was given. */
     658#define VERR_INVALID_FLAGS                  (-13)
    657659
    658660/** Not equal. */
     
    979981/** A path is not relative (start with root), expected an relative path. */
    980982#define VERR_PATH_IS_NOT_RELATIVE           (-144)
     983/** Zero length path. */
     984#define VERR_PATH_ZERO_LENGTH               (-145)
    981985/** @} */
    982986
  • trunk/include/iprt/path.h

    r45375 r45389  
    388388 */
    389389RTDECL(int) RTPathCopyComponents(char *pszDst, size_t cbDst, const char *pszSrc, size_t cComponents);
     390
     391/** @name Path properties returned by RTPathParse and RTPathSplit.
     392 * @{ */
     393
     394/** Indicates that there is a filename.
     395 * If not set, either a lone root spec was given (RTPATH_PROP_UNC,
     396 * RTPATH_PROP_ROOT_SLASH, or RTPATH_PROP_VOLUME) or the final component had a
     397 * trailing slash (RTPATH_PROP_DIR_SLASH). */
     398#define RTPATH_PROP_FILENAME        UINT16_C(0x0001)
     399/** Indicates that a directory was specified using a trailing slash.
     400 * @note This is not set for lone root specifications (RTPATH_PROP_UNC,
     401 *       RTPATH_PROP_ROOT_SLASH, or RTPATH_PROP_VOLUME).
     402 * @note The slash is not counted into the last component.  */
     403#define RTPATH_PROP_DIR_SLASH       UINT16_C(0x0002)
     404
     405/** The filename has a suffix (extension). */
     406#define RTPATH_PROP_SUFFIX          UINT16_C(0x0004)
     407/** Indicates that this is an UNC path (Windows and OS/2 only).
     408 *
     409 * UNC = Universal Naming Convention.  It is on the form '//Computer/',
     410 * '//Namespace/', '//ComputerName/Resource' and '//Namespace/Resource'.
     411 * RTPathParse, RTPathSplit and friends does not consider the 'Resource'  as
     412 * part of the UNC root specifier.  Thus the root specs for the above examples
     413 * would be '//ComputerName/' or '//Namespace/'.
     414 *
     415 * Please note that  '//something' is not a UNC path, there must be a slash
     416 * following the computer or namespace.
     417 */
     418#define RTPATH_PROP_UNC             UINT16_C(0x0010)
     419/** A root slash was specified (unix style root).
     420 * (While the path must relative if not set, this being set doesn't make it
     421 * absolute.)
     422 *
     423 * This will be set in the following examples: '/', '/bin', 'C:/', 'C:/Windows',
     424 * '//./', '//./PhysicalDisk0', '//example.org/', and '//example.org/share'.
     425 *
     426 * It will not be set for the following examples: '.', 'bin/ls', 'C:', and
     427 * 'C:Windows'.
     428 */
     429#define RTPATH_PROP_ROOT_SLASH      UINT16_C(0x0020)
     430/** A volume is specified (Windows, DOS and OS/2).
     431 * For examples: 'C:', 'C:/', and 'A:/AutoExec.bat'. */
     432#define RTPATH_PROP_VOLUME          UINT16_C(0x0040)
     433/** The path is absolute, i.e. has a root specifier (root-slash,
     434 * volume or UNC) and contains no winding '..' bits, though it may contain
     435 * unnecessary slashes (RTPATH_PROP_EXTRA_SLASHES) and '.' components
     436 * (RTPATH_PROP_DOT_REFS).
     437 *
     438 * On systems without volumes and UNC (unix style) it will be set for '/',
     439 * '/bin/ls', and '/bin//./ls', but not for 'bin/ls', /bin/../usr/bin/env',
     440 * '/./bin/ls' or '/.'.
     441 *
     442 * On systems with volumes, it will be set for 'C:/', C:/Windows', and
     443 * 'C:/./Windows//', but not for 'C:', 'C:Windows', or 'C:/Windows/../boot.ini'.
     444 *
     445 * On systems with UNC paths, it will be set for '//localhost/',
     446 * '//localhost/C$', '//localhost/C$/Windows/System32', '//localhost/.', and
     447 * '//localhost/C$//./AutoExec.bat', but not for
     448 * '//localhost/C$/Windows/../AutoExec.bat'.
     449 *
     450 * @note For the RTPathAbs definition, this flag needs to be set while both
     451 *       RTPATH_PROP_EXTRA_SLASHES and RTPATH_PROP_DOT_REFS must be cleared.
     452 */
     453#define RTPATH_PROP_ABSOLUTE        UINT16_C(0x0100)
     454/** Relative path. Inverse of RTPATH_PROP_ABSOLUTE. */
     455#define RTPATH_PROP_RELATIVE        UINT16_C(0x0200)
     456/** The path contains unnecessary slashes. Meaning, that if  */
     457#define RTPATH_PROP_EXTRA_SLASHES   UINT16_C(0x0400)
     458/** The path contains references to the special '.' (dot) directory link. */
     459#define RTPATH_PROP_DOT_REFS        UINT16_C(0x0800)
     460/** The path contains references to the special '..' (dot) directory link.
     461 * RTPATH_PROP_RELATIVE will always be set together with this.  */
     462#define RTPATH_PROP_DOTDOT_REFS     UINT16_C(0x1000)
     463
     464
     465/** Macro to determin whether to insert a slash after the first component when
     466 * joining it with something else.
     467 * (All other components in a split or parsed path requies slashes added.) */
     468#define RTPATH_PROP_FIRST_NEEDS_NO_SLASH(a_fProps) \
     469    ( (a_fProps) & (RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_VOLUME | RTPATH_PROP_UNC) )
     470
     471/** Macro to determin whether there is a root specification of any kind
     472 * (unix, volumes, unc). */
     473#define RTPATH_PROP_HAS_ROOT_SPEC(a_fProps) \
     474    ( (a_fProps) & (RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_VOLUME | RTPATH_PROP_UNC) )
     475
     476/** @} */
     477
     478
     479/**
     480 * Parsed path.
     481 *
     482 * The first component is the root, volume or UNC specifier, if present.  Use
     483 * RTPATH_PROP_HAS_ROOT_SPEC() on RTPATHPARSED::fProps to determine its
     484 * precense.
     485 *
     486 * Other than the root component, no component will include directory separators
     487 * (slashes).
     488 */
     489typedef struct RTPATHPARSED
     490{
     491    /** Number of path components.
     492     * This will always be set on VERR_BUFFER_OVERFLOW returns from RTPathParsed
     493     * so the caller can calculate the required buffer size. */
     494    uint16_t    cComps;
     495    /** Path property flags, RTPATH_PROP_XXX */
     496    uint16_t    fProps;
     497    /** On success this is the length of the described path, i.e. sum of all
     498     * component lengths and necessary separators.
     499     * Do NOT use this to index in the source path in case it contains
     500     * unnecessary slashes that RTPathParsed has ignored here. */
     501    uint16_t    cchPath;
     502    /** Reserved for future use. */
     503    uint16_t    u16Reserved;
     504    /** The offset of the filename suffix, offset of the NUL char if none. */
     505    uint16_t    offSuffix;
     506    /** The lenght of the suffix. */
     507    uint16_t    cchSuffix;
     508    /** Array of component descriptors (variable size).
     509     * @note Don't try figure the end of the input path by adding up off and cch
     510     *       of the last component.  If RTPATH_PROP_DIR_SLASH is set, there may
     511     *       be one or more trailing slashes that are unaccounted for! */
     512    struct
     513    {
     514        /** The offset of the component. */
     515        uint16_t    off;
     516        /** The length of the component. */
     517        uint16_t    cch;
     518    } aComps[1];
     519} RTPATHPARSED;
     520/** Pointer to to a parsed path result. */
     521typedef RTPATHPARSED *PRTPATHPARSED;
     522/** Pointer to to a const parsed path result. */
     523typedef RTPATHPARSED *PCRTPATHPARSED;
     524
     525
     526/**
     527 * Parses the path.
     528 *
     529 * @returns IPRT status code.
     530 * @retval  VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer.
     531 * @retval  VERR_INVALID_PARAMETER if cbOutput is less than the RTPATHPARSED
     532 *          strucuture. No output. (asserted)
     533 * @retval  VERR_BUFFER_OVERFLOW there are more components in the path than
     534 *          there is space in aComps. The required amount of space can be
     535 *          determined from the pParsed->cComps:
     536 *          @code
     537 *              RT_OFFSETOF(RTPATHPARSED, aComps[pParsed->cComps])
     538 *          @endcode
     539 * @retval  VERR_PATH_ZERO_LENGTH if the path is empty.
     540 *
     541 * @param   pszPath             The path to parse.
     542 * @param   pParsed             Where to store the details of the parsed path.
     543 * @param   cbParsed            The size of the buffer. Must be at least the
     544 *                              size of RTPATHPARSED.
     545 * @param   fFlags              Combination of RTPATHPARSE_FLAGS_XXX that can be
     546 *                              used to change how the start and end of the
     547 *                              path is parsed. Most users will pass 0.
     548 * @sa      RTPathSplit, RTPathSplitA.
     549 */
     550RTDECL(int) RTPathParse(const char *pszPath,  PRTPATHPARSED pParsed, size_t cbParsed, uint32_t fFlags);
     551
     552/** @name RTPATHPARSE_FLAGS_XXX - RTPathParse flags.
     553 * @{ */
     554/** Partial path - no start.
     555 * This causes RTPathParse to skip the root specification parsing.  */
     556#define RTPATHPARSE_FLAGS_NO_START          RT_BIT_32(0)
     557/** Partial path - no end.
     558 * This causes RTPathParse to skip the filename and dir-slash parsing.  */
     559#define RTPATHPARSE_FLAGS_NO_END            RT_BIT_32(1)
     560/** Partial path - no start and no end. */
     561#define RTPATHPARSE_FLAGS_MIDDLE            (RTPATHPARSE_FLAGS_NO_START | RTPATHPARSE_FLAGS_NO_END)
     562
     563/** Host OS path style. */
     564#define RTPATHPARSE_FLAGS_STYLE_HOST        UINT32_C(0x00000000)
     565/** DOS, OS/2 and Windows path style. */
     566#define RTPATHPARSE_FLAGS_STYLE_DOS         UINT32_C(0x00000010)
     567/** Unix path style. */
     568#define RTPATHPARSE_FLAGS_STYLE_UNIX        UINT32_C(0x00000020)
     569/** Reserved path style. */
     570#define RTPATHPARSE_FLAGS_STYLE_RESERVED    UINT32_C(0x00000030)
     571/** The path style mask. */
     572#define RTPATHPARSE_FLAGS_STYLE_MASK        UINT32_C(0x00000030)
     573
     574/** Mask containing the valid flags. */
     575#define RTPATHPARSE_FLAGS_VALID_MASK        UINT32_C(0x00000033)
     576/** @}  */
     577
     578/**
     579 * Output buffer for RTPathSplit and RTPathSplitA.
     580 */
     581typedef struct RTPATHSPLIT
     582{
     583    /** Number of path components.
     584     * This will always be set on VERR_BUFFER_OVERFLOW returns from RTPathParsed
     585     * so the caller can calculate the required buffer size. */
     586    uint16_t    cComps;
     587    /** Path property flags, RTPATH_PROP_XXX */
     588    uint16_t    fProps;
     589    /** On success this is the length of the described path, i.e. sum of all
     590     * component lengths and necessary separators.
     591     * Do NOT use this to index in the source path in case it contains
     592     * unnecessary slashes that RTPathParsed has ignored here. */
     593    uint16_t    cchPath;
     594    /** Reserved (internal use).  */
     595    uint16_t    u16Reserved;
     596    /** The amount of memory used (on success) or required (on
     597     *  VERR_BUFFER_OVERFLOW) of this structure and it's strings. */
     598    uint32_t    cbNeeded;
     599    /** Pointer to the filename suffix (the dot), if any. Points to the NUL
     600     * character of the last component if none or if RTPATH_PROP_DIR_SLASH is
     601     * present. */
     602    const char *pszSuffix;
     603    /** Array of component strings (variable size). */
     604    char       *apszComps[1];
     605} RTPATHSPLIT;
     606/** Pointer to a split path buffer. */
     607typedef RTPATHSPLIT *PRTPATHSPLIT;
     608/** Pointer to a const split path buffer. */
     609typedef RTPATHSPLIT const *PCRTPATHSPLIT;
     610
     611/**
     612 * Splits the path into individual component strings, carved from user supplied
     613 * the given buffer block.
     614 *
     615 * @returns IPRT status code.
     616 * @retval  VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer.
     617 * @retval  VERR_INVALID_PARAMETER if cbOutput is less than the RTPATHSPLIT
     618 *          strucuture. No output. (asserted)
     619 * @retval  VERR_BUFFER_OVERFLOW there are more components in the path than
     620 *          there is space in aComps. The required amount of space can be
     621 *          determined from the pParsed->cComps:
     622 *          @code
     623 *              RT_OFFSETOF(RTPATHPARSED, aComps[pParsed->cComps])
     624 *          @endcode
     625 * @retval  VERR_PATH_ZERO_LENGTH if the path is empty.
     626 * @retval  VERR_FILENAME_TOO_LONG if the filename is too long (close to 64 KB).
     627 *
     628 * @param   pszPath             The path to parse.
     629 * @param   pSplit              Where to store the details of the parsed path.
     630 * @param   cbSplit             The size of the buffer pointed to by @a pSplit
     631 *                              (variable sized array at the end).  Must be at
     632 *                              least the size of RTPATHSPLIT.
     633 *
     634 * @sa      RTPathSplitA, RTPathParse.
     635 */
     636RTDECL(int) RTPathSplit(const char *pszPath, PRTPATHSPLIT pSplit, size_t cbSplit);
     637
     638/**
     639 * Splits the path into individual component strings, allocating the buffer on
     640 * the default thread heap.
     641 *
     642 * @returns IPRT status code.
     643 * @retval  VERR_INVALID_POINTER if pParsed or pszPath is an invalid pointer.
     644 * @retval  VERR_PATH_ZERO_LENGTH if the path is empty.
     645 *
     646 * @param   pszPath             The path to parse.
     647 * @param   ppSplit             Where to return the pointer to the output on
     648 *                              success.  This must be freed by calling
     649 *                              RTPathSplitFree().
     650 * @sa      RTPathSplitFree, RTPathSplit, RTPathParse.
     651 */
     652RTDECL(int) RTPathSplitA(const char *pszPath, PRTPATHSPLIT *ppSplit);
     653
     654/**
     655 * Frees buffer returned by RTPathSplitA.
     656 *
     657 * @param   pSplit              What RTPathSplitA returned.
     658 * @sa      RTPathSplitA
     659 */
     660RTDECL(void) RTPathSplitFree(PRTPATHSPLIT pSplit);
     661
    390662
    391663/**
  • trunk/src/VBox/Runtime/Makefile.kmk

    r45375 r45389  
    362362        common/path/RTPathJoinA.cpp \
    363363        common/path/RTPathJoinEx.cpp \
     364        common/path/RTPathParse.cpp \
    364365        common/path/RTPathParseSimple.cpp \
    365366        common/path/RTPathRealDup.cpp \
     
    17091710        common/path/RTPathHasExt.cpp \
    17101711        common/path/RTPathHasPath.cpp \
     1712        common/path/RTPathParse.cpp \
    17111713        common/path/RTPathParseSimple.cpp \
    17121714        common/path/RTPathRealDup.cpp \
  • trunk/src/VBox/Runtime/common/path/rtPathRootSpecLen.cpp

    r28800 r45389  
    5555    if (RTPATH_IS_SLASH(pszPath[0]))
    5656    {
    57 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
     57#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
    5858        if (   RTPATH_IS_SLASH(pszPath[1])
    5959            && !RTPATH_IS_SLASH(pszPath[2])
     
    7979            off++;
    8080    }
    81 #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
     81#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
    8282    else if (RT_C_IS_ALPHA(pszPath[0]) && pszPath[1] == ':')
    8383    {
  • trunk/src/VBox/Runtime/testcase/tstRTPath.cpp

    r44623 r45389  
    3737#include <iprt/string.h>
    3838#include <iprt/test.h>
     39
     40
     41static void testParser(RTTEST hTest)
     42{
     43    RTTestSub(hTest, "RTPathParse");
     44
     45    static struct
     46    {
     47        uint16_t    cComps;
     48        uint16_t    cchPath;
     49        uint16_t    offSuffix;
     50        const char *pszPath;
     51        uint16_t    fProps;
     52        uint32_t    fFlags;
     53    } const s_aTests[] =
     54    {
     55        { 2, 13,  9,  "C:/Config.sys",    RTPATH_PROP_VOLUME | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,       RTPATHPARSE_FLAGS_STYLE_DOS },
     56        { 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, RTPATHPARSE_FLAGS_STYLE_DOS },
     57        { 2, 12,  8,  "C:Config.sys",     RTPATH_PROP_VOLUME | RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,                                RTPATHPARSE_FLAGS_STYLE_DOS },
     58        { 1, 10,  6,  "Config.sys",       RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,                                                     RTPATHPARSE_FLAGS_STYLE_DOS },
     59        { 1,  4,  4,  "//./",             RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE,                                                      RTPATHPARSE_FLAGS_STYLE_DOS },
     60        { 2,  5,  5,  "//./f",            RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                               RTPATHPARSE_FLAGS_STYLE_DOS },
     61        { 2,  5,  6,  "//.//f",           RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_EXTRA_SLASHES,   RTPATHPARSE_FLAGS_STYLE_DOS },
     62        { 3,  7,  7,  "//././f",          RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS,        RTPATHPARSE_FLAGS_STYLE_DOS },
     63        { 3,  8,  8,  "//.././f",         RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS,        RTPATHPARSE_FLAGS_STYLE_DOS },
     64        { 3,  9,  9,  "//../../f",        RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOTDOT_REFS,     RTPATHPARSE_FLAGS_STYLE_DOS },
     65        { 1,  1,  1,  "/",                RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE,                                                                        RTPATHPARSE_FLAGS_STYLE_UNIX },
     66        { 2,  4,  4,  "/bin",             RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATHPARSE_FLAGS_STYLE_UNIX },
     67        { 2,  4,  5,  "/bin/",            RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_DIR_SLASH,                                                RTPATHPARSE_FLAGS_STYLE_UNIX },
     68        { 3,  7,  7,  "/bin/ls",          RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATHPARSE_FLAGS_STYLE_UNIX },
     69        { 3,  12, 7,  "/etc/rc.conf",     RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX,                            RTPATHPARSE_FLAGS_STYLE_UNIX },
     70        { 1,  1,  2,  "//",               RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES,                                            RTPATHPARSE_FLAGS_STYLE_UNIX },
     71        { 1,  1,  3,  "///",              RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES,                                            RTPATHPARSE_FLAGS_STYLE_UNIX },
     72        { 3,  6,  7,  "/.//bin",          RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_DOT_REFS | RTPATH_PROP_FILENAME, RTPATHPARSE_FLAGS_STYLE_UNIX },
     73        { 1,  3,  3,  "bin",              RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME,                                                                          RTPATHPARSE_FLAGS_STYLE_UNIX },
     74        { 1,  3,  4,  "bin/",             RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH,                                                                         RTPATHPARSE_FLAGS_STYLE_UNIX },
     75        { 1,  3,  7,  "bin////",          RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH | RTPATH_PROP_EXTRA_SLASHES,                                             RTPATHPARSE_FLAGS_STYLE_UNIX },
     76        { 3, 10, 10,  "bin/../usr",       RTPATH_PROP_RELATIVE | RTPATH_PROP_DOTDOT_REFS | RTPATH_PROP_FILENAME,                                                RTPATHPARSE_FLAGS_STYLE_UNIX },
     77        { 4, 11, 11,  "/bin/../usr",      RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE | RTPATH_PROP_DOTDOT_REFS | RTPATH_PROP_FILENAME,                       RTPATHPARSE_FLAGS_STYLE_UNIX },
     78        { 4,  8,  8,  "/a/.../u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATHPARSE_FLAGS_STYLE_UNIX },
     79        { 4,  8,  8,  "/a/.b./u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATHPARSE_FLAGS_STYLE_UNIX },
     80        { 4,  8,  8,  "/a/..c/u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATHPARSE_FLAGS_STYLE_UNIX },
     81        { 4,  8,  8,  "/a/d../u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATHPARSE_FLAGS_STYLE_UNIX },
     82        { 4,  8,  8,  "/a/.e/.u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATHPARSE_FLAGS_STYLE_UNIX },
     83        { 4,  8,  8,  "/a/.f/.u",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATHPARSE_FLAGS_STYLE_UNIX },
     84        { 4,  8,  8,  "/a/.g/u.",         RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME,                                                 RTPATHPARSE_FLAGS_STYLE_UNIX },
     85        { 3,  9, 10,  "/a/h/u.ext",       RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_RELATIVE,                                                                     RTPATHPARSE_FLAGS_STYLE_UNIX | RTPATHPARSE_FLAGS_MIDDLE },
     86        { 3,  9,  9,  "a/h/u.ext",        RTPATH_PROP_RELATIVE,                                                                                                 RTPATHPARSE_FLAGS_STYLE_UNIX | RTPATHPARSE_FLAGS_MIDDLE },
     87        { 3,  9, 10,  "a/h/u.ext/",       RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_RELATIVE,                                                                     RTPATHPARSE_FLAGS_STYLE_UNIX | RTPATHPARSE_FLAGS_MIDDLE },
     88    };
     89
     90    union
     91    {
     92        RTPATHPARSED    Parsed;
     93        uint8_t         ab[4096];
     94    } u;
     95
     96    for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++)
     97    {
     98        int rc = RTPathParse(s_aTests[i].pszPath, &u.Parsed, sizeof(u), s_aTests[i].fFlags);
     99        if (   rc != VINF_SUCCESS
     100            || s_aTests[i].cComps    != u.Parsed.cComps
     101            || s_aTests[i].fProps    != u.Parsed.fProps
     102            || s_aTests[i].offSuffix != u.Parsed.offSuffix
     103            || s_aTests[i].cchPath   != u.Parsed.cchPath)
     104        {
     105            RTTestFailed(hTest, "i=%d rc=%Rrc %s", i, rc, s_aTests[i].pszPath);
     106            RTTestFailureDetails(hTest,
     107                                 "  cComps    %u, got %u\n"
     108                                 "  fProps    %#x, got %#x, xor=>%#x\n"
     109                                 "  offSuffix %u, got %u\n"
     110                                 "  cchPath   %u, got %u\n"
     111                                 ,
     112                                 s_aTests[i].cComps,    u.Parsed.cComps,
     113                                 s_aTests[i].fProps,    u.Parsed.fProps, s_aTests[i].fProps ^ u.Parsed.fProps,
     114                                 s_aTests[i].offSuffix, u.Parsed.offSuffix,
     115                                 s_aTests[i].cchPath,   u.Parsed.cchPath);
     116        }
     117    }
     118}
    39119
    40120
     
    596676    }
    597677
     678    testParser(hTest);
     679
    598680    /*
    599681     * Summary.
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