errstr parameter in slug

This commit is contained in:
c9s 2014-06-01 20:51:47 +08:00
parent 2858ede695
commit 70693ea1f2
4 changed files with 29 additions and 11 deletions

View file

@ -10,7 +10,7 @@
#include "r3.h" #include "r3.h"
#include "config.h" #include "config.h"
int slug_count(const char * p, int len); int slug_count(const char * p, int len, char ** errstr);
char * slug_compile(const char * str, int len); char * slug_compile(const char * str, int len);
@ -20,7 +20,7 @@ char * slug_find_pattern(const char *s1, int *len);
char * slug_find_placeholder(const char *s1, int *len); char * slug_find_placeholder(const char *s1, int *len);
char * inside_slug(const char * needle, int needle_len, char *offset); char * inside_slug(const char * needle, int needle_len, char *offset, char **errstr);
char * ltrim_slash(char* str); char * ltrim_slash(char* str);

View file

@ -493,7 +493,7 @@ node * r3_tree_insert_pathl_(node *tree, const char *path, int path_len, route *
// branch the edge at correct position (avoid broken slugs) // branch the edge at correct position (avoid broken slugs)
const char *slug_s; const char *slug_s;
if ( (slug_s = inside_slug(path, path_len, (char*) path + prefix_len)) != NULL ) { if ( (slug_s = inside_slug(path, path_len, ((char*) path + prefix_len), NULL)) != NULL ) {
prefix_len = slug_s - path; prefix_len = slug_s - path;
} }
@ -503,7 +503,9 @@ node * r3_tree_insert_pathl_(node *tree, const char *path, int path_len, route *
// common prefix not found, insert a new edge for this pattern // common prefix not found, insert a new edge for this pattern
if ( prefix_len == 0 ) { if ( prefix_len == 0 ) {
// there are two more slugs, we should break them into several parts // there are two more slugs, we should break them into several parts
int slug_cnt = slug_count(path, path_len); char *errstr = NULL;
int slug_cnt = slug_count(path, path_len, &errstr);
if ( slug_cnt > 1 ) { if ( slug_cnt > 1 ) {
int slug_len; int slug_len;
char *p = slug_find_placeholder(path, &slug_len); char *p = slug_find_placeholder(path, &slug_len);

View file

@ -42,7 +42,7 @@ int r3_pattern_to_opcode(const char * pattern, int len) {
/** /**
* provide a quick way to count slugs, simply search for '{' * provide a quick way to count slugs, simply search for '{'
*/ */
int slug_count(const char * p, int len) { int slug_count(const char * p, int len, char **errstr) {
int s = 0; int s = 0;
int lev = 0; int lev = 0;
while( len-- ) { while( len-- ) {
@ -56,6 +56,15 @@ int slug_count(const char * p, int len) {
} }
p++; p++;
} }
/*
XXX:
if (lev != 0) {
if (errstr) {
asprintf(errstr, "incomplete slug pattern: %s", p);
}
return 0;
}
*/
return s; return s;
} }
@ -63,7 +72,7 @@ bool contains_slug(const char * str) {
return strchr(str, '{') != NULL ? TRUE : FALSE; return strchr(str, '{') != NULL ? TRUE : FALSE;
} }
char * inside_slug(const char * needle, int needle_len, char *offset) { char * inside_slug(const char * needle, int needle_len, char *offset, char **errstr) {
char * s1 = offset; char * s1 = offset;
char * s2 = offset; char * s2 = offset;
@ -89,6 +98,13 @@ char * inside_slug(const char * needle, int needle_len, char *offset) {
if (found_s1 && found_s2) { if (found_s1 && found_s2) {
return s1; return s1;
} }
if (found_s1 || found_s2) {
// wrong slug pattern
if(errstr) {
asprintf(errstr, "incomplete slug pattern");
}
return NULL;
}
return NULL; return NULL;
} }

View file

@ -76,19 +76,19 @@ START_TEST (test_inside_slug)
{ {
char * pattern = "/user/{name:\\s+}/to/{id}"; char * pattern = "/user/{name:\\s+}/to/{id}";
char * offset = strchr(pattern, '{') + 2; char * offset = strchr(pattern, '{') + 2;
ck_assert( (int)inside_slug(pattern, strlen(pattern), offset) ); ck_assert( (int)inside_slug(pattern, strlen(pattern), offset, NULL) );
ck_assert( *(inside_slug(pattern, strlen(pattern), offset)) == '{' ); ck_assert( *(inside_slug(pattern, strlen(pattern), offset, NULL)) == '{' );
ck_assert( ! inside_slug(pattern, strlen(pattern), pattern) ); ck_assert( ! inside_slug(pattern, strlen(pattern), pattern, NULL) );
} }
END_TEST END_TEST
START_TEST (test_slug_count) START_TEST (test_slug_count)
{ {
char * pattern = "/user/{name:\\s+}/to/{id}"; char * pattern = "/user/{name:\\s+}/to/{id}";
ck_assert_int_eq( slug_count(pattern, strlen(pattern) ), 2 ); ck_assert_int_eq( slug_count(pattern, strlen(pattern), NULL), 2 );
char * pattern2 = "/user/{name:\\d{3}}/to/{id}"; char * pattern2 = "/user/{name:\\d{3}}/to/{id}";
ck_assert_int_eq( slug_count(pattern2, strlen(pattern) ), 2 ); ck_assert_int_eq( slug_count(pattern2, strlen(pattern), NULL), 2 );
} }
END_TEST END_TEST