improve r3_slug_parse function
This commit is contained in:
parent
6dfd37d43d
commit
359d9df369
1 changed files with 33 additions and 7 deletions
40
src/slug.c
40
src/slug.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue