tstRTPath.cpp revision 4fca597ed56c7834134c9090c32f6cf71946944c
/* $Id$ */
/** @file
* IPRT Testcase - Test various path functions.
*/
/*
* Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <iprt/initterm.h>
{
static struct
{
const char *pszPath;
} const s_aTests[] =
{
{ 2, 5, 5, "/bin/", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_DIR_SLASH, RTPATH_STR_F_STYLE_UNIX },
{ 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 },
{ 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 },
{ 2, 12, 8, "C:Config.sys", RTPATH_PROP_VOLUME | RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX, RTPATH_STR_F_STYLE_DOS },
{ 1, 10, 6, "Config.sys", RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX, RTPATH_STR_F_STYLE_DOS },
{ 1, 4, 4, "//./", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE, RTPATH_STR_F_STYLE_DOS },
{ 2, 5, 5, "//./f", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_DOS },
{ 2, 5, 6, "//.//f", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_DOS },
{ 3, 7, 7, "//././f", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS, RTPATH_STR_F_STYLE_DOS },
{ 3, 8, 8, "//.././f", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOT_REFS, RTPATH_STR_F_STYLE_DOS },
{ 3, 9, 9, "//../../f", RTPATH_PROP_UNC | RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE | RTPATH_PROP_FILENAME | RTPATH_PROP_DOTDOT_REFS, RTPATH_STR_F_STYLE_DOS },
{ 2, 4, 4, "/bin", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 2, 5, 5, "/bin/", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_DIR_SLASH, RTPATH_STR_F_STYLE_UNIX },
{ 3, 7, 7, "/bin/ls", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 3, 12, 7, "/etc/rc.conf", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME | RTPATH_PROP_SUFFIX, RTPATH_STR_F_STYLE_UNIX },
{ 1, 1, 2, "//", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_UNIX },
{ 1, 1, 3, "///", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_UNIX },
{ 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 },
{ 1, 4, 7, "bin////", RTPATH_PROP_RELATIVE | RTPATH_PROP_DIR_SLASH | RTPATH_PROP_EXTRA_SLASHES, RTPATH_STR_F_STYLE_UNIX },
{ 3, 10, 10, "bin/../usr", RTPATH_PROP_RELATIVE | RTPATH_PROP_DOTDOT_REFS | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 4, 11, 11, "/bin/../usr", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_RELATIVE | RTPATH_PROP_DOTDOT_REFS | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 4, 8, 8, "/a/.../u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 4, 8, 8, "/a/.b./u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 4, 8, 8, "/a/..c/u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 4, 8, 8, "/a/d../u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 4, 8, 8, "/a/.e/.u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 4, 8, 8, "/a/.f/.u", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 4, 8, 8, "/a/.g/u.", RTPATH_PROP_ROOT_SLASH | RTPATH_PROP_ABSOLUTE | RTPATH_PROP_FILENAME, RTPATH_STR_F_STYLE_UNIX },
{ 3, 9, 10, "/a/h/u.ext", RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_RELATIVE, RTPATH_STR_F_STYLE_UNIX | RTPATH_STR_F_MIDDLE },
{ 3, 9, 10, "a/h/u.ext/", RTPATH_PROP_EXTRA_SLASHES | RTPATH_PROP_RELATIVE, RTPATH_STR_F_STYLE_UNIX | RTPATH_STR_F_MIDDLE },
};
char szPath1[RTPATH_MAX];
union
{
} u;
{
if ( rc != VINF_SUCCESS
{
" cComps %u, got %u\n"
" fProps %#x, got %#x, xor=>%#x\n"
" offSuffix %u, got %u\n"
" cchPath %u, got %u\n"
,
}
else
{
rc = RTPathParsedReassemble(s_aTests[i].pszPath, &u.Parsed, s_aTests[i].fFlags & ~RTPATH_STR_F_MIDDLE,
if (rc == VINF_SUCCESS)
{
}
else
}
}
{
if ( rc != VINF_SUCCESS
{
" cComps %u, got %u\n"
" fProps %#x, got %#x, xor=>%#x\n"
" cchPath %u, got %u\n"
,
}
else
{
RTTESTI_CHECK_MSG(*u.Split.pszSuffix == '\0' || *u.Split.pszSuffix == '.', ("%s", u.Split.pszSuffix));
for (uint32_t idxComp = RTPATH_PROP_HAS_ROOT_SPEC(u.Split.fProps); idxComp < u.Split.cComps; idxComp++)
RTTESTI_CHECK_RC(rc = RTPathSplitA(s_aTests[i].pszPath, &pSplit, s_aTests[i].fFlags), VINF_SUCCESS);
if (RT_SUCCESS(rc))
{
}
rc = RTPathSplitReassemble(&u.Split, s_aTests[i].fFlags & ~RTPATH_STR_F_MIDDLE, szPath1, sizeof(szPath1));
if (rc == VINF_SUCCESS)
{
}
else
}
}
}
int main()
{
char szPath[RTPATH_MAX];
/*
* Init RT+Test.
*/
if (rc)
return rc;
#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
# if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS
# else
RTTestIFailed("#if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS");
# endif
#else
# if RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX
# else
RTTestIFailed("#if RTPATH_STYLE == RTPATH_STR_F_STYLE_UNIX");
# endif
#endif
/*
* RTPathExecDir, RTPathUserHome and RTProcGetExecutablePath.
*/
if (RT_SUCCESS(rc))
else
RTTestIFailed("RTProcGetExecutablePath -> NULL");
if (RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
/*
* RTPathAbsEx
*/
static const struct
{
const char *pcszInputBase;
const char *pcszInputPath;
int rc;
const char *pcszOutput;
}
{
#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
#else
{ NULL, "relative/../dir\\.\\.\\.\\file.txt", VINF_SUCCESS, "%p/dir\\.\\.\\.\\file.txt" }, /* linux-specific */
#endif
#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
{ "C:\\VirtualBox/Machines", "..\\VirtualBox.xml", VINF_SUCCESS, "C:\\VirtualBox\\VirtualBox.xml" },
{ "\\\\server\\share_as_base", "relative\\data", VINF_SUCCESS, "\\\\server\\share_as_base\\relative\\data" },
#else
#endif
};
for (unsigned i = 0; i < RT_ELEMENTS(s_aRTPathAbsExTests); ++ i)
{
{
RTTestIFailed("unexpected result code!\n"
" input base: '%s'\n"
" input path: '%s'\n"
" output: '%s'\n"
" rc: %Rrc\n"
" expected rc: %Rrc",
s_aRTPathAbsExTests[i].rc);
continue;
}
char szTmp[RTPATH_MAX];
char *pszExpected = NULL;
{
{
if (RT_FAILURE(rc))
break;
pszExpected = szTmp;
{
}
#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
{
}
#endif
}
else
{
pszExpected = szTmp;
}
{
RTTestIFailed("Unexpected result\n"
" input base: '%s'\n"
" input path: '%s'\n"
" output: '%s'\n"
" expected: '%s'",
}
}
}
/*
* RTPathStripFilename
*/
static const char *s_apszStripFilenameTests[] =
{
"/usr", "/",
"usr", ".",
#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
"c:/windows", "c:/",
"c:/", "c:/",
"D:", "D:",
"C:\\OS2\\DLLS", "C:\\OS2",
#endif
};
{
const char *pszInput = s_apszStripFilenameTests[i];
{
RTTestIFailed("Unexpected result\n"
" input: '%s'\n"
" output: '%s'\n"
"expected: '%s'",
}
}
/*
* RTPathAppend.
*/
static const char *s_apszAppendTests[] =
{
/* base append result */
"/", "", "/",
"", "/", "/",
"/", "/", "/",
"/x", "", "/x",
"/x", "/", "/x/",
"/", "x", "/x",
#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
"/", "\\", "/",
"\\", "/", "\\",
"\\\\srv\\shr", "/\\dir//", "\\\\srv\\shr\\dir//",
"C:", "autoexec.bat", "C:autoexec.bat",
"C:", "/autoexec.bat", "C:/autoexec.bat",
"C:", "\\autoexec.bat", "C:\\autoexec.bat",
"C:\\", "/autoexec.bat", "C:\\autoexec.bat",
"C:\\\\", "autoexec.bat", "C:\\autoexec.bat",
#endif
};
{
const char *pszInput = s_apszAppendTests[i];
if (RT_FAILURE(rc))
continue;
{
RTTestIFailed("Unexpected result\n"
" input: '%s'\n"
" append: '%s'\n"
" output: '%s'\n"
"expected: '%s'",
}
else
{
{
}
}
}
/*
* RTPathJoin - reuse the append tests.
*/
{
const char *pszInput = s_apszAppendTests[i];
if (RT_FAILURE(rc))
continue;
{
RTTestIFailed("Unexpected result\n"
" input: '%s'\n"
" append: '%s'\n"
" output: '%s'\n"
"expected: '%s'",
}
else
{
}
}
/*
* RTPathJoinA - reuse the append tests.
*/
{
const char *pszInput = s_apszAppendTests[i];
char *pszPathDst;
if (!pszPathDst)
continue;
{
RTTestIFailed("Unexpected result\n"
" input: '%s'\n"
" append: '%s'\n"
" output: '%s'\n"
"expected: '%s'",
}
}
/*
* RTPathStripTrailingSlash
*/
static const char *s_apszStripTrailingSlash[] =
{
/* input result */
"/", "/",
"//", "/",
"////////////////////", "/",
"/tmp", "/tmp",
"/tmp////////////////", "/tmp",
"tmp", "tmp",
"tmp////////////////", "tmp",
"./", ".",
#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
"////////////////////", "/",
"D:", "D:",
"D:/", "D:/",
"D:\\", "D:\\",
"D:\\/\\", "D:\\",
"D:/\\/\\", "D:/",
"C:/Temp", "C:/Temp",
"C:/Temp/", "C:/Temp",
"C:/Temp\\/", "C:/Temp",
#endif
};
{
const char *pszInput = s_apszStripTrailingSlash[i];
RTTestIFailed("Unexpected result\n"
" input: '%s'\n"
" output: '%s'\n"
"expected: '%s'",
else
}
/*
* RTPathCountComponents
*/
#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
#endif
/*
* RTPathCopyComponents
*/
struct
{
const char *pszSrc;
const char *pszResult;
} s_aCopyComponents[] =
{
{ "", 0, "" },
{ "", 5, "" },
{ "/", 0, "" },
{ "/", 1, "/" },
{ "/", 2, "/" },
};
for (unsigned i = 0; i < RT_ELEMENTS(s_aCopyComponents); i++)
{
RTTestIFailed("Unexpected result\n"
" input: '%s' cComponents=%u\n"
" output: '%s'\n"
"expected: '%s'",
else if (RT_SUCCESS(rc))
{
RTTESTI_CHECK_RC(RTPathCopyComponents(szPath, strlen(pszResult) + 1, pszInput, cComponents), VINF_SUCCESS);
RTTESTI_CHECK_RC(RTPathCopyComponents(szPath, strlen(pszResult), pszInput, cComponents), VERR_BUFFER_OVERFLOW);
}
}
/*
* RTPathStripSuffix
*/
struct
{
const char *pszSrc;
const char *pszResult;
} s_aStripExt[] =
{
{ "filename.ext", "filename" },
{ "filename.ext1.ext2.ext3", "filename.ext1.ext2" },
{ "filename..ext", "filename." },
{ "filename.ext.", "filename.ext." },
};
for (unsigned i = 0; i < RT_ELEMENTS(s_aStripExt); i++)
{
RTTestIFailed("Unexpected result\n"
" input: '%s'\n"
" output: '%s'\n"
"expected: '%s'",
}
/*
* RTPathCalcRelative
*/
struct
{
const char *pszFrom;
const char *pszTo;
int rc;
const char *pszExpected;
} s_aRelPath[] =
{
{ "/dir/dir2/test.ext", "/dir/dir3/test2.ext", VINF_SUCCESS, ".." RTPATH_SLASH_STR "dir3/test2.ext"},
#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
#endif
};
for (unsigned i = 0; i < RT_ELEMENTS(s_aRelPath); i++)
{
RTTestIFailed("Unexpected return code\n"
" got: %Rrc\n"
"expected: %Rrc",
else if ( RT_SUCCESS(rc)
RTTestIFailed("Unexpected result\n"
" from: '%s'\n"
" to: '%s'\n"
" output: '%s'\n"
"expected: '%s'",
}
/*
* Summary.
*/
return RTTestSummaryAndDestroy(hTest);
}