diff --git a/Makefile b/Makefile index 51674c2..e5e1f6d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC=gcc all: test shortcodes.c: shortcodes.rl - ragel -G2 -L shortcodes.rl -o shortcodes.c + ragel -G2 shortcodes.rl -o shortcodes.c tests.so: shortcodes.c tests.c $(CC) -fPIC -shared -g -o $@ $^ -lbg -lcgreen clean: diff --git a/shortcodes.h b/shortcodes.h index 01840b9..254ae73 100644 --- a/shortcodes.h +++ b/shortcodes.h @@ -5,15 +5,15 @@ // and goes on for len characters. struct chunk { - int start, len; + unsigned int start, len; }; typedef struct chunk chunk; // An error struct sc_error { - int position; - int code; + unsigned int position; + unsigned int code; }; typedef struct sc_error sc_error; @@ -26,7 +26,7 @@ struct shortcode char matching; chunk argnames[100]; chunk argvals[100]; - int argcount; + unsigned int argcount; }; typedef struct shortcode shortcode; @@ -34,7 +34,7 @@ struct sc_result { shortcode sc[100]; sc_error errors[10]; - int errcount; + unsigned int errcount; }; typedef struct sc_result sc_result; diff --git a/shortcodes.rl b/shortcodes.rl index cd76fb4..15a7ad0 100644 --- a/shortcodes.rl +++ b/shortcodes.rl @@ -87,8 +87,6 @@ matched_shortcode = (shortcode any* closing_shortcode) @ { - sc_list[c_sc-1].matching = 1; - sc_list[c_sc-1].whole.len = p-start-sc_list[c_sc-1].whole.start + 1; if ( sc_list[c_sc-1].name.len != sc_list[c_sc].name.len || strncmp( @@ -96,11 +94,16 @@ start + sc_list[c_sc].name.start, sc_list[c_sc-1].name.len) !=0) { - result.errors[result.errcount].position = p-start; + result.errors[result.errcount].position = + sc_list[c_sc].whole.start; result.errors[result.errcount].code = ERR_MISMATCHED_CLOSING_TAG; result.errcount++; + } else { + // The previous shortcode is matching (mark it) + sc_list[c_sc-1].matching = 1; + sc_list[c_sc-1].whole.len = p-start-sc_list[c_sc-1].whole.start + 1; } - // Reuse this shortcode entry for next one + // Reuse the closing shortcode tag entry for next one sc_list[c_sc].name.start = 0; sc_list[c_sc].name.len=0; }; diff --git a/tests.c b/tests.c index 8526604..f4753b0 100644 --- a/tests.c +++ b/tests.c @@ -20,6 +20,7 @@ Ensure(parse, empty_string) result = parse(input); // This means no shortcodes in it assert_that(result.sc[0].name.len, is_equal_to(0)); + assert_that(result.errcount, is_equal_to(0)); } Ensure(parse, simple_shortcode) @@ -37,8 +38,22 @@ Ensure(parse, simple_shortcode) // The whole shortcode is the whole thing chunk_s(input, result.sc[0].whole); assert_that(s.s, is_equal_to_string("{{% shortcode %}}")); + assert_that(result.errcount, is_equal_to(0)); } +Ensure(parse, mismatched_tags) +{ + char *input = "foobar {{% shortcode %}}blah{{% /foo %}}"; + result = parse(input); + // No shortcodes + assert_that(result.sc[0].name.len, is_equal_to(0)); + assert_that(result.errcount, is_equal_to(1)); + assert_that(result.errors[0].code, is_equal_to(ERR_MISMATCHED_CLOSING_TAG)); + str_copyb(&s, input + result.errors[0].position, 8); + assert_that(s.s, is_equal_to_string("{{% /foo")); +} + + Ensure(parse, mismatched_brackets) { char *input = "foobar {{% shortcode >}}blah"; @@ -61,6 +76,7 @@ Ensure(parse, mismatched_brackets_inside_data_are_ok) assert_that(s.s, is_equal_to_string("{{% sc %}} >}}blah {{% /sc %}}")); chunk_s(input, result.sc[0].data); assert_that(s.s, is_equal_to_string(" >}}blah ")); + assert_that(result.errcount, is_equal_to(0)); } Ensure(parse, mismatched_brackets_in_qval_are_ok) @@ -73,6 +89,7 @@ Ensure(parse, mismatched_brackets_in_qval_are_ok) assert_that(s.s, is_equal_to_string("{{% sc \">}}blah\" %}} {{% /sc %}}")); chunk_s(input, result.sc[0].argvals[0]); assert_that(s.s, is_equal_to_string(">}}blah")); + assert_that(result.errcount, is_equal_to(0)); } Ensure(parse, inner_spaces_optional) @@ -90,6 +107,7 @@ Ensure(parse, inner_spaces_optional) // The whole shortcode is the whole thing chunk_s(input, result.sc[0].whole); assert_that(s.s, is_equal_to_string("{{% shortcode%}}")); + assert_that(result.errcount, is_equal_to(0)); } Ensure(parse, name_can_be_path) @@ -104,6 +122,7 @@ Ensure(parse, name_can_be_path) assert_that(s.s, is_equal_to_string("shortcode/foo/bar")); assert_that(result.sc[0].matching, is_equal_to(0)); assert_that(result.sc[0].argcount, is_equal_to(0)); + assert_that(result.errcount, is_equal_to(0)); } Ensure(parse, multiple_shortcodes) @@ -129,6 +148,7 @@ Ensure(parse, multiple_shortcodes) // The whole shortcode is the whole thing chunk_s(input, result.sc[1].whole); assert_that(s.s, is_equal_to_string("{{}}")); + assert_that(result.errcount, is_equal_to(0)); } Ensure(parse, matching_shortcode) @@ -150,6 +170,7 @@ Ensure(parse, matching_shortcode) // The whole shortcode is the whole thing chunk_s(input, result.sc[0].whole); assert_that(s.s, is_equal_to_string("{{% shortcode %}}foo bar{{% /shortcode %}}")); + assert_that(result.errcount, is_equal_to(0)); } Ensure(parse, shortcode_args) @@ -193,6 +214,7 @@ Ensure(parse, shortcode_args) assert_that(s.s, is_equal_to_string("baz")); chunk_s(input, result.sc[0].argvals[4]); assert_that(s.s, is_equal_to_string("v2")); + assert_that(result.errcount, is_equal_to(0)); } // BUG? @@ -202,26 +224,4 @@ Ensure(parse, shortcode_args) // result = parse(input); // // No shortcodes // assert_that(result.sc[0].name.len, is_equal_to(0)); -// } - -#ifdef MAIN -int main(int argc, char **argv) -{ - str_init(&s); - TestSuite *suite = create_test_suite(); - add_test_with_context(suite, parse, empty_string); - add_test_with_context(suite, parse, simple_shortcode); - add_test_with_context(suite, parse, mismatched_brackets); - add_test_with_context(suite, parse, mismatched_brackets_inside_data_are_ok); - add_test_with_context(suite, parse, mismatched_brackets_in_qval_are_ok); - add_test_with_context(suite, parse, name_can_be_path); - add_test_with_context(suite, parse, inner_spaces_optional); - add_test_with_context(suite, parse, multiple_shortcodes); - add_test_with_context(suite, parse, matching_shortcode); - add_test_with_context(suite, parse, shortcode_args); - - // Bugs - // add_test_with_context(suite, parse, escaped_shortcode); - return run_test_suite(suite, create_text_reporter()); -} -#endif \ No newline at end of file +// } \ No newline at end of file