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:
Martin Willi
2014-06-04 15:53:09 +02:00
parent 2496eaffde
commit 67b3bcd13d
3 changed files with 88 additions and 38 deletions
+53 -38
View File
@@ -508,52 +508,54 @@ START_TEST(test_strreplace)
END_TEST END_TEST
/******************************************************************************* /*******************************************************************************
* path_dirname/basename * path_dirname/basename/absolute
*/ */
static struct { static struct {
char *path; char *path;
char *dir; char *dir;
char *base; char *base;
bool absolute;
} path_data[] = { } path_data[] = {
{NULL, ".", "."}, {NULL, ".", ".", FALSE},
{"", ".", "."}, {"", ".", ".", FALSE},
{".", ".", "."}, {".", ".", ".", FALSE},
{"..", ".", ".."}, {"..", ".", "..", FALSE},
#ifdef WIN32 #ifdef WIN32
{"C:\\", "C:\\", "C:\\"}, {"C:\\", "C:", "C:", TRUE},
{"C:\\\\", "C:\\", "C:\\"}, {"X:\\\\", "X:", "X:", TRUE},
{"foo", ".", "foo"}, {"foo", ".", "foo", FALSE},
{"f\\", ".", "f"}, {"f\\", ".", "f", FALSE},
{"foo\\", ".", "foo"}, {"foo\\", ".", "foo", FALSE},
{"foo\\\\", ".", "foo"}, {"foo\\\\", ".", "foo", FALSE},
{"C:\\f", "C:\\", "f"}, {"d:\\f", "d:", "f", TRUE},
{"C:\\f\\", "\\", "f"}, {"C:\\f\\", "C:", "f", TRUE},
{"C:\\foo", "C:\\", "foo"}, {"C:\\foo", "C:", "foo", TRUE},
{"C:\\foo\\", "C:\\", "foo"}, {"C:\\foo\\", "C:", "foo", TRUE},
{"foo\\bar", "foo", "bar"}, {"foo\\bar", "foo", "bar", FALSE},
{"foo\\\\bar", "foo", "bar"}, {"foo\\\\bar", "foo", "bar", FALSE},
{"C:\\foo\\bar", "C:\\foo", "bar"}, {"C:\\foo\\bar", "C:\\foo", "bar", TRUE},
{"C:\\foo\\bar\\", "C:\\foo", "bar"}, {"C:\\foo\\bar\\", "C:\\foo", "bar", TRUE},
{"C:\\foo\\bar\\baz", "C:\\foo\\bar", "baz"}, {"C:\\foo\\bar\\baz", "C:\\foo\\bar", "baz", TRUE},
{"\\foo\\bar", "\\foo", "bar"}, {"\\foo\\bar", "\\foo", "bar", FALSE},
{"\\\\foo\\bar", "\\\\foo", "bar", TRUE},
#else /* !WIN32 */ #else /* !WIN32 */
{"/", "/", "/"}, {"/", "/", "/", TRUE},
{"//", "/", "/"}, {"//", "/", "/", TRUE},
{"foo", ".", "foo"}, {"foo", ".", "foo", FALSE},
{"f/", ".", "f"}, {"f/", ".", "f", FALSE},
{"foo/", ".", "foo"}, {"foo/", ".", "foo", FALSE},
{"foo//", ".", "foo"}, {"foo//", ".", "foo", FALSE},
{"/f", "/", "f"}, {"/f", "/", "f", TRUE},
{"/f/", "/", "f"}, {"/f/", "/", "f", TRUE},
{"/foo", "/", "foo"}, {"/foo", "/", "foo", TRUE},
{"/foo/", "/", "foo"}, {"/foo/", "/", "foo", TRUE},
{"//foo/", "/", "foo"}, {"//foo/", "/", "foo", TRUE},
{"foo/bar", "foo", "bar"}, {"foo/bar", "foo", "bar", FALSE},
{"foo//bar", "foo", "bar"}, {"foo//bar", "foo", "bar", FALSE},
{"/foo/bar", "/foo", "bar"}, {"/foo/bar", "/foo", "bar", TRUE},
{"/foo/bar/", "/foo", "bar"}, {"/foo/bar/", "/foo", "bar", TRUE},
{"/foo/bar/baz", "/foo/bar", "baz"}, {"/foo/bar/baz", "/foo/bar", "baz", TRUE},
#endif #endif
}; };
@@ -577,6 +579,12 @@ START_TEST(test_path_basename)
} }
END_TEST END_TEST
START_TEST(test_path_absolute)
{
ck_assert(path_data[_i].absolute == path_absolute(path_data[_i].path));
}
END_TEST
/******************************************************************************* /*******************************************************************************
* time_printf_hook * time_printf_hook
*/ */
@@ -744,11 +752,18 @@ Suite *utils_suite_create()
tcase_add_loop_test(tc, test_strreplace, 0, countof(strreplace_data)); tcase_add_loop_test(tc, test_strreplace, 0, countof(strreplace_data));
suite_add_tcase(s, tc); 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)); 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)); tcase_add_loop_test(tc, test_path_basename, 0, countof(path_data));
suite_add_tcase(s, tc); 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"); 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_printf_hook, 0, countof(time_data));
tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data)); tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data));
+27
View File
@@ -288,6 +288,33 @@ char* path_basename(const char *path)
return trail ? strndup(pos, trail - pos) : strdup(pos); 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. * Described in header.
*/ */
+8
View File
@@ -568,6 +568,14 @@ char *path_dirname(const char *path);
*/ */
char *path_basename(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. * Creates a directory and all required parent directories.
* *