diff --git a/include/define.h b/include/define.h new file mode 100644 index 0000000..126e932 --- /dev/null +++ b/include/define.h @@ -0,0 +1,16 @@ +/* + * define.h + * Copyright (C) 2014 c9s + * + * Distributed under terms of the MIT license. + */ + +#ifndef DEFINE_H +#define DEFINE_H + +typedef unsigned char bool; +#define FALSE 0 +#define TRUE 1 + + +#endif /* !DEFINE_H */ diff --git a/include/node.h b/include/node.h index 6656542..0cf5c54 100644 --- a/include/node.h +++ b/include/node.h @@ -45,6 +45,8 @@ void rnode_dump(rnode * n, int level); void rnode_combine_patterns(rnode * n); +bool rnode_has_slug_edges(rnode *n); + rnode * rnode_lookup(rnode * tree, char * path, int path_len); redge * redge_create(char * pattern, int pattern_len, rnode * child); diff --git a/include/str.h b/include/str.h index 572dc89..60d21fb 100644 --- a/include/str.h +++ b/include/str.h @@ -7,6 +7,7 @@ #ifndef STR_H #define STR_H +#include "define.h" int strndiff(char * d1, char * d2, unsigned int n); @@ -16,7 +17,8 @@ int count_slug(char * p, int len); char * compile_slug(char * str, int len); -char * contains_slug(char * str); +bool contains_slug(char * str); + char * ltrim_slash(char* str); diff --git a/include/token.h b/include/token.h index 9df8fa1..129e551 100644 --- a/include/token.h +++ b/include/token.h @@ -8,9 +8,7 @@ #ifndef TOKEN_H #define TOKEN_H -typedef unsigned char bool; -#define FALSE 0 -#define TRUE 1 +#include "define.h" typedef struct _token_array { char **tokens; diff --git a/src/node.c b/src/node.c index 6b67c7d..e04c194 100644 --- a/src/node.c +++ b/src/node.c @@ -31,7 +31,7 @@ struct _rnode { struct _redge { char * pattern; int pattern_len; - bool is_slug; + bool has_slug; rnode * child; }; @@ -108,6 +108,16 @@ redge * rnode_find_edge(rnode * n, char * pat) { return NULL; } +void rnode_compile(rnode *n) +{ + bool has_slug_edges = rnode_has_slug_edges(n); + if ( has_slug_edges ) { + rnode_combine_patterns(n); + } else { + // use normal text matching... + n->combined_pattern = NULL; + } +} /** @@ -118,7 +128,7 @@ void rnode_combine_patterns(rnode * n) { char * cpat; char * p; - cpat = malloc(128); + cpat = calloc(sizeof(char),128); if (cpat==NULL) return; @@ -127,12 +137,17 @@ void rnode_combine_patterns(rnode * n) { redge *e = NULL; for ( int i = 0 ; i < n->edge_len ; i++ ) { e = n->edges[i]; - strncat(p++,"(", 1); - strncat(p, e->pattern, e->pattern_len); + if ( e->has_slug ) { + char * slug_pat = compile_slug(e->pattern, e->pattern_len); + strcat(p, slug_pat); + } else { + strncat(p++,"(", 1); - p += e->pattern_len; + strncat(p, e->pattern, e->pattern_len); + p += e->pattern_len; - strncat(p++,")", 1); + strncat(p++,")", 1); + } if ( i + 1 < n->edge_len ) { strncat(p++,"|",1); @@ -280,6 +295,18 @@ rnode * rnode_insert_routel(rnode *tree, char *route, int route_len) return n; } +bool rnode_has_slug_edges(rnode *n) { + bool found = FALSE; + redge *e; + for ( int i = 0 ; i < n->edge_len ; i++ ) { + e = n->edges[i]; + e->has_slug = contains_slug(e->pattern); + if (e->has_slug) + found = TRUE; + } + return found; +} + void redge_branch(redge *e, int dl) { rnode *c1; // child 1, child 2 redge *e1; // edge 1, edge 2 @@ -306,25 +333,12 @@ void redge_branch(redge *e, int dl) { c1->endpoint++; } -void rnode_dump(rnode * n, int level) { - if ( n->edge_len ) { - print_indent(level); - printf("+--\n"); - for ( int i = 0 ; i < n->edge_len ; i++ ) { - redge * e = n->edges[i]; - print_indent(level + 1); - printf("|-\"%s\"\n", e->pattern); - rnode_dump( e->child, level + 1); - } - } -} redge * redge_create(char * pattern, int pattern_len, rnode * child) { redge * edge = (redge*) malloc( sizeof(redge) ); edge->pattern = pattern; edge->pattern_len = pattern_len; edge->child = child; - edge->is_slug = 0; return edge; } @@ -338,4 +352,18 @@ void redge_free(redge * e) { } - +void rnode_dump(rnode * n, int level) { + if ( n->edge_len ) { + printf(" => \n"); + for ( int i = 0 ; i < n->edge_len ; i++ ) { + redge * e = n->edges[i]; + print_indent(level); + printf(" |-\"%s\"", e->pattern); + if ( e->child ) { + rnode_dump( e->child, level + 1); + printf("\n"); + } else { + } + } + } +} diff --git a/src/str.c b/src/str.c index f3fbb80..c345a74 100644 --- a/src/str.c +++ b/src/str.c @@ -10,6 +10,7 @@ #include #include "str.h" #include "token.h" +#include "define.h" int strndiff(char * d1, char * d2, unsigned int n) { char * o = d1; @@ -44,8 +45,8 @@ int count_slug(char * p, int len) { return s; } -char * contains_slug(char * str) { - return strchr(str, '}'); +bool contains_slug(char * str) { + return strchr(str, '{') != NULL ? TRUE : FALSE; } /** diff --git a/tests/test_tree.c b/tests/test_tree.c index 0f8f73c..b702ae5 100644 --- a/tests/test_tree.c +++ b/tests/test_tree.c @@ -133,8 +133,11 @@ START_TEST (test_rnode_insert_routel) printf("Inserting /post/{handle}-{id}\n"); rnode_insert_routel(n, "/post/{handle}-{id}", strlen("/post/{handle}-{id}") ); + rnode_combine_patterns(n); rnode_dump(n, 0); + + /* fail_if(n == NULL, "rnode tree");