From c91c06ec3bd085fddebcd8e73fb85010f6aaca31 Mon Sep 17 00:00:00 2001 From: c9s Date: Thu, 15 May 2014 12:47:14 +0800 Subject: [PATCH] Add token list tests --- include/str.h | 1 - include/token.h | 4 +++ src/str.c | 59 +--------------------------------------- src/token.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++- tests/test_tree.c | 33 ++++++++++++++++++++--- 5 files changed, 103 insertions(+), 63 deletions(-) diff --git a/include/str.h b/include/str.h index dc83cdd..2559c70 100644 --- a/include/str.h +++ b/include/str.h @@ -7,6 +7,5 @@ #ifndef STR_H #define STR_H -char** split_route_pattern(char *pattern, int pattern_len); #endif /* !STR_H */ diff --git a/include/token.h b/include/token.h index 01408c0..3d37029 100644 --- a/include/token.h +++ b/include/token.h @@ -29,4 +29,8 @@ bool token_array_append(token_array * list, char * token); void token_array_free(token_array *l); +void token_array_dump(token_array *l); + +token_array * split_route_pattern(char *pattern, int pattern_len); + #endif /* !TOKEN_H */ diff --git a/src/str.c b/src/str.c index 49994ab..b814e0a 100644 --- a/src/str.c +++ b/src/str.c @@ -9,66 +9,9 @@ #include #include #include "str.h" +#include "token.h" -/** - * This function is used to split route path into a string array, not for performance. - * hence this function should be safe. - * - * Split "/path/foo/{id}" into [ "/path" , "/foo" , "/{id}" ] - * Split "/path/bar/{id}" into [ "/path" , "/foo" , "/{id}" ] - * Split "/blog/post/{id}" into [ "/blog" , "/post" , "/{id}" ] - * Split "/blog/{id}" into [ "/blog" , "/{id}" ] - * Split "/blog" into [ "/blog" ] - * Split "/b" into [ "/b" ] - * Split "/{id}" into [ "/{id}" ] - * - * @param char* pattern - * @param int pattern_len - * - * @return char** - */ -char** split_route_pattern(char *pattern, int pattern_len) { - char *s1, *p = pattern; - - char ** list; - unsigned int list_idx = 0; - unsigned int list_size = 20; - - list = malloc( sizeof(char**) * list_size ); // default token list size - - s1 = p; - while (*p && (p - pattern) < pattern_len ) { - - // a slug - if ( *p == '{' ) { - while (*(p++) != '}') { - if ( p - pattern > pattern_len ) { - // XXX: unexpected error (unclosed slug) - } - } - list[list_idx] = strndup(s1, p-s1); - printf("%d -> %s\n", list_idx, list[list_idx]); - list_idx++; - - s1 = p; - } - else if ( *p == '/' ) { - char *s2; - while (*(++p) != '/'); - // printf("-> %s\n", strndup(s1, p-s1) ); - - list[list_idx] = strndup(s1, p-s1); - printf("%d -> %s\n", list_idx, list[list_idx]); - list_idx++; - - s1 = p; - } - p++; - } - return NULL; -} - char** str_split(char* a_str, const char a_delim) { diff --git a/src/token.c b/src/token.c index f5f8ba6..8547bce 100644 --- a/src/token.c +++ b/src/token.c @@ -5,6 +5,9 @@ * Distributed under terms of the MIT license. */ #include +#include +#include +#include #include "token.h" @@ -33,10 +36,21 @@ bool token_array_append(token_array * l, char * token) { return FALSE; } } - l->tokens[ ++(l->len) ] = token; + l->tokens[ l->len++ ] = token; return TRUE; } +void token_array_dump(token_array *l) { + printf("["); + for ( int i = 0; i < l->len ; i++ ) { + printf("\"%s\"", l->tokens[i] ); + if ( i + 1 != l->len ) { + printf(", "); + } + } + printf("]\n"); +} + void token_array_free(token_array *l) { for ( int i = 0; i < l->len ; i++ ) { char * t = l->tokens[ i ]; @@ -46,3 +60,56 @@ void token_array_free(token_array *l) { } + +/** + * This function is used to split route path into a string array, not for performance. + * hence this function should be safe. + * + * Split "/path/foo/{id}" into [ "/path" , "/foo" , "/{id}" ] + * Split "/path/bar/{id}" into [ "/path" , "/foo" , "/{id}" ] + * Split "/blog/post/{id}" into [ "/blog" , "/post" , "/{id}" ] + * Split "/blog/{id}" into [ "/blog" , "/{id}" ] + * Split "/blog" into [ "/blog" ] + * Split "/b" into [ "/b" ] + * Split "/{id}" into [ "/{id}" ] + * + * @param char* pattern + * @param int pattern_len + * + * @return char** + */ +token_array * split_route_pattern(char *pattern, int pattern_len) { + char *s1, *p = pattern; + + token_array * token_array = token_array_create( 20 ); + + s1 = p; + p++; + while (*p && (p - pattern) < pattern_len ) { + + // a slug + if ( *p == '{' ) { + // find closing '}' + while (*p != '}') { + p++; + assert(p - pattern < pattern_len ); // throw exception + } + p++; // contains the '}' + // printf("==> %s\n", strndup(s1, p-s1) ); + token_array_append(token_array, strndup(s1, p-s1) ); + s1 = p; + continue; + } + else if ( *p == '/' ) { + // printf("==> %s\n", strndup(s1, p-s1) ); + token_array_append(token_array, strndup(s1, p-s1) ); + s1 = p; + } + p++; + } + + if ( p-s1 > 0 ) { + token_array_append(token_array, strndup(s1, p-s1) ); + } + return token_array; +} diff --git a/tests/test_tree.c b/tests/test_tree.c index a0123ee..c0e7241 100644 --- a/tests/test_tree.c +++ b/tests/test_tree.c @@ -6,9 +6,36 @@ START_TEST (test_route) { - split_route_pattern("/blog", strlen("/blog") ); - split_route_pattern("/foo/{id}", strlen("/foo/{id}") ); - split_route_pattern("/{title}", strlen("/{title}") ); + token_array *t; + + t = split_route_pattern("/blog", strlen("/blog") ); + fail_if( t == NULL ); + token_array_dump(t); + token_array_free(t); + + t = split_route_pattern("/foo/{id}", strlen("/foo/{id}") ); + fail_if( t == NULL ); + token_array_dump(t); + fail_if( t->len != 2 ); + token_array_free(t); + + t = split_route_pattern("/foo/bar/{id}", strlen("/foo/bar/{id}") ); + fail_if( t == NULL ); + token_array_dump(t); + fail_if( t->len != 3 ); + token_array_free(t); + + t = split_route_pattern("/{title}", strlen("/{title}") ); + fail_if( t == NULL ); + token_array_dump(t); + fail_if( t->len != 1 ); + token_array_free(t); + + t = split_route_pattern("/", strlen("/") ); + fail_if( t == NULL ); + token_array_dump(t); + fail_if( t->len != 1 ); + token_array_free(t); } END_TEST