summaryrefslogtreecommitdiff
path: root/apps/gui/skin_engine/skin_parser.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2009-11-01 23:35:14 +0000
committerThomas Martitz <kugel@rockbox.org>2009-11-01 23:35:14 +0000
commite28bfd1349ca813cf34d8b327e21e128a6badba1 (patch)
treea24435818074711bf948bc218afd08174e6fbcfc /apps/gui/skin_engine/skin_parser.c
parent33040275cfccdc1f1c33e0a9ef3b5a2b88aa3679 (diff)
downloadrockbox-e28bfd1349ca813cf34d8b327e21e128a6badba1.tar.gz
rockbox-e28bfd1349ca813cf34d8b327e21e128a6badba1.zip
Rework how feature skin tags work (%cc currently) when used conditionally (i.e. to detect a feature).
If the feature is known to be unavailable at compile time or runtime detected, then let parsing skip over the true case. That enables parsing skins that properly put tags not available on a target within these tags. In the past the true case was parsed even if never could be true, which led to unexpected parsing failures. Parsing %cc<%St|time format|[..]|> is now possible on target where that setting doesn't exist (the %St parser wold fail). More of these tags are to be added, for example to indicate fm radio or recording capabilities. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23479 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui/skin_engine/skin_parser.c')
-rw-r--r--apps/gui/skin_engine/skin_parser.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index c05ebca45e..7119024c69 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -1387,6 +1387,83 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data)
1387 return skip; 1387 return skip;
1388} 1388}
1389 1389
1390
1391/*
1392 * Returns the number of bytes to skip the buf pointer to access the false
1393 * branch in a _binary_ conditional
1394 *
1395 * That is:
1396 * - before the '|' if we have a false branch, (%?<true|false> -> %?<|false>)
1397 * - or before the closing '>' if there's no false branch (%?<true> -> %?<>)
1398 *
1399 * depending on the features of a target it's not called from check_feature_tag,
1400 * hence the __attribute__ or it issues compiler warnings
1401 *
1402 **/
1403
1404static int find_false_branch(const char *wps_bufptr) __attribute__((unused));
1405static int find_false_branch(const char *wps_bufptr)
1406{
1407 const char *buf = wps_bufptr;
1408 /* wps_bufptr is after the opening '<', hence level = 1*/
1409 int level = 1;
1410 char ch;
1411 do
1412 {
1413 ch = *buf;
1414 if (ch == '%')
1415 { /* filter out the characters we check later if they're printed
1416 * as literals */
1417 ch = *(++buf);
1418 if (ch == '<' || ch == '>' || ch == '|')
1419 continue;
1420 /* else: some tags/printed literals we skip over */
1421 }
1422 else if (ch == '<') /* nested conditional */
1423 level++;
1424 else if (ch == '>')
1425 { /* closed our or a nested conditional,
1426 * do NOT skip over the '>' so that wps_parse() sees it for closing
1427 * if it is the closing one for our conditional */
1428 level--;
1429 }
1430 else if (ch == '|' && level == 1)
1431 { /* we found our separator, point before and get out */
1432 break;
1433 }
1434 /* if level is 0, we don't have a false branch */
1435 } while (level > 0 && *(++buf));
1436
1437 return buf - wps_bufptr;
1438}
1439
1440/*
1441 * returns the number of bytes to get the appropriate branch of a binary
1442 * conditional
1443 *
1444 * That means:
1445 * - if a feature is available, it returns 0 to not skip anything
1446 * - if the feature is not available, skip to the false branch and don't
1447 * parse the true branch at all
1448 *
1449 * */
1450static int check_feature_tag(const char *wps_bufptr, const int type)
1451{
1452 (void)wps_bufptr;
1453 switch (type)
1454 {
1455 case WPS_TOKEN_RTC_PRESENT:
1456#if CONFIG_RTC
1457 return 0;
1458#else
1459 return find_false_branch(wps_bufptr);
1460#endif
1461 default: /* not a tag we care about, just don't skip */
1462 return 0;
1463 }
1464}
1465
1466
1390/* Parses the WPS. 1467/* Parses the WPS.
1391 data is the pointer to the structure where the parsed WPS should be stored. 1468 data is the pointer to the structure where the parsed WPS should be stored.
1392 It is initialised. 1469 It is initialised.
@@ -1466,7 +1543,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug)
1466 fail = PARSE_FAIL_COND_SYNTAX_ERROR; 1543 fail = PARSE_FAIL_COND_SYNTAX_ERROR;
1467 break; 1544 break;
1468 } 1545 }
1469 1546 wps_bufptr += check_feature_tag(wps_bufptr,
1547 data->tokens[data->num_tokens-1].type);
1470 data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_START; 1548 data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_START;
1471 lastcond[level] = data->num_tokens++; 1549 lastcond[level] = data->num_tokens++;
1472 break; 1550 break;