From 2d3c43dffeb048297313cd9333731d47d66010a0 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Sat, 21 Apr 2012 23:34:42 +1000 Subject: [PATCH] skin_engine: rework the parser to be closer to the langauge grammar. The parser was unconditionally scanning things which it thought were conditional/enum lists (or tag arg lists) when they couldn't possibly be (i.e < inside a param which should be valid). This change fixes it (i.e %?and(%if(%pv, <, -50), %if(%mp, >i, 1)) is perfectly valid now. This *may* break your exsiting skins if you were using %if with < or > Change-Id: Ia24dbdf0b11fc7d8a735c1111d648c3bebd68ac6 --- lib/skin_parser/skin_parser.c | 65 +++----------------------------- lib/skin_parser/skin_scan.c | 71 +++++++++++++++++++++++++---------- lib/skin_parser/skin_scan.h | 1 + 3 files changed, 57 insertions(+), 80 deletions(-) diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c index a81bcded34..44a1c03245 100644 --- a/lib/skin_parser/skin_parser.c +++ b/lib/skin_parser/skin_parser.c @@ -182,26 +182,12 @@ static struct skin_element* skin_parse_viewport(const char** document) } else if(*cursor == TAGSYM) { - /* A ';' directly after a '%' doesn't count */ - cursor ++; - - if(*cursor == '\0') - break; - - cursor++; + skip_tag(&cursor); } else if(*cursor == COMMENTSYM) { skip_comment(&cursor); } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); - } else { /* Advancing the cursor as normal */ @@ -445,20 +431,9 @@ static struct skin_element* skin_parse_sublines_optional(const char** document, { skip_comment(&cursor); } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); - } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } else if(*cursor == TAGSYM) { - cursor++; - if(*cursor == '\0' || *cursor == '\n') - break; - cursor++; + skip_tag(&cursor); } else if(*cursor == MULTILINESYM) { @@ -595,19 +570,12 @@ static int skin_parse_tag(struct skin_element* element, const char** document) /* Skipping over escaped characters */ if(*cursor == TAGSYM) { - cursor++; - if(*cursor == '\0') - break; - cursor++; + skip_tag(&cursor); } else if(*cursor == COMMENTSYM) { skip_comment(&cursor); } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } else if(*cursor == ARGLISTSEPARATESYM) { num_args++; @@ -974,18 +942,9 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc { skip_comment(&cursor); } - else if(*cursor == ENUMLISTOPENSYM) - { - if (*cursor == '\n') - cursor++; - skip_enumlist(&cursor); - } else if(*cursor == TAGSYM) { - cursor++; - if(*cursor == '\0' || *cursor == '\n') - break; - cursor++; + skip_tag(&cursor); } else if(*cursor == ENUMLISTSEPARATESYM) { @@ -1139,21 +1098,7 @@ static struct skin_element* skin_parse_code_as_arg(const char** document) } else if(*cursor == TAGSYM) { - /* A ';' directly after a '%' doesn't count */ - cursor ++; - - if(*cursor == '\0') - break; - - cursor++; - } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); + skip_tag(&cursor); } else { diff --git a/lib/skin_parser/skin_scan.c b/lib/skin_parser/skin_scan.c index 50d58bc250..f93606d54d 100644 --- a/lib/skin_parser/skin_scan.c +++ b/lib/skin_parser/skin_scan.c @@ -28,6 +28,7 @@ #include "skin_debug.h" #include "symbols.h" #include "skin_parser.h" +#include "tag_table.h" /* Scanning Functions */ @@ -40,6 +41,54 @@ void skip_comment(const char** document) (*document)++; } +void skip_tag(const char** document) +{ + char tag_name[MAX_TAG_LENGTH]; + int i; + bool qmark; + const struct tag_info *tag; + const char *cursor; + + if(**document == TAGSYM) + (*document)++; + qmark = (**document == CONDITIONSYM); + if (qmark) + (*document)++; + + if (!qmark && find_escape_character(**document)) + { + (*document)++; + } + else + { + cursor = *document; + + /* Checking the tag name */ + for (i=0; cursor[i] && i 1) + { + tag_name[i-1] = '\0'; + tag = find_tag(tag_name); + i--; + } + + if (tag) + { + *document += strlen(tag->name); + } + } + if (**document == ARGLISTOPENSYM) + skip_arglist(document); + + if (**document == ENUMLISTOPENSYM) + skip_enumlist(document); +} + void skip_arglist(const char** document) { if(**document == ARGLISTOPENSYM) @@ -47,16 +96,7 @@ void skip_arglist(const char** document) while(**document && **document != ARGLISTCLOSESYM) { if(**document == TAGSYM) - { - (*document)++; - if(**document == '\0') - break; - (*document)++; - } - else if(**document == ARGLISTOPENSYM) - skip_arglist(document); - else if(**document == ENUMLISTOPENSYM) - skip_enumlist(document); + skip_tag(document); else if(**document == COMMENTSYM) skip_comment(document); else @@ -73,16 +113,7 @@ void skip_enumlist(const char** document) while(**document && **document != ENUMLISTCLOSESYM) { if(**document == TAGSYM) - { - (*document)++; - if(**document == '\0') - break; - (*document)++; - } - else if(**document == ARGLISTOPENSYM) - skip_arglist(document); - else if(**document == ENUMLISTOPENSYM) - skip_enumlist(document); + skip_tag(document); else if(**document == COMMENTSYM) skip_comment(document); else diff --git a/lib/skin_parser/skin_scan.h b/lib/skin_parser/skin_scan.h index 47d8289f98..6281582b88 100644 --- a/lib/skin_parser/skin_scan.h +++ b/lib/skin_parser/skin_scan.h @@ -29,6 +29,7 @@ extern "C" /* Scanning functions */ +void skip_tag(const char** document); void skip_comment(const char** document); void skip_arglist(const char** document); void skip_enumlist(const char** document);