1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index c05ebca..ef348c6 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -1387,6 +1387,73 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data)
     return skip;
 }

+
+/*
+ * Returns the number of bytes to skip the buf pointer to access the false branch
+ * if a _binary_ conditional
+ *
+ * That is, after the | if we have a false branch,
+ * or before the closing '>' if there's no such branch
+ *
+ * depending on the features of a target it's not called from check_feature_tag,
+ * hence the __attribute__ or it issues compiler warnings
+ *
+ **/
+
+static int find_false_branch(const char *wps_bufptr) __attribute__((unused));
+static int find_false_branch(const char *wps_bufptr)
+{
+    const char *buf = wps_bufptr;
+    int level = 1;
+    do
+    {
+        if (*buf == '<' && *(buf-1) != '%') /* nested conditional */
+            level++;
+        if (*buf == '>' && *(buf-1) != '%')
+        {
+             /* closed our or a nested conditional,
+              * do NOT skip over the '<' so that wps_parse() sees it for closing
+              * if it is the closing one for our conditional */
+            level--;
+        }
+        if (*buf == '|' && level == 1 && *(buf-1) != '%')
+        {   /* we found our separator, point behind and get out */
+            buf++;
+            break;
+        }
+    /* if level is 0, we don't have a false branch */
+    } while (level > 0 && buf && *buf++);
+
+    return buf - wps_bufptr;
+}
+
+/*
+ * returns the number of bytes to get the appropriate branch of a binary
+ * conditional
+ *
+ * That means: if a feature is available, it returns 0 to not skip anything
+ * if the feature is not available, skip to the false branch and don't
+ * parse the true branch at all
+ *
+ * NOTE: This will turn the false branch into a true branch. get_token_value
+ * must not return NULL for these tags if the feature is not available */
+static int check_feature_tag(const char *wps_bufptr, const int type)
+{
+    (void)wps_bufptr;
+    switch (type)
+    {
+        case WPS_TOKEN_RTC_PRESENT:
+#if CONFIG_RTC && 0
+            return 0;
+#else
+            return find_false_branch(wps_bufptr);
+#endif
+        default: /* not a tag we care about, just don't skip */
+            return 0;
+    }
+}
+
+
 /* Parses the WPS.
    data is the pointer to the structure where the parsed WPS should be stored.
         It is initialised.
@@ -1466,7 +1533,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug)
                     fail = PARSE_FAIL_COND_SYNTAX_ERROR;
                     break;
                 }
-
+                wps_bufptr += check_feature_tag(wps_bufptr,
+                                    data->tokens[data->num_tokens-1].type);
                 data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_START;
                 lastcond[level] = data->num_tokens++;
                 break;
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 46adbdc..e8123ab 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -565,9 +565,12 @@ const char *get_token_value(struct gui_wps *gwps,

         case WPS_TOKEN_RTC_PRESENT:
 #if CONFIG_RTC
-                return "c";
+                return radio_hardware_present() ? "yes":NULL;
 #else
-                return NULL;
+                /* return "no" instead of NULL so that the false branch
+                 * is evaluated, which we turned into a single true branch
+                 * since the true branch is skipped on parsing */ 
+                return "no";
 #endif

 #if CONFIG_RTC