diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2012-04-16 15:42:24 +1000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2012-04-17 17:05:20 +0200 |
commit | e43b856ed0f2fa3cb03a1335c9dc311b572e88e2 (patch) | |
tree | 4b22c3178612058c739e4e76500433d11d51615a | |
parent | e92fbb42d7d25311cc03a69390ba758033d5134a (diff) | |
download | rockbox-e43b856ed0f2fa3cb03a1335c9dc311b572e88e2.tar.gz rockbox-e43b856ed0f2fa3cb03a1335c9dc311b572e88e2.zip |
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, > 1))
is perfectly valid now.
This *may* break your exsiting skins if you were using %if with < or >
Change-Id: Ibcb42bc6bb78908f79de024b61276b91b1ce02a0
Reviewed-on: http://gerrit.rockbox.org/214
Reviewed-by: Thomas Martitz <kugel@rockbox.org>
-rw-r--r-- | lib/skin_parser/skin_parser.c | 65 | ||||
-rw-r--r-- | lib/skin_parser/skin_scan.c | 71 | ||||
-rw-r--r-- | 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) | |||
182 | } | 182 | } |
183 | else if(*cursor == TAGSYM) | 183 | else if(*cursor == TAGSYM) |
184 | { | 184 | { |
185 | /* A ';' directly after a '%' doesn't count */ | 185 | skip_tag(&cursor); |
186 | cursor ++; | ||
187 | |||
188 | if(*cursor == '\0') | ||
189 | break; | ||
190 | |||
191 | cursor++; | ||
192 | } | 186 | } |
193 | else if(*cursor == COMMENTSYM) | 187 | else if(*cursor == COMMENTSYM) |
194 | { | 188 | { |
195 | skip_comment(&cursor); | 189 | skip_comment(&cursor); |
196 | } | 190 | } |
197 | else if(*cursor == ARGLISTOPENSYM) | ||
198 | { | ||
199 | skip_arglist(&cursor); | ||
200 | } | ||
201 | else if(*cursor == ENUMLISTOPENSYM) | ||
202 | { | ||
203 | skip_enumlist(&cursor); | ||
204 | } | ||
205 | else | 191 | else |
206 | { | 192 | { |
207 | /* Advancing the cursor as normal */ | 193 | /* Advancing the cursor as normal */ |
@@ -445,20 +431,9 @@ static struct skin_element* skin_parse_sublines_optional(const char** document, | |||
445 | { | 431 | { |
446 | skip_comment(&cursor); | 432 | skip_comment(&cursor); |
447 | } | 433 | } |
448 | else if(*cursor == ENUMLISTOPENSYM) | ||
449 | { | ||
450 | skip_enumlist(&cursor); | ||
451 | } | ||
452 | else if(*cursor == ARGLISTOPENSYM) | ||
453 | { | ||
454 | skip_arglist(&cursor); | ||
455 | } | ||
456 | else if(*cursor == TAGSYM) | 434 | else if(*cursor == TAGSYM) |
457 | { | 435 | { |
458 | cursor++; | 436 | skip_tag(&cursor); |
459 | if(*cursor == '\0' || *cursor == '\n') | ||
460 | break; | ||
461 | cursor++; | ||
462 | } | 437 | } |
463 | else if(*cursor == MULTILINESYM) | 438 | else if(*cursor == MULTILINESYM) |
464 | { | 439 | { |
@@ -595,19 +570,12 @@ static int skin_parse_tag(struct skin_element* element, const char** document) | |||
595 | /* Skipping over escaped characters */ | 570 | /* Skipping over escaped characters */ |
596 | if(*cursor == TAGSYM) | 571 | if(*cursor == TAGSYM) |
597 | { | 572 | { |
598 | cursor++; | 573 | skip_tag(&cursor); |
599 | if(*cursor == '\0') | ||
600 | break; | ||
601 | cursor++; | ||
602 | } | 574 | } |
603 | else if(*cursor == COMMENTSYM) | 575 | else if(*cursor == COMMENTSYM) |
604 | { | 576 | { |
605 | skip_comment(&cursor); | 577 | skip_comment(&cursor); |
606 | } | 578 | } |
607 | else if(*cursor == ARGLISTOPENSYM) | ||
608 | { | ||
609 | skip_arglist(&cursor); | ||
610 | } | ||
611 | else if(*cursor == ARGLISTSEPARATESYM) | 579 | else if(*cursor == ARGLISTSEPARATESYM) |
612 | { | 580 | { |
613 | num_args++; | 581 | num_args++; |
@@ -974,18 +942,9 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc | |||
974 | { | 942 | { |
975 | skip_comment(&cursor); | 943 | skip_comment(&cursor); |
976 | } | 944 | } |
977 | else if(*cursor == ENUMLISTOPENSYM) | ||
978 | { | ||
979 | if (*cursor == '\n') | ||
980 | cursor++; | ||
981 | skip_enumlist(&cursor); | ||
982 | } | ||
983 | else if(*cursor == TAGSYM) | 945 | else if(*cursor == TAGSYM) |
984 | { | 946 | { |
985 | cursor++; | 947 | skip_tag(&cursor); |
986 | if(*cursor == '\0' || *cursor == '\n') | ||
987 | break; | ||
988 | cursor++; | ||
989 | } | 948 | } |
990 | else if(*cursor == ENUMLISTSEPARATESYM) | 949 | else if(*cursor == ENUMLISTSEPARATESYM) |
991 | { | 950 | { |
@@ -1139,21 +1098,7 @@ static struct skin_element* skin_parse_code_as_arg(const char** document) | |||
1139 | } | 1098 | } |
1140 | else if(*cursor == TAGSYM) | 1099 | else if(*cursor == TAGSYM) |
1141 | { | 1100 | { |
1142 | /* A ';' directly after a '%' doesn't count */ | 1101 | skip_tag(&cursor); |
1143 | cursor ++; | ||
1144 | |||
1145 | if(*cursor == '\0') | ||
1146 | break; | ||
1147 | |||
1148 | cursor++; | ||
1149 | } | ||
1150 | else if(*cursor == ARGLISTOPENSYM) | ||
1151 | { | ||
1152 | skip_arglist(&cursor); | ||
1153 | } | ||
1154 | else if(*cursor == ENUMLISTOPENSYM) | ||
1155 | { | ||
1156 | skip_enumlist(&cursor); | ||
1157 | } | 1102 | } |
1158 | else | 1103 | else |
1159 | { | 1104 | { |
diff --git a/lib/skin_parser/skin_scan.c b/lib/skin_parser/skin_scan.c index 50d58bc250..f6424aba53 100644 --- a/lib/skin_parser/skin_scan.c +++ b/lib/skin_parser/skin_scan.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "skin_debug.h" | 28 | #include "skin_debug.h" |
29 | #include "symbols.h" | 29 | #include "symbols.h" |
30 | #include "skin_parser.h" | 30 | #include "skin_parser.h" |
31 | #include "tag_table.h" | ||
31 | 32 | ||
32 | /* Scanning Functions */ | 33 | /* Scanning Functions */ |
33 | 34 | ||
@@ -40,6 +41,54 @@ void skip_comment(const char** document) | |||
40 | (*document)++; | 41 | (*document)++; |
41 | } | 42 | } |
42 | 43 | ||
44 | void skip_tag(const char** document) | ||
45 | { | ||
46 | char tag_name[MAX_TAG_LENGTH]; | ||
47 | int i; | ||
48 | bool qmark; | ||
49 | const struct tag_info *tag; | ||
50 | const char *cursor; | ||
51 | |||
52 | if(**document == TAGSYM) | ||
53 | (*document)++; | ||
54 | qmark = (**document == CONDITIONSYM); | ||
55 | if (qmark) | ||
56 | (*document)++; | ||
57 | |||
58 | if (!qmark && find_escape_character(**document)) | ||
59 | { | ||
60 | (*document)++; | ||
61 | } | ||
62 | else | ||
63 | { | ||
64 | cursor = *document; | ||
65 | |||
66 | /* Checking the tag name */ | ||
67 | for (i=0; cursor[i] && i<MAX_TAG_LENGTH; i++) | ||
68 | tag_name[i] = cursor[i]; | ||
69 | |||
70 | /* First we check the two characters after the '%', then a single char */ | ||
71 | tag = NULL; | ||
72 | i = MAX_TAG_LENGTH; | ||
73 | while (!tag && i > 1) | ||
74 | { | ||
75 | tag_name[i-1] = '\0'; | ||
76 | tag = find_tag(tag_name); | ||
77 | i--; | ||
78 | } | ||
79 | |||
80 | if (tag) | ||
81 | { | ||
82 | *document += strlen(tag->name); | ||
83 | } | ||
84 | } | ||
85 | if (**document == ARGLISTOPENSYM) | ||
86 | skip_arglist(document); | ||
87 | |||
88 | if (**document == ENUMLISTOPENSYM) | ||
89 | skip_enumlist(document); | ||
90 | } | ||
91 | |||
43 | void skip_arglist(const char** document) | 92 | void skip_arglist(const char** document) |
44 | { | 93 | { |
45 | if(**document == ARGLISTOPENSYM) | 94 | if(**document == ARGLISTOPENSYM) |
@@ -47,16 +96,7 @@ void skip_arglist(const char** document) | |||
47 | while(**document && **document != ARGLISTCLOSESYM) | 96 | while(**document && **document != ARGLISTCLOSESYM) |
48 | { | 97 | { |
49 | if(**document == TAGSYM) | 98 | if(**document == TAGSYM) |
50 | { | 99 | skip_tag(document); |
51 | (*document)++; | ||
52 | if(**document == '\0') | ||
53 | break; | ||
54 | (*document)++; | ||
55 | } | ||
56 | else if(**document == ARGLISTOPENSYM) | ||
57 | skip_arglist(document); | ||
58 | else if(**document == ENUMLISTOPENSYM) | ||
59 | skip_enumlist(document); | ||
60 | else if(**document == COMMENTSYM) | 100 | else if(**document == COMMENTSYM) |
61 | skip_comment(document); | 101 | skip_comment(document); |
62 | else | 102 | else |
@@ -73,16 +113,7 @@ void skip_enumlist(const char** document) | |||
73 | while(**document && **document != ENUMLISTCLOSESYM) | 113 | while(**document && **document != ENUMLISTCLOSESYM) |
74 | { | 114 | { |
75 | if(**document == TAGSYM) | 115 | if(**document == TAGSYM) |
76 | { | 116 | skip_tag(document); |
77 | (*document)++; | ||
78 | if(**document == '\0') | ||
79 | break; | ||
80 | (*document)++; | ||
81 | } | ||
82 | else if(**document == ARGLISTOPENSYM) | ||
83 | skip_arglist(document); | ||
84 | else if(**document == ENUMLISTOPENSYM) | ||
85 | skip_enumlist(document); | ||
86 | else if(**document == COMMENTSYM) | 117 | else if(**document == COMMENTSYM) |
87 | skip_comment(document); | 118 | skip_comment(document); |
88 | else | 119 | 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" | |||
29 | 29 | ||
30 | 30 | ||
31 | /* Scanning functions */ | 31 | /* Scanning functions */ |
32 | void skip_tag(const char** document); | ||
32 | void skip_comment(const char** document); | 33 | void skip_comment(const char** document); |
33 | void skip_arglist(const char** document); | 34 | void skip_arglist(const char** document); |
34 | void skip_enumlist(const char** document); | 35 | void skip_enumlist(const char** document); |