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>
This commit is contained in:
parent
e92fbb42d7
commit
e43b856ed0
3 changed files with 57 additions and 80 deletions
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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<MAX_TAG_LENGTH; i++)
|
||||
tag_name[i] = cursor[i];
|
||||
|
||||
/* First we check the two characters after the '%', then a single char */
|
||||
tag = NULL;
|
||||
i = MAX_TAG_LENGTH;
|
||||
while (!tag && 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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue