summaryrefslogtreecommitdiff
path: root/apps/gui/skin_engine
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/skin_engine')
-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;