diff --git a/include/r3.h b/include/r3.h index a8568d4..6db0143 100644 --- a/include/r3.h +++ b/include/r3.h @@ -109,7 +109,7 @@ edge * r3_node_find_edge(const node * n, const char * pat, int pat_len); void r3_node_append_edge(node *n, edge *child); -edge * r3_node_find_common_prefix(node *n, char *path, int path_len, int *prefix_len); +edge * r3_node_find_common_prefix(node *n, char *path, int path_len, int *prefix_len, char **errstr); node * r3_tree_insert_pathl(node *tree, const char *path, int path_len, void * data); diff --git a/src/node.c b/src/node.c index 3cdfb9d..b02eefb 100644 --- a/src/node.c +++ b/src/node.c @@ -492,7 +492,7 @@ node * r3_tree_insert_pathl(node *tree, const char *path, int path_len, void * d * 4. "aaa{slug:xxx}/hate" vs "aab{slug:yyy}/bar" => common prefix = "aa" * 5. "/foo/{slug}/hate" vs "/fo{slug}/bar" => common prefix = "/fo" */ -edge * r3_node_find_common_prefix(node *n, char *path, int path_len, int *prefix_len) { +edge * r3_node_find_common_prefix(node *n, char *path, int path_len, int *prefix_len, char **errstr) { int i = 0; int prefix = 0; edge *e = NULL; @@ -520,7 +520,7 @@ edge * r3_node_find_common_prefix(node *n, char *path, int path_len, int *prefix slug = r3_slug_new(path, path_len); do { - ret = r3_slug_parse(slug, path, path_len, offset, NULL); + ret = r3_slug_parse(slug, path, path_len, offset, errstr); // found slug if (ret == 1) { // inside slug, backtrace to the begin of the slug @@ -536,6 +536,8 @@ edge * r3_node_find_common_prefix(node *n, char *path, int path_len, int *prefix } else { break; } + } else if (ret == -1) { + return -1; } else { break; } @@ -563,7 +565,10 @@ node * r3_tree_insert_pathl_ex(node *tree, const char *path, int path_len, route /* length of common prefix */ int prefix_len = 0; - e = r3_node_find_common_prefix(tree, path, path_len, &prefix_len); + e = r3_node_find_common_prefix(tree, path, path_len, &prefix_len, errstr); + if (e == -1) { + return NULL; + } const char * subpath = path + prefix_len; const int subpath_len = path_len - prefix_len; diff --git a/tests/check_slug.c b/tests/check_slug.c index 9b05a2e..2e89136 100644 --- a/tests/check_slug.c +++ b/tests/check_slug.c @@ -88,7 +88,7 @@ START_TEST (test_incomplete_slug) char * errstr = NULL; char * pattern = "/user/{name:\\d{3}}/to/{id"; cnt = slug_count(pattern, strlen(pattern), &errstr); - ck_assert_int_eq(cnt, 0); + ck_assert_int_eq(cnt, -1); ck_assert(errstr); printf("%s\n",errstr); free(errstr); diff --git a/tests/check_tree.c b/tests/check_tree.c index beae505..d376d50 100644 --- a/tests/check_tree.c +++ b/tests/check_tree.c @@ -20,43 +20,43 @@ START_TEST (test_find_common_prefix) edge *ret_edge = NULL; prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/foo", sizeof("/foo")-1, &prefix_len); - ck_assert(ret_edge); + ret_edge = r3_node_find_common_prefix(n, "/foo", sizeof("/foo")-1, &prefix_len, NULL); + ck_assert(ret_edge != NULL); ck_assert_int_eq(prefix_len, 4); prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/foo/", sizeof("/foo/")-1, &prefix_len); - ck_assert(ret_edge); + ret_edge = r3_node_find_common_prefix(n, "/foo/", sizeof("/foo/")-1, &prefix_len, NULL); + ck_assert(ret_edge != NULL); ck_assert_int_eq(prefix_len, 5); prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/foo/{slog}", sizeof("/foo/{slog}")-1, &prefix_len); - ck_assert(ret_edge); + ret_edge = r3_node_find_common_prefix(n, "/foo/{slog}", sizeof("/foo/{slog}")-1, &prefix_len, NULL); + ck_assert(ret_edge != NULL); ck_assert_int_eq(prefix_len, 5); prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/foo/{bar}", sizeof("/foo/{bar}")-1, &prefix_len); - ck_assert(ret_edge); + ret_edge = r3_node_find_common_prefix(n, "/foo/{bar}", sizeof("/foo/{bar}")-1, &prefix_len, NULL); + ck_assert(ret_edge != NULL); ck_assert_int_eq(prefix_len, 5); prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/foo/bar", sizeof("/foo/bar")-1, &prefix_len); - ck_assert(ret_edge); + ret_edge = r3_node_find_common_prefix(n, "/foo/bar", sizeof("/foo/bar")-1, &prefix_len, NULL); + ck_assert(ret_edge != NULL); ck_assert_int_eq(prefix_len, 5); prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/bar/", sizeof("/bar/")-1, &prefix_len); - ck_assert(ret_edge); + ret_edge = r3_node_find_common_prefix(n, "/bar/", sizeof("/bar/")-1, &prefix_len, NULL); + ck_assert(ret_edge != NULL); ck_assert_int_eq(prefix_len, 1); prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "{bar}", sizeof("{bar}")-1, &prefix_len); - ck_assert(!ret_edge); + ret_edge = r3_node_find_common_prefix(n, "{bar}", sizeof("{bar}")-1, &prefix_len, NULL); + ck_assert(!ret_edge != NULL); ck_assert_int_eq(prefix_len, 0); @@ -79,19 +79,19 @@ START_TEST (test_find_common_prefix_after) prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/foo", sizeof("/foo")-1, &prefix_len); + ret_edge = r3_node_find_common_prefix(n, "/foo", sizeof("/foo")-1, &prefix_len, NULL); ck_assert(ret_edge == NULL); ck_assert_int_eq(prefix_len, 0); prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "{slug}/bar", sizeof("{slug}/bar")-1, &prefix_len); + ret_edge = r3_node_find_common_prefix(n, "{slug}/bar", sizeof("{slug}/bar")-1, &prefix_len, NULL); ck_assert(ret_edge); ck_assert_int_eq(prefix_len, 7); prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "{slug}/foo", sizeof("{slug}/foo")-1, &prefix_len); + ret_edge = r3_node_find_common_prefix(n, "{slug}/foo", sizeof("{slug}/foo")-1, &prefix_len, NULL); ck_assert(ret_edge); ck_assert_int_eq(prefix_len, 10); @@ -112,7 +112,7 @@ START_TEST (test_find_common_prefix_double_middle) edge *ret_edge = NULL; prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "{slug}/foo/{number}", sizeof("{slug}/foo/{number}")-1, &prefix_len); + ret_edge = r3_node_find_common_prefix(n, "{slug}/foo/{number}", sizeof("{slug}/foo/{number}")-1, &prefix_len, NULL); ck_assert(ret_edge); ck_assert_int_eq(prefix_len, 11); @@ -132,12 +132,12 @@ START_TEST (test_find_common_prefix_middle) edge *ret_edge = NULL; prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/foo/{slug}/bar", sizeof("/foo/{slug}/bar")-1, &prefix_len); + ret_edge = r3_node_find_common_prefix(n, "/foo/{slug}/bar", sizeof("/foo/{slug}/bar")-1, &prefix_len, NULL); ck_assert(ret_edge); ck_assert_int_eq(prefix_len, 12); prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/fo/{slug}/bar", sizeof("/fo/{slug}/bar")-1, &prefix_len); + ret_edge = r3_node_find_common_prefix(n, "/fo/{slug}/bar", sizeof("/fo/{slug}/bar")-1, &prefix_len, NULL); ck_assert(ret_edge); ck_assert_int_eq(prefix_len, 3); @@ -155,13 +155,13 @@ START_TEST (test_find_common_prefix_same_pattern) edge *ret_edge = NULL; prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/foo/{slug:yyy}/hate", sizeof("/foo/{slug:yyy}/hate")-1, &prefix_len); + ret_edge = r3_node_find_common_prefix(n, "/foo/{slug:yyy}/hate", sizeof("/foo/{slug:yyy}/hate")-1, &prefix_len, NULL); ck_assert(ret_edge); ck_assert_int_eq(prefix_len, 5); prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "/foo/{slug}/hate", sizeof("/foo/{slug}/hate")-1, &prefix_len); + ret_edge = r3_node_find_common_prefix(n, "/foo/{slug}/hate", sizeof("/foo/{slug}/hate")-1, &prefix_len, NULL); ck_assert(ret_edge); ck_assert_int_eq(prefix_len, 5); @@ -179,7 +179,7 @@ START_TEST (test_find_common_prefix_same_pattern2) edge *ret_edge = NULL; prefix_len = 0; - ret_edge = r3_node_find_common_prefix(n, "{slug:yyy}/hate", sizeof("{slug:yyy}/hate")-1, &prefix_len); + ret_edge = r3_node_find_common_prefix(n, "{slug:yyy}/hate", sizeof("{slug:yyy}/hate")-1, &prefix_len, NULL); ck_assert(ret_edge); ck_assert_int_eq(prefix_len, 0);