summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2010-08-14 11:17:49 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2010-08-14 11:17:49 +0000
commit863d239aa2d1585a13b5610d1a8619d5fb9e3554 (patch)
treea305e81d9b444408e5dc32353f254321c94e5699 /lib
parentb75a414167a4aff96a9baf0dd96e7ac2b5d689d5 (diff)
Change %xd to allow for a number to be used to specify the subimage. i.e %xd(Ac) can now we written as %xd(A, 3). subimage count start at 1 so a=1, b=2 etc.
Also adds the possibility to specify a set of params which a tag can have (i.e a tag or a integer) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27812 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'lib')
-rw-r--r--lib/skin_parser/skin_parser.c76
-rw-r--r--lib/skin_parser/tag_table.c2
-rw-r--r--lib/skin_parser/tag_table.h4
3 files changed, 72 insertions, 10 deletions
diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c
index fba074f00c..66deaab102 100644
--- a/lib/skin_parser/skin_parser.c
+++ b/lib/skin_parser/skin_parser.c
@@ -579,6 +579,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
/* Now we have to actually parse each argument */
for(i = 0; i < num_args; i++)
{
+ char type_code;
/* Making sure we haven't run out of arguments */
if(*tag_args == '\0')
{
@@ -600,14 +601,71 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
/* Checking for comments */
if(*cursor == COMMENTSYM)
skip_comment(&cursor);
-
+
+ if (*tag_args == '[')
+ {
+ /* we need to guess which type of param it is.
+ * guess using this priority:
+ * default > decimal/integer > single tag/code > string
+ */
+ int j=0;
+ bool canbedefault = false;
+ bool haspercent = false, number = true, hasdecimal = false;
+ char temp_params[8];
+ tag_args++;
+ while (*tag_args != ']')
+ {
+ if (*tag_args >= 'a' && *tag_args <= 'z')
+ canbedefault = true;
+ temp_params[j++] = tolower(*tag_args++);
+ }
+ temp_params[j] = '\0';
+ j = 0;
+ while (cursor[j] != ',' && cursor[j] != ')')
+ {
+ haspercent = haspercent || (cursor[j] == '%');
+ hasdecimal = hasdecimal || (cursor[j] == '.');
+ number = number && (isdigit(cursor[j]) || (cursor[j] == '.'));
+ j++;
+ }
+ type_code = '*';
+ if (canbedefault && *cursor == DEFAULTSYM && !isdigit(cursor[1]))
+ {
+ type_code = 'i';
+ }
+ else if (number && hasdecimal && strchr(temp_params, 'd'))
+ {
+ type_code = 'd';
+ }
+ else if (number &&
+ (strchr(temp_params, 'i') || strchr(temp_params, 'd')))
+ {
+ type_code = strchr(temp_params, 'i') ? 'i' : 'd';
+ }
+ else if (haspercent &&
+ (strchr(temp_params, 't') || strchr(temp_params, 'c')))
+ {
+ type_code = strchr(temp_params, 't') ? 't' : 'c';
+ }
+ else if (strchr(temp_params, 's'))
+ {
+ type_code = 's';
+ }
+ if (type_code == '*')
+ {
+ skin_error(INSUFFICIENT_ARGS, cursor);
+ return 0;
+ }
+ }
+ else
+ type_code = *tag_args;
/* Storing the type code */
- element->params[i].type_code = *tag_args;
+ element->params[i].type_code = type_code;
/* Checking a nullable argument for null. */
if(*cursor == DEFAULTSYM && !isdigit(cursor[1]))
{
- if(islower(*tag_args))
+ if(islower(type_code))
{
element->params[i].type = DEFAULT;
cursor++;
@@ -618,7 +676,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
return 0;
}
}
- else if(tolower(*tag_args) == 'i')
+ else if(tolower(type_code) == 'i')
{
/* Scanning an int argument */
if(!isdigit(*cursor) && *cursor != '-')
@@ -630,7 +688,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
element->params[i].type = INTEGER;
element->params[i].data.number = scan_int(&cursor);
}
- else if(tolower(*tag_args) == 'd')
+ else if(tolower(type_code) == 'd')
{
int val = 0;
bool have_point = false;
@@ -657,15 +715,15 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
element->params[i].type = DECIMAL;
element->params[i].data.number = val;
}
- else if(tolower(*tag_args) == 'n' ||
- tolower(*tag_args) == 's' || tolower(*tag_args) == 'f')
+ else if(tolower(type_code) == 'n' ||
+ tolower(type_code) == 's' || tolower(type_code) == 'f')
{
/* Scanning a string argument */
element->params[i].type = STRING;
element->params[i].data.text = scan_string(&cursor);
}
- else if(tolower(*tag_args) == 'c')
+ else if(tolower(type_code) == 'c')
{
/* Recursively parsing a code argument */
element->params[i].type = CODE;
@@ -673,7 +731,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
if(!element->params[i].data.code)
return 0;
}
- else if (tolower(*tag_args) == 't')
+ else if (tolower(type_code) == 't')
{
struct skin_element* child = skin_alloc_element();
child->type = TAG;
diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c
index dccb9f8259..4f201ec911 100644
--- a/lib/skin_parser/tag_table.c
+++ b/lib/skin_parser/tag_table.c
@@ -167,7 +167,7 @@ static const struct tag_info legal_tags[] =
{ SKIN_TOKEN_DRAW_INBUILTBAR, "wi", "", SKIN_REFRESH_STATIC|NOBREAK },
{ SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SFII|I", 0|NOBREAK },
- { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S|TI", 0 },
+ { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S|[IT]I", 0 },
{ SKIN_TOKEN_IMAGE_DISPLAY, "x", "SFII", 0|NOBREAK },
{ SKIN_TOKEN_LOAD_FONT, "Fl" , "IF", 0|NOBREAK },
diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h
index c96feccc65..4b7efaa835 100644
--- a/lib/skin_parser/tag_table.h
+++ b/lib/skin_parser/tag_table.h
@@ -291,6 +291,10 @@ enum skin_token_type {
* 2s
* will specify two strings. An asterisk (*) at the beginning of the
* string will specify that you may choose to omit all arguments
+ *
+ * You may also group param types in [] which will tell the parser to
+ * accept any *one* of those types for that param. i.e [IT] will
+ * accept either an integer or tag type. [ITs] will also accept a string or -
*
*/
struct tag_info