redge_branch function to branch the edge
This commit is contained in:
parent
9381ab943c
commit
824ae8784e
5 changed files with 118 additions and 56 deletions
|
@ -49,6 +49,8 @@ rnode * rnode_lookup(rnode * tree, char * path, int path_len);
|
|||
|
||||
redge * redge_create(char * pattern, int pattern_len, rnode * child);
|
||||
|
||||
void redge_branch(redge *e, int dl);
|
||||
|
||||
void redge_free(redge * edge);
|
||||
|
||||
#endif /* !NODE_H */
|
||||
|
|
|
@ -12,7 +12,9 @@ int strndiff(char * d1, char * d2, unsigned int n);
|
|||
|
||||
int strdiff(char * d1, char * d2);
|
||||
|
||||
char * slug_to_pcre(char * slug, char sep);
|
||||
char * compile_slug(char * str, int len);
|
||||
|
||||
char * contains_slug(char * str);
|
||||
|
||||
char * ltrim_slash(char* str);
|
||||
|
||||
|
|
79
src/node.c
79
src/node.c
|
@ -236,12 +236,12 @@ rnode * rnode_insert_routel(rnode *tree, char *route, int route_len)
|
|||
// branch the edge at correct position (avoid broken slugs)
|
||||
char *slug_s = strchr(route, '{');
|
||||
char *slug_e = strchr(route, '}');
|
||||
if ( slug_s && slug_e ) {
|
||||
if ( dl > (slug_s - route) && dl < (slug_e - route) ) {
|
||||
// break before '{'
|
||||
dl = slug_s - route;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* it's partically matched with the pattern,
|
||||
* we should split the end point and make a branch here...
|
||||
|
@ -252,8 +252,44 @@ rnode * rnode_insert_routel(rnode *tree, char *route, int route_len)
|
|||
char * s2 = route + dl;
|
||||
int s1_len = 0, s2_len = 0;
|
||||
|
||||
redge_branch(e, dl);
|
||||
|
||||
// here is the new edge from.
|
||||
c2 = rnode_create(3);
|
||||
s2_len = route_len - dl;
|
||||
e2 = redge_create(strndup(s2, s2_len), s2_len, c2);
|
||||
// printf("edge right: %s\n", e2->pattern);
|
||||
rnode_append_edge(e->child, e2);
|
||||
|
||||
// truncate the original edge pattern
|
||||
free(e->pattern);
|
||||
e->pattern = strndup(e->pattern, dl);
|
||||
e->pattern_len = dl;
|
||||
|
||||
|
||||
// move n->edges to c1
|
||||
c2->endpoint++;
|
||||
return c2;
|
||||
} else if ( dl > 0 ) {
|
||||
|
||||
} else {
|
||||
printf("unexpected condition.");
|
||||
return NULL;
|
||||
}
|
||||
// token_array * t = split_route_pattern(route, strlen(route));
|
||||
// return rnode_insert_tokens(tree, t);
|
||||
// n->endpoint++;
|
||||
return n;
|
||||
}
|
||||
|
||||
void redge_branch(redge *e, int dl) {
|
||||
rnode *c1; // child 1, child 2
|
||||
redge *e1; // edge 1, edge 2
|
||||
char * s1 = e->pattern + dl;
|
||||
int s1_len = 0;
|
||||
|
||||
redge **tmp_edges = e->child->edges;
|
||||
int **tmp_edge_len = e->child->edge_len;
|
||||
int tmp_edge_len = e->child->edge_len;
|
||||
|
||||
// the suffix edge of the leaf
|
||||
c1 = rnode_create(3);
|
||||
|
@ -269,44 +305,7 @@ rnode * rnode_insert_routel(rnode *tree, char *route, int route_len)
|
|||
e->child->edge_len = 0;
|
||||
|
||||
rnode_append_edge(e->child, e1);
|
||||
|
||||
|
||||
|
||||
|
||||
// here is the new edge from.
|
||||
c2 = rnode_create(3);
|
||||
s2_len = route_len - dl;
|
||||
e2 = redge_create(strndup(s2, s2_len), s2_len, c2);
|
||||
// printf("edge right: %s\n", e2->pattern);
|
||||
rnode_append_edge(e->child, e2);
|
||||
|
||||
// truncate the original edge pattern
|
||||
free(e->pattern);
|
||||
e->pattern = strndup(e->pattern, dl);
|
||||
e->pattern_len = dl;
|
||||
|
||||
|
||||
|
||||
// Move the child edges to the new suffix edge child
|
||||
/*
|
||||
e->child->edge_len = 0;
|
||||
*/
|
||||
|
||||
|
||||
// move n->edges to c1
|
||||
c1->endpoint++;
|
||||
c2->endpoint++;
|
||||
return c2;
|
||||
} else if ( dl > 0 ) {
|
||||
|
||||
} else {
|
||||
printf("unexpected condition.");
|
||||
return NULL;
|
||||
}
|
||||
// token_array * t = split_route_pattern(route, strlen(route));
|
||||
// return rnode_insert_tokens(tree, t);
|
||||
// n->endpoint++;
|
||||
return n;
|
||||
}
|
||||
|
||||
void rnode_dump(rnode * n, int level) {
|
||||
|
|
68
src/str.c
68
src/str.c
|
@ -32,29 +32,71 @@ int strdiff(char * d1, char * d2) {
|
|||
|
||||
|
||||
|
||||
char * contains_slug(char * str) {
|
||||
return strchr(str, '}');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param char * sep separator
|
||||
*/
|
||||
char * slug_to_pcre(char * slug, char sep)
|
||||
char * compile_slug(char * str, int len)
|
||||
{
|
||||
char * p = NULL;
|
||||
char * pat = NULL;
|
||||
char * end = NULL;
|
||||
char *s1 = NULL, *s2 = NULL, *i = NULL, *o = NULL;
|
||||
char *pat = NULL;
|
||||
char sep = '/';
|
||||
|
||||
if ( NULL != (p = strchr(slug, ':')) ) {
|
||||
// this slug contains a pattern
|
||||
end = strchr(p, '}');
|
||||
// find '{'
|
||||
s1 = strchr(str, '{');
|
||||
|
||||
// start after ':'
|
||||
return strndup( (p + 1) , (end - p - 1) );
|
||||
} else {
|
||||
if ((pat = malloc(128)) == NULL) {
|
||||
if ( s1 == NULL ) {
|
||||
return strdup(str);
|
||||
}
|
||||
|
||||
if ( (s1 - str) > 0 ) {
|
||||
sep = *(s1-1);
|
||||
}
|
||||
|
||||
char * out = NULL;
|
||||
if ((out = calloc(sizeof(char),128)) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// append prefix
|
||||
o = out;
|
||||
strncat(o, str, s1 - str);
|
||||
o += (s1 - str);
|
||||
|
||||
// start after ':'
|
||||
if ( NULL != (pat = strchr(s1, ':')) ) {
|
||||
pat++;
|
||||
|
||||
// this slug contains a pattern
|
||||
s2 = strchr(pat, '}');
|
||||
|
||||
*o = '(';
|
||||
o++;
|
||||
|
||||
strncat(o, pat, (s2 - pat) );
|
||||
o += (s2 - pat);
|
||||
|
||||
*o = ')';
|
||||
o++;
|
||||
|
||||
} else {
|
||||
// should return a '[^/]+' pattern
|
||||
snprintf(pat, 128, "[^%c]+", sep);
|
||||
// strncat(c, "([^%c]+)", strlen("([^%c]+)") );
|
||||
// snprintf(pat, 128, "([^%c]+)", sep);
|
||||
sprintf(o, "([^%c]+)", sep);
|
||||
o+= sizeof("([^%c]+)");
|
||||
}
|
||||
return pat;
|
||||
|
||||
s2++;
|
||||
while( (s2 - str) > len ) {
|
||||
*o = *s2;
|
||||
s2++;
|
||||
o++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -62,20 +62,37 @@ START_TEST (test_combine_patterns)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (test_slug_to_pcre)
|
||||
START_TEST (test_compile_slug)
|
||||
{
|
||||
/*
|
||||
char * pattern;
|
||||
pattern = slug_to_pcre("{id}", '/');
|
||||
fail_if( strcmp(pattern, "[^/]+") != 0 , "as [^/]+" );
|
||||
pattern = compile_slug("{id}", strlen("{id}"));
|
||||
ck_assert_str_eq( pattern, "([^/]+)" );
|
||||
free(pattern);
|
||||
|
||||
pattern = slug_to_pcre("{id:[a-z]+}", '/');
|
||||
fail_if( strcmp(pattern, "[a-z]+") != 0 , "as [a-z]+" );
|
||||
pattern = compile_slug("/{id}", strlen("/{id}"));
|
||||
ck_assert_str_eq( pattern, "/([^/]+)" );
|
||||
free(pattern);
|
||||
|
||||
pattern = compile_slug("-{id}", strlen("-{id}"));
|
||||
ck_assert_str_eq( pattern, "-([^-]+)" );
|
||||
free(pattern);
|
||||
|
||||
pattern = compile_slug("{id}-{title}", strlen("{id}-{title}"));
|
||||
ck_assert_str_eq( pattern, "([^/]+)-([^-]+)" );
|
||||
free(pattern);
|
||||
|
||||
|
||||
pattern = compile_slug("{id:[a-z]+}", strlen("{id:[a-z]+}") );
|
||||
ck_assert_str_eq( pattern, "([a-z]+)" );
|
||||
free(pattern);
|
||||
|
||||
|
||||
pattern = compile_slug("/path/{id:[a-z]+}", strlen("/path/{id:[a-z]+}") );
|
||||
ck_assert_str_eq( pattern, "/path/([a-z]+)" );
|
||||
free(pattern);
|
||||
*/
|
||||
|
||||
/*
|
||||
char * p = malloc(sizeof(char) * 10);
|
||||
strncat(p, "foo", 3);
|
||||
|
@ -221,7 +238,7 @@ Suite* r3_suite (void) {
|
|||
tcase_add_test(tcase, test_rnode_construct_uniq);
|
||||
tcase_add_test(tcase, test_rnode_find_edge);
|
||||
tcase_add_test(tcase, test_rnode_insert_routel);
|
||||
tcase_add_test(tcase, test_slug_to_pcre);
|
||||
tcase_add_test(tcase, test_compile_slug);
|
||||
tcase_add_test(tcase, test_combine_patterns);
|
||||
|
||||
suite_add_tcase(suite, tcase);
|
||||
|
|
Loading…
Reference in a new issue