summaryrefslogtreecommitdiff
path: root/lib/skin_parser
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2012-02-02 22:26:16 +1100
committerJonathan Gordon <rockbox@jdgordon.info>2012-02-07 21:41:18 +1100
commit40ecdf6811d9a717ef67ff1833a67dbb521f91be (patch)
treeddde16bbb941fb70515a6127339b0a2f176e224f /lib/skin_parser
parentf1eedb80a2efbf60cfc25182b72e3da07e0f1250 (diff)
downloadrockbox-40ecdf6811d9a717ef67ff1833a67dbb521f91be.tar.gz
rockbox-40ecdf6811d9a717ef67ff1833a67dbb521f91be.zip
skin engine: New logical 'and' and 'or' tags to evaluate multiple tags in a single conditional.
Use these tags to stop having multiple conditionals.. e.g: OLD: %?C<%?Ia<something>> NEW: %?and(%C, %Ia)<something> Change-Id: Ia3bbe4611cf808e87dcd1b1147181461fa08294a
Diffstat (limited to 'lib/skin_parser')
-rw-r--r--lib/skin_parser/skin_parser.c51
-rw-r--r--lib/skin_parser/tag_table.c8
-rw-r--r--lib/skin_parser/tag_table.h7
3 files changed, 39 insertions, 27 deletions
diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c
index 24f64fd788..a81bcded34 100644
--- a/lib/skin_parser/skin_parser.c
+++ b/lib/skin_parser/skin_parser.c
@@ -513,35 +513,31 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
513{ 513{
514 const char* cursor = *document + 1; 514 const char* cursor = *document + 1;
515 const char* bookmark; 515 const char* bookmark;
516 char *open_square_bracket = NULL;
516 517
517 char tag_name[3]; 518 char tag_name[MAX_TAG_LENGTH];
518 char* tag_args; 519 char* tag_args;
519 const struct tag_info *tag; 520 const struct tag_info *tag;
520 struct skin_tag_parameter* params = NULL; 521 struct skin_tag_parameter* params = NULL;
521 522
522 int num_args = 1; 523 int num_args = 1;
523 int i; 524 int i;
524 int star = 0; /* Flag for the all-or-none option */ 525 int qmark = 0; /* Flag for the all-or-none option */
525 526
526 int optional = 0; 527 int optional = 0;
527 528
528 /* Checking the tag name */ 529 /* Checking the tag name */
529 tag_name[0] = cursor[0]; 530 for (i=0; cursor[i] && i<MAX_TAG_LENGTH; i++)
530 tag_name[1] = cursor[1]; 531 tag_name[i] = cursor[i];
531 tag_name[2] = '\0';
532 532
533 /* First we check the two characters after the '%', then a single char */ 533 /* First we check the two characters after the '%', then a single char */
534 tag = find_tag(tag_name); 534 tag = NULL;
535 535 i = MAX_TAG_LENGTH;
536 if(!tag) 536 while (!tag && i > 1)
537 { 537 {
538 tag_name[1] = '\0'; 538 tag_name[i-1] = '\0';
539 tag = find_tag(tag_name); 539 tag = find_tag(tag_name);
540 cursor++; 540 i--;
541 }
542 else
543 {
544 cursor += 2;
545 } 541 }
546 542
547 if(!tag) 543 if(!tag)
@@ -549,6 +545,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
549 skin_error(ILLEGAL_TAG, cursor); 545 skin_error(ILLEGAL_TAG, cursor);
550 return 0; 546 return 0;
551 } 547 }
548 cursor += i;
552 549
553 /* Copying basic tag info */ 550 /* Copying basic tag info */
554 if(element->type != CONDITIONAL && element->type != VIEWPORT) 551 if(element->type != CONDITIONAL && element->type != VIEWPORT)
@@ -558,16 +555,16 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
558 element->line = skin_line; 555 element->line = skin_line;
559 556
560 /* Checking for the * flag */ 557 /* Checking for the * flag */
561 if(tag_args[0] == '*') 558 if(tag_args[0] == '?')
562 { 559 {
563 star = 1; 560 qmark = 1;
564 tag_args++; 561 tag_args++;
565 } 562 }
566 563
567 /* If this tag has no arguments, we can bail out now */ 564 /* If this tag has no arguments, we can bail out now */
568 if(strlen(tag_args) == 0 565 if(strlen(tag_args) == 0
569 || (tag_args[0] == '|' && *cursor != ARGLISTOPENSYM) 566 || (tag_args[0] == '|' && *cursor != ARGLISTOPENSYM)
570 || (star && *cursor != ARGLISTOPENSYM)) 567 || (qmark && *cursor != ARGLISTOPENSYM))
571 { 568 {
572 569
573#ifdef ROCKBOX 570#ifdef ROCKBOX
@@ -663,6 +660,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
663 bool canbedefault = false; 660 bool canbedefault = false;
664 bool haspercent = false, number = true, hasdecimal = false; 661 bool haspercent = false, number = true, hasdecimal = false;
665 char temp_params[8]; 662 char temp_params[8];
663 open_square_bracket = tag_args;
666 tag_args++; 664 tag_args++;
667 while (*tag_args != ']') 665 while (*tag_args != ']')
668 { 666 {
@@ -681,7 +679,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
681 (cursor[j] == '-')); 679 (cursor[j] == '-'));
682 j++; 680 j++;
683 } 681 }
684 type_code = '*'; 682 type_code = '?';
685 if (canbedefault && *cursor == DEFAULTSYM && !isdigit(cursor[1])) 683 if (canbedefault && *cursor == DEFAULTSYM && !isdigit(cursor[1]))
686 { 684 {
687 type_code = 'i'; 685 type_code = 'i';
@@ -704,7 +702,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
704 { 702 {
705 type_code = 's'; 703 type_code = 's';
706 } 704 }
707 if (type_code == '*') 705 if (type_code == '?')
708 { 706 {
709 skin_error(INSUFFICIENT_ARGS, cursor); 707 skin_error(INSUFFICIENT_ARGS, cursor);
710 return 0; 708 return 0;
@@ -768,8 +766,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
768 params[i].type = DECIMAL; 766 params[i].type = DECIMAL;
769 params[i].data.number = val; 767 params[i].data.number = val;
770 } 768 }
771 else if(tolower(type_code) == 'n' || 769 else if(tolower(type_code) == 's' || tolower(type_code) == 'f')
772 tolower(type_code) == 's' || tolower(type_code) == 'f')
773 { 770 {
774 /* Scanning a string argument */ 771 /* Scanning a string argument */
775 params[i].type = STRING; 772 params[i].type = STRING;
@@ -813,7 +810,17 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
813 cursor++; 810 cursor++;
814 } 811 }
815 812
816 if (*tag_args != 'N') 813 if (*(tag_args + 1) == '*')
814 {
815 if (i+1 == num_args)
816 tag_args += 2;
817 else if (open_square_bracket)
818 {
819 tag_args = open_square_bracket;
820 open_square_bracket = NULL;
821 }
822 }
823 else
817 tag_args++; 824 tag_args++;
818 825
819 /* Checking for the optional bar */ 826 /* Checking for the optional bar */
diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c
index dda5074d9a..f8fbb99c18 100644
--- a/lib/skin_parser/tag_table.c
+++ b/lib/skin_parser/tag_table.c
@@ -22,7 +22,7 @@
22#include "tag_table.h" 22#include "tag_table.h"
23 23
24#include <string.h> 24#include <string.h>
25#define BAR_PARAMS "*iiii|sN" 25#define BAR_PARAMS "?iiii|s^"
26/* The tag definition table */ 26/* The tag definition table */
27static const struct tag_info legal_tags[] = 27static const struct tag_info legal_tags[] =
28{ 28{
@@ -34,6 +34,8 @@ static const struct tag_info legal_tags[] =
34 { SKIN_TOKEN_ALIGN_LANGDIRECTION, "ax", "", 0 }, 34 { SKIN_TOKEN_ALIGN_LANGDIRECTION, "ax", "", 0 },
35 35
36 { SKIN_TOKEN_LOGICAL_IF, "if", "TS[ITS]|D", SKIN_REFRESH_DYNAMIC }, 36 { SKIN_TOKEN_LOGICAL_IF, "if", "TS[ITS]|D", SKIN_REFRESH_DYNAMIC },
37 { SKIN_TOKEN_LOGICAL_AND, "and", "T*", SKIN_REFRESH_DYNAMIC },
38 { SKIN_TOKEN_LOGICAL_OR, "or", "T*", SKIN_REFRESH_DYNAMIC },
37 39
38 { SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS, SKIN_REFRESH_DYNAMIC }, 40 { SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS, SKIN_REFRESH_DYNAMIC },
39 { SKIN_TOKEN_BATTERY_VOLTS, "bv", "", SKIN_REFRESH_DYNAMIC }, 41 { SKIN_TOKEN_BATTERY_VOLTS, "bv", "", SKIN_REFRESH_DYNAMIC },
@@ -214,10 +216,10 @@ static const struct tag_info legal_tags[] =
214 /* HACK Alert (jdgordon): The next two tags have hacks so we could 216 /* HACK Alert (jdgordon): The next two tags have hacks so we could
215 * add a S param at the front without breaking old skins. 217 * add a S param at the front without breaking old skins.
216 * [SD]D <- handled by the callback, allows SD or S or D params 218 * [SD]D <- handled by the callback, allows SD or S or D params
217 * [SI]III[SI]|SN -< SIIIIS|S or IIIIS|S 219 * [SI]III[SI]|SN <- SIIIIS|S or IIIIS|S
218 * keep in sync with parse_touchregion() and parse_lasttouch() */ 220 * keep in sync with parse_touchregion() and parse_lasttouch() */
219 { SKIN_TOKEN_LASTTOUCH, "Tl" , "|[SD]D", SKIN_REFRESH_DYNAMIC }, 221 { SKIN_TOKEN_LASTTOUCH, "Tl" , "|[SD]D", SKIN_REFRESH_DYNAMIC },
220 { SKIN_TOKEN_TOUCHREGION, "T" , "[SI]III[SI]|SN", 0|NOBREAK }, 222 { SKIN_TOKEN_TOUCHREGION, "T" , "[SI]III[SI]|S*", 0|NOBREAK },
221 223
222 { SKIN_TOKEN_HAVE_TOUCH, "Tp", "", FEATURE_TAG }, 224 { SKIN_TOKEN_HAVE_TOUCH, "Tp", "", FEATURE_TAG },
223 225
diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h
index 58c3869ea6..35316b749e 100644
--- a/lib/skin_parser/tag_table.h
+++ b/lib/skin_parser/tag_table.h
@@ -27,6 +27,7 @@ extern "C"
27{ 27{
28#endif 28#endif
29 29
30#define MAX_TAG_LENGTH 4 /* includes the \0 */
30#define MAX_TAG_PARAMS 12 31#define MAX_TAG_PARAMS 12
31 32
32#define NOBREAK 0x1 /* Flag to tell the renderer not to insert a line break */ 33#define NOBREAK 0x1 /* Flag to tell the renderer not to insert a line break */
@@ -73,6 +74,8 @@ enum skin_token_type {
73 74
74 /* Conditional */ 75 /* Conditional */
75 SKIN_TOKEN_LOGICAL_IF, 76 SKIN_TOKEN_LOGICAL_IF,
77 SKIN_TOKEN_LOGICAL_AND,
78 SKIN_TOKEN_LOGICAL_OR,
76 SKIN_TOKEN_CONDITIONAL, 79 SKIN_TOKEN_CONDITIONAL,
77 SKIN_TOKEN_CONDITIONAL_START, 80 SKIN_TOKEN_CONDITIONAL_START,
78 SKIN_TOKEN_CONDITIONAL_OPTION, 81 SKIN_TOKEN_CONDITIONAL_OPTION,
@@ -301,7 +304,7 @@ enum skin_token_type {
301 * f - Nullable file name 304 * f - Nullable file name
302 * C - Required skin code 305 * C - Required skin code
303 * T - Required single skin tag 306 * T - Required single skin tag
304 * N - any amount of strings.. must be the last param in the list 307 * * - Any amonut of the previous tag (or group if after a []
305 * \n - causes the parser to eat everything up to and including the \n 308 * \n - causes the parser to eat everything up to and including the \n
306 * MUST be the last character of the prams string 309 * MUST be the last character of the prams string
307 * Any nullable parameter may be replaced in the WPS file 310 * Any nullable parameter may be replaced in the WPS file
@@ -315,7 +318,7 @@ enum skin_token_type {
315 * To specify multiple instances of the same type, put a 318 * To specify multiple instances of the same type, put a
316 * number before the character. For instance, the string... 319 * number before the character. For instance, the string...
317 * 2s 320 * 2s
318 * will specify two strings. An asterisk (*) at the beginning of the 321 * will specify two strings. A ? at the beginning of the
319 * string will specify that you may choose to omit all arguments 322 * string will specify that you may choose to omit all arguments
320 * 323 *
321 * You may also group param types in [] which will tell the parser to 324 * You may also group param types in [] which will tell the parser to