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
/*******************************************************************************
* 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));
+27
View File
@@ -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.
*/
+8
View File
@@ -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.
*