commit e01590338c3e32a0e096d3409844b7e587ab894b from: Stefan Sperling date: Tue Jan 08 21:32:42 2019 UTC generalize the pathset's path comparison function commit - 025eb8a5503ebea0b3dffaf887ef0fd8aa5e1d23 commit + e01590338c3e32a0e096d3409844b7e587ab894b blob - 46595f8d660ac6b02340670eaa92dd3be2aa93c0 blob + 6f0f5dc9245062ceb219c057933f229d2e7c6c0b --- lib/got_lib_path.h +++ lib/got_lib_path.h @@ -51,3 +51,9 @@ const struct got_error *got_path_skip_common_ancestor( /* Determine whether a path points to the root directory "/" . */ int got_path_is_root_dir(const char *); + +/* + * Like strcmp() but orders children in subdirectories directly after + * their parents. + */ +int got_compare_paths(const char *, const char *); blob - c78fdb20bdb77cb22d2610b7d886f4effaee2e01 blob + a57cfdeeba9be0ab1803758a4fadd15c64108606 --- lib/path.c +++ lib/path.c @@ -25,6 +25,10 @@ #include "got_lib_path.h" +#ifndef MIN +#define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b)) +#endif + int got_path_is_absolute(const char *path) { @@ -139,3 +143,33 @@ got_path_is_root_dir(const char *path) { return (path[0] == '/' && path[1] == '\0'); } + +int +got_compare_paths(const char *path1, const char *path2) +{ + size_t len1 = strlen(path1); + size_t len2 = strlen(path2); + size_t min_len = MIN(len1, len2); + size_t i = 0; + + /* Skip over common prefix. */ + while (i < min_len && path1[i] == path2[i]) + i++; + + /* Are the paths exactly equal? */ + if (len1 == len2 && i >= min_len) + return 0; + + /* Order children in subdirectories directly after their parents. */ + if (path1[i] == '/' && path2[i] == '\0') + return 1; + if (path2[i] == '/' && path1[i] == '\0') + return -1; + if (path1[i] == '/') + return -1; + if (path2[i] == '/') + return 1; + + /* Next character following the common prefix determines order. */ + return (unsigned char)path1[i] < (unsigned char)path2[i] ? -1 : 1; +} blob - 9b124332dccbad46104feed8d49eca8c3bcd383e blob + 0332c19e110a0a01f815e84f6523dff8331994da --- lib/pathset.c +++ lib/pathset.c @@ -22,12 +22,9 @@ #include #include "got_error.h" +#include "got_lib_path.h" #include "got_lib_pathset.h" -#ifndef MIN -#define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b)) -#endif - struct got_pathset_element { RB_ENTRY(got_pathset_element) entry; char *path; @@ -40,31 +37,7 @@ static int cmp_elements(const struct got_pathset_element *e1, const struct got_pathset_element *e2) { - size_t len1 = strlen(e1->path); - size_t len2 = strlen(e2->path); - size_t min_len = MIN(len1, len2); - size_t i = 0; - - /* Skip over common prefix. */ - while (i < min_len && e1->path[i] == e2->path[i]) - i++; - - /* Are the paths exactly equal? */ - if (len1 == len2 && i >= min_len) - return 0; - - /* Order children in subdirectories directly after their parents. */ - if (e1->path[i] == '/' && e2->path[i] == '\0') - return 1; - if (e2->path[i] == '/' && e1->path[i] == '\0') - return -1; - if (e1->path[i] == '/') - return -1; - if (e2->path[i] == '/') - return 1; - - /* Next character following the common prefix determines order. */ - return (unsigned char)e1->path[i] < (unsigned char)e2->path[i] ? -1 : 1; + return got_compare_paths(e1->path, e2->path); } RB_PROTOTYPE(got_pathset_tree, got_pathset_element, entry, cmp_elements); blob - 9727586cdfb5e786c91383b214228ee484459083 blob + 35b7f216dd013066af642519d26ad4ddcb5a6b31 --- regress/pathset/Makefile +++ regress/pathset/Makefile @@ -1,7 +1,7 @@ .PATH:${.CURDIR}/../../lib PROG = pathset_test -SRCS = error.c sha1.c pathset.c pathset_test.c +SRCS = error.c sha1.c pathset.c path.c pathset_test.c CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib LDADD =