summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2012-04-16 15:42:24 +1000
committerThomas Martitz <kugel@rockbox.org>2012-04-17 17:05:20 +0200
commite43b856ed0f2fa3cb03a1335c9dc311b572e88e2 (patch)
tree4b22c3178612058c739e4e76500433d11d51615a
parente92fbb42d7d25311cc03a69390ba758033d5134a (diff)
downloadrockbox-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.c65
-rw-r--r--lib/skin_parser/skin_scan.c71
-rw-r--r--lib/skin_parser/skin_scan.h1
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
44void 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
43void skip_arglist(const char** document) 92void 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 */
32void skip_tag(const char** document);
32void skip_comment(const char** document); 33void skip_comment(const char** document);
33void skip_arglist(const char** document); 34void skip_arglist(const char** document);
34void skip_enumlist(const char** document); 35void skip_enumlist(const char** document);