combine_pattern function

This commit is contained in:
c9s 2014-05-15 21:17:30 +08:00
parent 89eaad6006
commit 01a0b0da01
3 changed files with 70 additions and 3 deletions

View file

@ -43,6 +43,8 @@ rnode * rnode_insert_routel(rnode *tree, char *route, int route_len);
void rnode_dump(rnode * n, int level); void rnode_dump(rnode * n, int level);
void rnode_combine_patterns(rnode * n);
rnode * rnode_lookup(rnode * tree, char * path, int path_len); rnode * rnode_lookup(rnode * tree, char * path, int path_len);
redge * redge_create(char * pattern, int pattern_len, rnode * child); redge * redge_create(char * pattern, int pattern_len, rnode * child);

View file

@ -23,6 +23,7 @@ struct _rnode {
/* the combined regexp pattern string from pattern_tokens */ /* the combined regexp pattern string from pattern_tokens */
char * combined_pattern; char * combined_pattern;
int combined_pattern_len;
int endpoint; int endpoint;
}; };
@ -30,6 +31,7 @@ struct _rnode {
struct _redge { struct _redge {
char * pattern; char * pattern;
int pattern_len; int pattern_len;
bool is_slug;
rnode * child; rnode * child;
}; };
@ -41,12 +43,13 @@ struct _redge {
* Create a rnode object * Create a rnode object
*/ */
rnode * rnode_create(int cap) { rnode * rnode_create(int cap) {
rnode * n = (rnode*) calloc( sizeof(rnode) , 1); rnode * n = (rnode*) malloc( sizeof(rnode) );
n->children = (redge**) malloc( sizeof(redge*) * 10 ); n->children = (redge**) malloc( sizeof(redge*) * 10 );
n->children_len = 0; n->children_len = 0;
n->children_cap = 10; n->children_cap = 10;
n->endpoint = 0; n->endpoint = 0;
n->combined_pattern = NULL;
// n->edge_patterns = token_array_create(10); // n->edge_patterns = token_array_create(10);
return n; return n;
} }
@ -103,12 +106,39 @@ redge * rnode_find_edge(rnode * n, char * pat) {
return NULL; return NULL;
} }
/**
* This function combines ['/foo', '/bar', '/{slug}'] into (/foo)|(/bar)|/([^/]+)}
*
*/
void rnode_combine_patterns(rnode * n) { void rnode_combine_patterns(rnode * n) {
char * cpat;
char * p;
cpat = malloc(128);
if (cpat==NULL)
return;
p = cpat;
redge *e = NULL; redge *e = NULL;
for ( int i = 0 ; i < n->children_len ; i++ ) { for ( int i = 0 ; i < n->children_len ; i++ ) {
e = n->children[i]; e = n->children[i];
strncat(p++,"(", 1);
strncat(p, e->pattern, e->pattern_len);
p += e->pattern_len;
strncat(p++,")", 1);
if ( i + 1 < n->children_len ) {
strncat(p++,"|",1);
} }
} }
n->combined_pattern = cpat;
n->combined_pattern_len = p - cpat;
}
rnode * rnode_lookup(rnode * tree, char * path, int path_len) { rnode * rnode_lookup(rnode * tree, char * path, int path_len) {
@ -179,6 +209,7 @@ redge * redge_create(char * pattern, int pattern_len, rnode * child) {
edge->pattern = pattern; edge->pattern = pattern;
edge->pattern_len = pattern_len; edge->pattern_len = pattern_len;
edge->child = child; edge->child = child;
edge->is_slug = 0;
return edge; return edge;
} }

View file

@ -40,6 +40,28 @@ START_TEST (test_rnode_find_edge)
END_TEST END_TEST
START_TEST (test_combine_patterns)
{
token_array *t;
rnode * n;
n = rnode_create(10);
t = split_route_pattern("/foo", strlen("/foo") );
fail_if( rnode_insert_tokens(n , t) == NULL );
t = split_route_pattern("/bar", strlen("/bar") );
fail_if( rnode_insert_tokens(n , t) == NULL );
t = split_route_pattern("/zoo", strlen("/zoo") );
fail_if( rnode_insert_tokens(n , t) == NULL );
rnode_combine_patterns(n);
// printf("%s\n", n->combined_pattern);
}
END_TEST
START_TEST (test_slug_to_pcre) START_TEST (test_slug_to_pcre)
{ {
char * pattern; char * pattern;
@ -53,6 +75,17 @@ START_TEST (test_slug_to_pcre)
/*
char * p = malloc(sizeof(char) * 10);
strncat(p, "foo", 3);
free(p);
*/
} }
END_TEST END_TEST
@ -170,6 +203,7 @@ Suite* r3_suite (void) {
tcase_add_test(tcase, test_rnode_find_edge); tcase_add_test(tcase, test_rnode_find_edge);
tcase_add_test(tcase, test_rnode_insert_tokens); tcase_add_test(tcase, test_rnode_insert_tokens);
tcase_add_test(tcase, test_slug_to_pcre); tcase_add_test(tcase, test_slug_to_pcre);
tcase_add_test(tcase, test_combine_patterns);
suite_add_tcase(suite, tcase); suite_add_tcase(suite, tcase);