From 1a4eb14a05501eca4f5ab31528737e766fe3c49f Mon Sep 17 00:00:00 2001 From: c9s Date: Sun, 1 Jun 2014 01:51:42 +0800 Subject: [PATCH] error code support - return error code if compilation error occurs - use asprintf to sprint errstr --- include/r3.h | 4 ++-- src/node.c | 45 +++++++++++++++++++++++++++++---------------- tests/bench.c | 4 ++-- tests/check_gvc.c | 4 ++-- tests/check_tree.c | 21 ++++++++++++--------- 5 files changed, 47 insertions(+), 31 deletions(-) diff --git a/include/r3.h b/include/r3.h index 50d1f21..5d04acf 100644 --- a/include/r3.h +++ b/include/r3.h @@ -122,9 +122,9 @@ int r3_tree_render_dot(node * tree); edge * r3_node_find_edge_str(const node * n, const char * str, int str_len); -void r3_tree_compile(node *n); +int r3_tree_compile(node *n, char** errstr); -void r3_tree_compile_patterns(node * n); +int r3_tree_compile_patterns(node * n, char** errstr); node * r3_tree_matchl(const node * n, const char * path, int path_len, const match_entry * entry); diff --git a/src/node.c b/src/node.c index 0c94c86..cec0fa2 100644 --- a/src/node.c +++ b/src/node.c @@ -124,19 +124,25 @@ edge * r3_node_find_edge(const node * n, const char * pat) { return NULL; } -void r3_tree_compile(node *n) +int r3_tree_compile(node *n, char **errstr) { + int ret = 0; bool use_slug = r3_node_has_slug_edges(n); if ( use_slug ) { - r3_tree_compile_patterns(n); + if ( (ret = r3_tree_compile_patterns(n, errstr)) ) { + return ret; + } } else { // use normal text matching... n->combined_pattern = NULL; } for (int i = 0 ; i < n->edge_len ; i++ ) { - r3_tree_compile(n->edges[i]->child); + if ( (ret = r3_tree_compile(n->edges[i]->child, errstr)) ) { + return ret; // stop here if error occurs + } } + return 0; } @@ -144,13 +150,15 @@ void r3_tree_compile(node *n) * This function combines ['/foo', '/bar', '/{slug}'] into (/foo)|(/bar)|/([^/]+)} * */ -void r3_tree_compile_patterns(node * n) { +int r3_tree_compile_patterns(node * n, char **errstr) { char * cpat; char * p; - cpat = zcalloc(sizeof(char) * 128); - if (cpat==NULL) - return; + cpat = zcalloc(sizeof(char) * 220); // XXX + if (!cpat) { + asprintf(errstr, "Can not allocate memory"); + return -1; + } p = cpat; @@ -195,8 +203,8 @@ void r3_tree_compile_patterns(node * n) { n->combined_pattern = cpat; - const char *error; - int erroffset; + const char *pcre_error; + int pcre_erroffset; unsigned int option_bits = 0; n->ov_cnt = (1 + n->edge_len) * 3; @@ -207,23 +215,28 @@ void r3_tree_compile_patterns(node * n) { n->pcre_pattern = pcre_compile( n->combined_pattern, /* the pattern */ option_bits, /* default options */ - &error, /* for error message */ - &erroffset, /* for error offset */ + &pcre_error, /* for error message */ + &pcre_erroffset, /* for error offset */ NULL); /* use default character tables */ if (n->pcre_pattern == NULL) { - printf("PCRE compilation failed at offset %d: %s, pattern: %s\n", erroffset, error, n->combined_pattern); - return; + if (errstr) { + asprintf(errstr, "PCRE compilation failed at offset %d: %s, pattern: %s\n", pcre_erroffset, pcre_error, n->combined_pattern); + } + return -1; } #ifdef PCRE_STUDY_JIT_COMPILE if (n->pcre_extra) { pcre_free_study(n->pcre_extra); } - n->pcre_extra = pcre_study(n->pcre_pattern, 0, &error); + n->pcre_extra = pcre_study(n->pcre_pattern, 0, &pcre_error); if (n->pcre_extra == NULL) { - printf("PCRE study failed at offset %s\n", error); - return; + if (errstr) { + asprintf(errstr, "PCRE study failed at offset %s\n", pcre_error); + } + return -1; } #endif + return 0; } diff --git a/tests/bench.c b/tests/bench.c index d6dd23f..b682ff8 100644 --- a/tests/bench.c +++ b/tests/bench.c @@ -441,7 +441,7 @@ r3_tree_insert_path(n, "/garply/grault/quux", NULL); r3_tree_insert_path(n, "/garply/grault/corge", NULL); MEASURE(tree_compile) - r3_tree_compile(n); + r3_tree_compile(n, NULL); END_MEASURE(tree_compile) node *m; @@ -466,7 +466,7 @@ r3_tree_insert_path(n, "/garply/grault/corge", NULL); node * tree2 = r3_tree_create(1); r3_tree_insert_path(tree2, "/post/{year}/{month}", NULL); - r3_tree_compile(tree2); + r3_tree_compile(tree2, NULL); BENCHMARK(pcre_dispatch) r3_tree_matchl(tree2, "/post/2014/12", strlen("/post/2014/12"), NULL); diff --git a/tests/check_gvc.c b/tests/check_gvc.c index 796c50d..44191f9 100644 --- a/tests/check_gvc.c +++ b/tests/check_gvc.c @@ -25,7 +25,7 @@ START_TEST (test_gvc_render_dot) r3_tree_insert_path(n, "/garply/grault/foo", NULL); r3_tree_insert_path(n, "/garply/grault/bar", NULL); - r3_tree_compile(n); + r3_tree_compile(n, NULL); r3_tree_render_dot(n); @@ -48,7 +48,7 @@ START_TEST (test_gvc_render_file) r3_tree_insert_path(n, "/user/{id}", NULL); r3_tree_insert_path(n, "/post/{title:\\w+}", NULL); - r3_tree_compile(n); + r3_tree_compile(n, NULL); r3_tree_render_file(n, "png", "check_gvc.png"); r3_tree_free(n); } diff --git a/tests/check_tree.c b/tests/check_tree.c index bf07b46..49779a8 100644 --- a/tests/check_tree.c +++ b/tests/check_tree.c @@ -47,7 +47,7 @@ static node * create_simple_str_tree() { r3_tree_insert_path(n, "/zoo", NULL); r3_tree_insert_path(n, "/foo", NULL); r3_tree_insert_path(n, "/bar", NULL); - r3_tree_compile(n); + r3_tree_compile(n, NULL); return n; } @@ -67,8 +67,8 @@ START_TEST (test_compile) r3_tree_insert_path(n, "/foo/{id}", NULL); r3_tree_insert_path(n, "/{id}", NULL); - r3_tree_compile(n); - r3_tree_compile(n); // test double compile + r3_tree_compile(n, NULL); + r3_tree_compile(n, NULL); // test double compile r3_tree_dump(n, 0); match_entry * entry; @@ -104,7 +104,10 @@ START_TEST (test_pcre_patterns_insert) // r3_tree_insert_path(n, "/foo-{user}-{id}", NULL, NULL); r3_tree_insert_path(n, "/post/{handle:\\d+}-{id:\\d+}", NULL); - r3_tree_compile(n); + + + char *errstr = NULL; + r3_tree_compile(n, &errstr); // r3_tree_dump(n, 0); node *matched; @@ -131,7 +134,7 @@ START_TEST (test_pcre_patterns_insert_2) r3_tree_insert_path(n, "/zoo", NULL); r3_tree_insert_path(n, "/foo", NULL); r3_tree_insert_path(n, "/bar", NULL); - r3_tree_compile(n); + r3_tree_compile(n, NULL); r3_tree_dump(n, 0); node *matched; matched = r3_tree_match(n, "/post/11/22", NULL); @@ -156,7 +159,7 @@ START_TEST (test_pcre_patterns_insert_3) r3_tree_insert_path(n, "/foo", NULL); r3_tree_insert_path(n, "/bar", NULL); - r3_tree_compile(n); + r3_tree_compile(n, NULL); r3_tree_dump(n, 0); node *matched; @@ -202,7 +205,7 @@ START_TEST (testr3_tree_insert_pathl) r3_tree_insert_path(n, "/post/{handle}", NULL); r3_tree_insert_path(n, "/post/{handle}-{id}", NULL); - r3_tree_compile(n); + r3_tree_compile(n, NULL); #ifdef DEBUG r3_tree_dump(n, 0); @@ -270,7 +273,7 @@ START_TEST(test_pcre_pattern_simple) node * n = r3_tree_create(10); r3_tree_insert_path(n, "/user/{id:\\d+}", NULL); r3_tree_insert_path(n, "/user", NULL); - r3_tree_compile(n); + r3_tree_compile(n, NULL); // r3_tree_dump(n, 0); node *matched; matched = r3_tree_matchl(n, "/user/123", strlen("/user/123"), entry); @@ -302,7 +305,7 @@ START_TEST(test_pcre_pattern_more) r3_tree_insert_path(n, "/user2/{id:\\d+}", &var2); r3_tree_insert_path(n, "/user3/{id:\\d{3}}", &var3); r3_tree_insert_path(n, "/user", &var0); - r3_tree_compile(n); + r3_tree_compile(n, NULL); r3_tree_dump(n, 0); node *matched;