utils: Provide a path_absolute() function to check path for non-relativeness
The usually used trivial '/' check won't work on Windows platforms.
This commit is contained in:
@@ -508,52 +508,54 @@ START_TEST(test_strreplace)
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* path_dirname/basename
|
||||
* path_dirname/basename/absolute
|
||||
*/
|
||||
|
||||
static struct {
|
||||
char *path;
|
||||
char *dir;
|
||||
char *base;
|
||||
bool absolute;
|
||||
} path_data[] = {
|
||||
{NULL, ".", "."},
|
||||
{"", ".", "."},
|
||||
{".", ".", "."},
|
||||
{"..", ".", ".."},
|
||||
{NULL, ".", ".", FALSE},
|
||||
{"", ".", ".", FALSE},
|
||||
{".", ".", ".", FALSE},
|
||||
{"..", ".", "..", FALSE},
|
||||
#ifdef WIN32
|
||||
{"C:\\", "C:\\", "C:\\"},
|
||||
{"C:\\\\", "C:\\", "C:\\"},
|
||||
{"foo", ".", "foo"},
|
||||
{"f\\", ".", "f"},
|
||||
{"foo\\", ".", "foo"},
|
||||
{"foo\\\\", ".", "foo"},
|
||||
{"C:\\f", "C:\\", "f"},
|
||||
{"C:\\f\\", "\\", "f"},
|
||||
{"C:\\foo", "C:\\", "foo"},
|
||||
{"C:\\foo\\", "C:\\", "foo"},
|
||||
{"foo\\bar", "foo", "bar"},
|
||||
{"foo\\\\bar", "foo", "bar"},
|
||||
{"C:\\foo\\bar", "C:\\foo", "bar"},
|
||||
{"C:\\foo\\bar\\", "C:\\foo", "bar"},
|
||||
{"C:\\foo\\bar\\baz", "C:\\foo\\bar", "baz"},
|
||||
{"\\foo\\bar", "\\foo", "bar"},
|
||||
{"C:\\", "C:", "C:", TRUE},
|
||||
{"X:\\\\", "X:", "X:", TRUE},
|
||||
{"foo", ".", "foo", FALSE},
|
||||
{"f\\", ".", "f", FALSE},
|
||||
{"foo\\", ".", "foo", FALSE},
|
||||
{"foo\\\\", ".", "foo", FALSE},
|
||||
{"d:\\f", "d:", "f", TRUE},
|
||||
{"C:\\f\\", "C:", "f", TRUE},
|
||||
{"C:\\foo", "C:", "foo", TRUE},
|
||||
{"C:\\foo\\", "C:", "foo", TRUE},
|
||||
{"foo\\bar", "foo", "bar", FALSE},
|
||||
{"foo\\\\bar", "foo", "bar", FALSE},
|
||||
{"C:\\foo\\bar", "C:\\foo", "bar", TRUE},
|
||||
{"C:\\foo\\bar\\", "C:\\foo", "bar", TRUE},
|
||||
{"C:\\foo\\bar\\baz", "C:\\foo\\bar", "baz", TRUE},
|
||||
{"\\foo\\bar", "\\foo", "bar", FALSE},
|
||||
{"\\\\foo\\bar", "\\\\foo", "bar", TRUE},
|
||||
#else /* !WIN32 */
|
||||
{"/", "/", "/"},
|
||||
{"//", "/", "/"},
|
||||
{"foo", ".", "foo"},
|
||||
{"f/", ".", "f"},
|
||||
{"foo/", ".", "foo"},
|
||||
{"foo//", ".", "foo"},
|
||||
{"/f", "/", "f"},
|
||||
{"/f/", "/", "f"},
|
||||
{"/foo", "/", "foo"},
|
||||
{"/foo/", "/", "foo"},
|
||||
{"//foo/", "/", "foo"},
|
||||
{"foo/bar", "foo", "bar"},
|
||||
{"foo//bar", "foo", "bar"},
|
||||
{"/foo/bar", "/foo", "bar"},
|
||||
{"/foo/bar/", "/foo", "bar"},
|
||||
{"/foo/bar/baz", "/foo/bar", "baz"},
|
||||
{"/", "/", "/", TRUE},
|
||||
{"//", "/", "/", TRUE},
|
||||
{"foo", ".", "foo", FALSE},
|
||||
{"f/", ".", "f", FALSE},
|
||||
{"foo/", ".", "foo", FALSE},
|
||||
{"foo//", ".", "foo", FALSE},
|
||||
{"/f", "/", "f", TRUE},
|
||||
{"/f/", "/", "f", TRUE},
|
||||
{"/foo", "/", "foo", TRUE},
|
||||
{"/foo/", "/", "foo", TRUE},
|
||||
{"//foo/", "/", "foo", TRUE},
|
||||
{"foo/bar", "foo", "bar", FALSE},
|
||||
{"foo//bar", "foo", "bar", FALSE},
|
||||
{"/foo/bar", "/foo", "bar", TRUE},
|
||||
{"/foo/bar/", "/foo", "bar", TRUE},
|
||||
{"/foo/bar/baz", "/foo/bar", "baz", TRUE},
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -577,6 +579,12 @@ START_TEST(test_path_basename)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_path_absolute)
|
||||
{
|
||||
ck_assert(path_data[_i].absolute == path_absolute(path_data[_i].path));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*******************************************************************************
|
||||
* time_printf_hook
|
||||
*/
|
||||
@@ -744,11 +752,18 @@ Suite *utils_suite_create()
|
||||
tcase_add_loop_test(tc, test_strreplace, 0, countof(strreplace_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("path_dirname/basename");
|
||||
tc = tcase_create("path_dirname");
|
||||
tcase_add_loop_test(tc, test_path_dirname, 0, countof(path_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("path_basename");
|
||||
tcase_add_loop_test(tc, test_path_basename, 0, countof(path_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("path_absolute");
|
||||
tcase_add_loop_test(tc, test_path_absolute, 0, countof(path_data));
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("printf_hooks");
|
||||
tcase_add_loop_test(tc, test_time_printf_hook, 0, countof(time_data));
|
||||
tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data));
|
||||
|
||||
@@ -288,6 +288,33 @@ char* path_basename(const char *path)
|
||||
return trail ? strndup(pos, trail - pos) : strdup(pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
bool path_absolute(const char *path)
|
||||
{
|
||||
if (!path)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef WIN32
|
||||
if (strpfx(path, "\\\\"))
|
||||
{ /* UNC */
|
||||
return TRUE;
|
||||
}
|
||||
if (strlen(path) && isalpha(path[0]) && path[1] == ':')
|
||||
{ /* drive letter */
|
||||
return TRUE;
|
||||
}
|
||||
#else /* !WIN32 */
|
||||
if (path[0] == DIRECTORY_SEPARATOR[0])
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
|
||||
@@ -568,6 +568,14 @@ char *path_dirname(const char *path);
|
||||
*/
|
||||
char *path_basename(const char *path);
|
||||
|
||||
/**
|
||||
* Check if a given path is absolute.
|
||||
*
|
||||
* @param path path to check
|
||||
* @return TRUE if absolute, FALSE if relative
|
||||
*/
|
||||
bool path_absolute(const char *path);
|
||||
|
||||
/**
|
||||
* Creates a directory and all required parent directories.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user