Parse a format string into ExpandoNodes.
130{
131 while (*str && (end ? (str <= end) : 1))
132 {
133
134
135 if ((*str == '%') ||
136 ((condition_start ==
CON_START) && ((*str ==
'?') || (*str ==
'<'))))
137 {
138 str++;
139
140
141 if (*str == '%')
142 {
143 *parsed_until = str + 1;
145 }
146
147 else if ((*str == '?') || (*str == '<'))
148 {
149 bool old_style = (*str == '?');
150 char end_terminator = old_style ? '?' : '>';
151
153 const char *next = NULL;
156 if (!condition)
157 return NULL;
158
160 {
163
164
165 _(
"Conditional expando is missing '%c'"),
'?');
167 return NULL;
168 }
169
171
172 const char *if_true_start = str;
173
175 bool only_true = (*if_true_end == end_terminator);
176 bool invalid = ((*if_true_end != '&') && !only_true);
177
178 if (invalid)
179 {
182
183
184 _(
"Conditional expando is missing '&' or '%c'"), end_terminator);
186 return NULL;
187 }
188
189 const char *if_true_parsed = NULL;
191
192 while (if_true_start < if_true_end)
193 {
195 &if_true_parsed, defs, error);
196 if (!node)
197 {
199 return NULL;
200 }
201
203
204 if_true_start = if_true_parsed;
205 }
206
207 if ((if_true_start == if_true_end) && !if_true_tree)
208 {
210 }
211
212 if (only_true)
213 {
214 *parsed_until = if_true_end + 1;
216 }
217 else
218 {
219 const char *if_false_start = if_true_end + 1;
220
222
223 if (*if_false_end != end_terminator)
224 {
227
228
229 _(
"Conditional expando is missing '%c'"), end_terminator);
232 return NULL;
233 }
234
235 const char *if_false_parsed = NULL;
237
238 while (if_false_start < if_false_end)
239 {
241 &if_false_parsed, defs, error);
242 if (!node)
243 {
246 return NULL;
247 }
248
250
251 if_false_start = if_false_parsed;
252 }
253
254 if ((if_false_start == if_false_end) && !if_false_tree)
255 {
257 }
258
259 *parsed_until = if_false_end + 1;
261 }
262 }
263
264 else
265 {
269 {
271 }
272 else
273 {
275 }
276
278 {
280 return NULL;
281 }
282
283 return node;
284 }
285 }
286
287 else
288 {
290 }
291 }
292
293 assert(false && "Internal parsing error");
294 return NULL;
295}
#define EP_NO_FLAGS
No flags are set.
uint8_t ExpandoParserFlags
Flags for expando_parse(), e.g. EP_CONDITIONAL.
#define EP_CONDITIONAL
Expando is being used as a condition.
const char * skip_until_ch(const char *start, char terminator)
Search a string for a terminator character.
static const char * skip_until_if_true_end(const char *start, char end_terminator)
Search for the end of an 'if true' condition.
static const char * skip_until_if_false_end(const char *start, char end_terminator)
Search for the end of an 'if false' condition.
static struct ExpandoNode * node_parse(const char *str, const char *end, enum ExpandoConditionStart condition_start, const char **parsed_until, const struct ExpandoDefinition *defs, struct ExpandoParseError *error)
Parse a format string into ExpandoNodes.
struct ExpandoNode * node_condbool_parse(const char *s, const char **parsed_until, const struct ExpandoDefinition *defs, ExpandoParserFlags flags, struct ExpandoParseError *error)
Parse a CondBool format string - Implements ExpandoDefinition::parse() -.
struct ExpandoNode * node_new(void)
Create a new empty ExpandoNode.
void node_append(struct ExpandoNode **root, struct ExpandoNode *new_node)
Append an ExpandoNode to an existing node.
void node_free(struct ExpandoNode **ptr)
Free an ExpandoNode and its private data.
struct ExpandoNode * node_condition_new(struct ExpandoNode *condition, struct ExpandoNode *if_true_tree, struct ExpandoNode *if_false_tree)
Create a new Condition Expando Node.
@ CON_NO_CONDITION
Parser is not currently in a condition.
@ CON_START
Parser is working on a condition.
struct ExpandoNode * node_expando_parse(const char *str, const char **parsed_until, const struct ExpandoDefinition *defs, ExpandoParserFlags flags, struct ExpandoParseError *error)
Parse an Expando format string.
struct ExpandoNode * node_text_new(const char *start, const char *end)
Create a new Text ExpandoNode.
struct ExpandoNode * node_text_parse(const char *str, const char *end, const char **parsed_until)
Extract a block of text.
const char * end
End of string data.
struct ExpandoNode * next
Linked list.
char message[128]
Error message.
const char * position
Position of error in original string.