improve r3_slug_parse function

This commit is contained in:
c9s 2014-06-02 05:02:37 +08:00
parent 6dfd37d43d
commit 359d9df369

View file

@ -12,6 +12,11 @@
#include "slug.h" #include "slug.h"
#include "zmalloc.h" #include "zmalloc.h"
inline int contains_slug_char(const char * str) {
return strchr(str, '{') != NULL ? 1 : 0;
}
r3_slug_t * r3_slug_new(char * path, int path_len) { r3_slug_t * r3_slug_new(char * path, int path_len) {
r3_slug_t * s = zmalloc(sizeof(r3_slug_t)); r3_slug_t * s = zmalloc(sizeof(r3_slug_t));
s->path = path; s->path = path;
@ -60,6 +65,7 @@ char * r3_slug_to_str(r3_slug_t *s) {
} }
/* /*
r3_slug_t * r3_slug_parse_next(r3_slug_t *s, char **errstr) { r3_slug_t * r3_slug_parse_next(r3_slug_t *s, char **errstr) {
return r3_slug_parse(s->end, s->path_len - (s->end - s->begin), errstr); return r3_slug_parse(s->end, s->path_len - (s->end - s->begin), errstr);
@ -68,6 +74,18 @@ r3_slug_t * r3_slug_parse_next(r3_slug_t *s, char **errstr) {
r3_slug_t * r3_slug_parse(const char *needle, int needle_len, char *offset, char **errstr) { r3_slug_t * r3_slug_parse(const char *needle, int needle_len, char *offset, char **errstr) {
r3_slug_t * s = r3_slug_new(needle, needle_len); r3_slug_t * s = r3_slug_new(needle, needle_len);
if (!s) {
return NULL;
}
if (!offset) {
offset = (char*) needle; // from the begining of the needle
}
// there is no slug
if (!contains_slug_char(offset)) {
return NULL;
}
int cnt = 0; int cnt = 0;
int state = 0; int state = 0;
@ -75,31 +93,40 @@ r3_slug_t * r3_slug_parse(const char *needle, int needle_len, char *offset, char
while( (p-needle) < needle_len) { while( (p-needle) < needle_len) {
// escape one character
if (*p == '\\' ) { if (*p == '\\' ) {
p++; p++; p++; p++;
} continue;
if (state == 0 && *p == '{') {
s->begin = p+1;
} }
// slug starts with '{'
if (state == 0 && *p == '{') {
s->begin = ++p;
state++;
continue;
}
// in the middle of the slug (pattern)
if (state == 1 && *p == ':') { if (state == 1 && *p == ':') {
// start from next // start from next
s->pattern = p+1; s->pattern = ++p;
continue;
} }
// closing slug // slug closed.
if (state == 1 && *p == '}') { if (state == 1 && *p == '}') {
s->end = p; s->end = p;
s->len = s->end - s->begin; s->len = s->end - s->begin;
if (s->pattern) { if (s->pattern) {
s->pattern_len = p - s->pattern; s->pattern_len = p - s->pattern;
} }
cnt++; cnt++;
state--; state--;
p++;
break; break;
} }
// might be inside the pattern
if ( *p == '{' ) { if ( *p == '{' ) {
state++; state++;
} else if ( *p == '}' ) { } else if ( *p == '}' ) {
@ -114,6 +141,5 @@ r3_slug_t * r3_slug_parse(const char *needle, int needle_len, char *offset, char
} }
return NULL; return NULL;
} }
return s; return s;
} }