Parse a format string into ExpandoNodes.
129{
130 while (*str && (end ? (str <= end) : 1))
131 {
132
133
134 if ((*str == '%') ||
135 ((condition_start ==
CON_START) && ((*str ==
'?') || (*str ==
'<'))))
136 {
137 str++;
138
139
140 if (*str == '%')
141 {
142 *parsed_until = str + 1;
144 }
145
146 else if ((*str == '?') || (*str == '<'))
147 {
148 bool old_style = (*str == '?');
149 char end_terminator = old_style ? '?' : '>';
150
152 const char *next = NULL;
155 if (!condition)
156 return NULL;
157
159 {
162
163
164 _(
"Conditional expando is missing '%c'"),
'?');
166 return NULL;
167 }
168
170
171 const char *start_true = str;
172
174 bool only_true = (*end_true == end_terminator);
175 bool invalid = ((*end_true != '&') && !only_true);
176
177 if (invalid)
178 {
181
182
183 _(
"Conditional expando is missing '&' or '%c'"), end_terminator);
185 return NULL;
186 }
187
188 const char *if_true_parsed = NULL;
190
191 while (start_true < end_true)
192 {
194 &if_true_parsed, defs, error);
195 if (!node)
196 {
198 return NULL;
199 }
200
202
203 start_true = if_true_parsed;
204 }
205
206 if ((start_true == end_true) && !node_true)
207 {
209 }
210
211 if (only_true)
212 {
213 *parsed_until = end_true + 1;
215 }
216 else
217 {
218 const char *start_false = end_true + 1;
219
221
222 if (*end_false != end_terminator)
223 {
226
227
228 _(
"Conditional expando is missing '%c'"), end_terminator);
231 return NULL;
232 }
233
234 const char *if_false_parsed = NULL;
236
237 while (start_false < end_false)
238 {
240 &if_false_parsed, defs, error);
241 if (!node)
242 {
245 return NULL;
246 }
247
249
250 start_false = if_false_parsed;
251 }
252
253 if ((start_false == end_false) && !node_false)
254 {
256 }
257
258 *parsed_until = end_false + 1;
260 }
261 }
262 else
263 {
267 {
269 }
270 else
271 {
273 }
274
276 {
278 return NULL;
279 }
280
281 return node;
282 }
283 }
284 else
285 {
287 }
288 }
289
290 ASSERT(
false &&
"Internal parsing error");
291 return NULL;
292}
#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.
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 *str, 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 *node_true, struct ExpandoNode *node_false)
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.
const char * position
Position of error in original string.
char message[256]
Error message.