commit
89fb801cfd
6 changed files with 68 additions and 37 deletions
|
@ -57,7 +57,8 @@ r3_tree_insert_pathl(n ,"/post/{id}", strlen("/post/{id}") , &route_data );
|
|||
r3_tree_insert_pathl(n, "/user/{id:\\d+}", strlen("/user/{id:\\d+}"), &route_data );
|
||||
|
||||
// let's compile the tree!
|
||||
r3_tree_compile(n);
|
||||
char *errstr = NULL;
|
||||
int errno = r3_tree_compile(n, &errstr);
|
||||
|
||||
|
||||
// dump the compiled tree
|
||||
|
@ -108,7 +109,9 @@ int route_data = 3;
|
|||
// insert the route path into the router tree
|
||||
r3_tree_insert_routel(n, METHOD_GET | METHOD_POST, "/blog/post", sizeof("/blog/post") - 1, &route_data );
|
||||
|
||||
r3_tree_compile(n);
|
||||
char *errstr = NULL;
|
||||
int errno;
|
||||
errno = r3_tree_compile(n, &errstr);
|
||||
|
||||
|
||||
// in your http server handler
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
45
src/node.c
45
src/node.c
|
@ -124,33 +124,41 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdio.h>
|
||||
#include <check.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "r3.h"
|
||||
#include "r3_str.h"
|
||||
#include "zmalloc.h"
|
||||
|
@ -47,7 +48,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;
|
||||
}
|
||||
|
||||
|
@ -55,20 +56,20 @@ static node * create_simple_str_tree() {
|
|||
|
||||
START_TEST (test_compile)
|
||||
{
|
||||
str_array *t;
|
||||
node * n = create_simple_str_tree();
|
||||
|
||||
node *n;
|
||||
node *m;
|
||||
edge *e;
|
||||
|
||||
n = create_simple_str_tree();
|
||||
|
||||
#ifdef DEBUG
|
||||
r3_tree_dump(n, 0);
|
||||
#endif
|
||||
|
||||
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 +105,13 @@ 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;
|
||||
int errno;
|
||||
errno = r3_tree_compile(n, &errstr);
|
||||
ck_assert(errno == 0); // no error
|
||||
|
||||
// r3_tree_dump(n, 0);
|
||||
|
||||
node *matched;
|
||||
|
@ -131,7 +138,10 @@ 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);
|
||||
|
||||
char *errstr = NULL;
|
||||
r3_tree_compile(n, &errstr);
|
||||
|
||||
r3_tree_dump(n, 0);
|
||||
node *matched;
|
||||
matched = r3_tree_match(n, "/post/11/22", NULL);
|
||||
|
@ -156,7 +166,10 @@ 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);
|
||||
|
||||
char *errstr = NULL;
|
||||
r3_tree_compile(n, &errstr);
|
||||
|
||||
r3_tree_dump(n, 0);
|
||||
node *matched;
|
||||
|
||||
|
@ -202,7 +215,9 @@ 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);
|
||||
|
||||
char * errstr = NULL;
|
||||
r3_tree_compile(n, &errstr);
|
||||
|
||||
#ifdef DEBUG
|
||||
r3_tree_dump(n, 0);
|
||||
|
@ -270,7 +285,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 +317,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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue