filter names no args

This commit is contained in:
Isha
2014-03-03 02:53:12 +00:00
parent bcb3f831b6
commit 331cf067b1
2 changed files with 85 additions and 46 deletions
+82 -43
View File
@@ -18,31 +18,35 @@ static VALUE rb_variable_allocate(VALUE klass)
return obj; 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; int skipped = 0; char * ptr = str;
while (i < len && isspace(*ptr)) while (skipped < len && isspace(*ptr))
{i++; ptr++;} {skipped++; ptr++;}
return i; 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; int p = 0; /* Current position in string */
while (count < len) { 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 '"': case '"':
if (start == -1) {start = count; quoted = '"';} if (start == -1) {start = p; quoted_by = '"';}
else if (cursor[start] == '"') {end = count; goto form_name;} else if (str[start] == '"') {end = p; goto quoted_fragment_found;}
else if (quoted == -1) quoted = '"'; else if (quoted_by == -1) quoted_by = '"';
else if (quoted == '"') quoted = -1; else if (quoted_by == '"') quoted_by = -1;
break; break;
case '\'': case '\'':
if (start == -1) {start = count; quoted = '\'';} if (start == -1) {start = p; quoted_by = '\'';}
else if (cursor[start] == '\'') {end = count; goto form_name;} else if (str[start] == '\'') {end = p; goto quoted_fragment_found;}
else if (quoted == -1) quoted = '\''; else if (quoted_by == -1) quoted_by = '\'';
else if (quoted == '\'') quoted = -1; else if (quoted_by == '\'') quoted_by = -1;
break; break;
case '|': case '|':
case ',': case ',':
@@ -52,66 +56,101 @@ static char * get_quoted_fragment(char * cursor, int len, int * ret_size)
case '\t': case '\t':
case '\v': case '\v':
case ' ': 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; break;
default: default:
if (start == -1) start = count; if (start == -1) start = p;
break; 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) { 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; *ret_size = end-start+1;
return &cursor[start]; *end_offset = end+1;
return &str[start];
} else { } else {
// rb_iv_set(self, "@name", Qnil);
*ret_size = 0; *ret_size = 0;
return NULL; return NULL;
} }
} }
static VALUE get_filters(char * cursor, int len, VALUE self) { static VALUE get_filters(char * str, int len, VALUE self) {
int count = 0; VALUE filters_arr = rb_ary_new();
while(count<len) { int p = 0;
if (cursor[count] == '|') { int ret_size, end_offset;
count += skip_whitespace(&cursor[count]+1, len-count); char * f;
while(p<len) {
if (str[p] == '|') {
VALUE filter = rb_ary_new();
VALUE f_args = rb_ary_new();
p += skip_whitespace(&str[p+1], len-p-1);
f = get_quoted_fragment(&str[p], len-p, &ret_size, &end_offset);
p += end_offset-1;
if (f) {
if (f[ret_size-1] == ':') ret_size--;
rb_ary_push(filter, rb_str_new(f, ret_size));
}
/* Check for filter arguments */
// do {
// p += skip_whitespace(&str[p+1], len-p-1);
// if (str[p] == '|')
// f = get_quoted_fragment(&str[p], len-p, &ret_size, &end_offset);
// p += end_offset-1;
// p += skip_whitespace(&str[p+1], len-p-1);
// if (f) rb_ary_push(f_args, rb_str_new(f, ret_size));
// } while (str[p] == ',' || str[p] == ':');
rb_ary_push(filter, f_args);
/* Add to filters_arr array */
rb_ary_push(filters_arr, filter);
} }
p++;
} }
return self; return filters_arr;
} }
static void rb_variable_lax_parse(VALUE self, VALUE m) static VALUE rb_variable_lax_parse(VALUE self, VALUE m)
{ {
char * markup = RSTRING_PTR(m); char * markup = RSTRING_PTR(m);
int markup_len = RSTRING_LEN(m); int markup_len = RSTRING_LEN(m);
char * cursor = markup; int count = 0; VALUE filters; int size; char * cursor = markup; int cursor_pos = 0;
VALUE filters_arr;
int size, end_offset;
/* Extract name */ /* Extract name */
count += skip_whitespace(markup, markup_len); cursor_pos += skip_whitespace(markup, markup_len);
cursor = markup+count; cursor = markup + cursor_pos;
cursor = get_quoted_fragment(cursor, markup_len-count, &size); cursor = get_quoted_fragment(cursor, markup_len - cursor_pos, &size, &end_offset);
if (cursor == NULL) { if (cursor == NULL) {
rb_iv_set(self, "@name", Qnil); rb_iv_set(self, "@name", Qnil);
filters = rb_ary_new(); filters_arr = rb_ary_new();
rb_iv_set(self, "@filters", filters); rb_iv_set(self, "@filters", filters_arr);
} }
else else
{ {
rb_iv_set(self, "@name", rb_str_new(cursor, size)); rb_iv_set(self, "@name", rb_str_new(cursor, size));
/* Extract filters */
// filters = get_filters(cursor, (markup-cursor)/sizeof(char), self);
}
/* Extract filters */
if (end_offset < markup_len) {
cursor = &markup[end_offset];
filters_arr = get_filters(cursor, markup_len - end_offset, self);
rb_iv_set(self, "@filters", filters_arr);
}
}
return filters_arr;
} }
void init_liquid_variable() void init_liquid_variable()
+3 -3
View File
@@ -15,7 +15,7 @@ class VariableTest < Test::Unit::TestCase
var = Variable.new('hello | textileze | paragraph') var = Variable.new('hello | textileze | paragraph')
assert_equal 'hello', var.name assert_equal 'hello', var.name
# assert_equal [["textileze",[]], ["paragraph",[]]], var.filters assert_equal [["textileze",[]], ["paragraph",[]]], var.filters
var = Variable.new(%! hello | strftime: '%Y'!) var = Variable.new(%! hello | strftime: '%Y'!)
assert_equal 'hello', var.name assert_equal 'hello', var.name
@@ -47,7 +47,7 @@ class VariableTest < Test::Unit::TestCase
var = Variable.new(%! hello | things: "%Y, okay?", 'the other one'!) var = Variable.new(%! hello | things: "%Y, okay?", 'the other one'!)
assert_equal 'hello', var.name assert_equal 'hello', var.name
# assert_equal [["things",["\"%Y, okay?\"","'the other one'"]]], var.filters # assert_equal [["things",["\"%Y, okay?\"","'the other one'"]]], var.filters
end end
def test_filter_with_date_parameter def test_filter_with_date_parameter
@@ -59,7 +59,7 @@ class VariableTest < Test::Unit::TestCase
def test_filters_without_whitespace def test_filters_without_whitespace
var = Variable.new('hello | textileze | paragraph') var = Variable.new('hello | textileze | paragraph')
assert_equal 'hello', var.name assert_equal 'hello', var.name
# assert_equal [["textileze",[]], ["paragraph",[]]], var.filters assert_equal [["textileze",[]], ["paragraph",[]]], var.filters
var = Variable.new('hello|textileze|paragraph') var = Variable.new('hello|textileze|paragraph')
assert_equal 'hello', var.name assert_equal 'hello', var.name