diff --git a/ext/liquid/variable.c b/ext/liquid/variable.c index 4b39f5c..8907de3 100644 --- a/ext/liquid/variable.c +++ b/ext/liquid/variable.c @@ -18,31 +18,35 @@ static VALUE rb_variable_allocate(VALUE klass) return obj; } -static int skip_whitespace(char * str, int len) +static inline int skip_whitespace(char * str, int len) { - int i = 0; char * ptr = str; - while (i < len && isspace(*ptr)) - {i++; ptr++;} - return i; + int skipped = 0; char * ptr = str; + while (skipped < len && isspace(*ptr)) + {skipped++; ptr++;} + return skipped; } -static char * get_quoted_fragment(char * cursor, int len, int * ret_size) +static char * get_quoted_fragment(char * str, int len, int * ret_size, int * end_offset) { - int count = 0; int start = -1, end = -1; char quoted = -1; - while (count < len) { + int p = 0; /* Current position in string */ + int start = -1, end = -1; /* Start and end indices for the found string */ + char quoted_by = -1; /* Is the current part of string quoted by a single or double quote? If so + ignore any special chars */ + + while (p < len) { - switch (cursor[count]) { + switch (str[p]) { case '"': - if (start == -1) {start = count; quoted = '"';} - else if (cursor[start] == '"') {end = count; goto form_name;} - else if (quoted == -1) quoted = '"'; - else if (quoted == '"') quoted = -1; + if (start == -1) {start = p; quoted_by = '"';} + else if (str[start] == '"') {end = p; goto quoted_fragment_found;} + else if (quoted_by == -1) quoted_by = '"'; + else if (quoted_by == '"') quoted_by = -1; break; case '\'': - if (start == -1) {start = count; quoted = '\'';} - else if (cursor[start] == '\'') {end = count; goto form_name;} - else if (quoted == -1) quoted = '\''; - else if (quoted == '\'') quoted = -1; + if (start == -1) {start = p; quoted_by = '\'';} + else if (str[start] == '\'') {end = p; goto quoted_fragment_found;} + else if (quoted_by == -1) quoted_by = '\''; + else if (quoted_by == '\'') quoted_by = -1; break; case '|': case ',': @@ -52,66 +56,101 @@ static char * get_quoted_fragment(char * cursor, int len, int * ret_size) case '\t': case '\v': case ' ': - if (start != -1 && quoted == -1) {end = count-1; goto form_name;} + if (start != -1 && quoted_by == -1) {end = p-1; goto quoted_fragment_found;} break; default: - if (start == -1) start = count; + if (start == -1) start = p; break; } - count++; + p++; } - if (count == len && start != -1 && end == -1) end = len-1; + if (p == len && start != -1 && end == -1) end = len-1; - form_name: +quoted_fragment_found: if (end > start) { - // rb_iv_set(self, "@name", rb_str_new(&cursor[start], end-start+1)); - // return &cursor[end+1]; *ret_size = end-start+1; - return &cursor[start]; - + *end_offset = end+1; + return &str[start]; } else { - // rb_iv_set(self, "@name", Qnil); *ret_size = 0; return NULL; } } -static VALUE get_filters(char * cursor, int len, VALUE self) { - int count = 0; +static VALUE get_filters(char * str, int len, VALUE self) { + VALUE filters_arr = rb_ary_new(); - while(count