57 if ((ctr == 0) && (((*
start == end_terminator) && (prev !=
'%')) || (*
start ==
'&')))
63 if ((prev ==
'%') && (*
start ==
'<'))
68 if ((*
start ==
'>') && (prev !=
'%'))
92 if ((ctr == 0) && (*
start == end_terminator) && (prev !=
'%'))
98 if ((prev ==
'%') && (*
start ==
'<'))
103 if ((*
start ==
'>') && (prev !=
'%'))
127 const char **parsed_until,
131 while (*str && (
end ? (str <=
end) : 1))
136 ((condition_start ==
CON_START) && ((*str ==
'?') || (*str ==
'<'))))
143 *parsed_until = str + 1;
147 else if ((*str ==
'?') || (*str ==
'<'))
149 bool old_style = (*str ==
'?');
150 char end_terminator = old_style ?
'?' :
'>';
153 const char *
next = NULL;
165 _(
"Conditional expando is missing '%c'"),
'?');
172 const char *if_true_start = str;
175 bool only_true = (*if_true_end == end_terminator);
176 bool invalid = ((*if_true_end !=
'&') && !only_true);
184 _(
"Conditional expando is missing '&' or '%c'"), end_terminator);
189 const char *if_true_parsed = NULL;
192 while (if_true_start < if_true_end)
195 &if_true_parsed, defs, error);
204 if_true_start = if_true_parsed;
207 if ((if_true_start == if_true_end) && !if_true_tree)
214 *parsed_until = if_true_end + 1;
219 const char *if_false_start = if_true_end + 1;
223 if (*if_false_end != end_terminator)
229 _(
"Conditional expando is missing '%c'"), end_terminator);
235 const char *if_false_parsed = NULL;
238 while (if_false_start < if_false_end)
241 &if_false_parsed, defs, error);
251 if_false_start = if_false_parsed;
254 if ((if_false_start == if_false_end) && !if_false_tree)
259 *parsed_until = if_false_end + 1;
293 assert(
false &&
"Internal parsing error");
307 if (!
string || !*
string)
313 const char *
end = NULL;
314 const char *
start = string;
Define an Expando format string.
#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.
void node_tree_parse(struct ExpandoNode **root, const char *string, 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() -.
Convenience wrapper for the library headers.
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.
Expando Node for a Conditional Boolean.
struct ExpandoNode * node_condition_new(struct ExpandoNode *condition, struct ExpandoNode *if_true_tree, struct ExpandoNode *if_false_tree)
Create a new Condition Expando Node.
Expando Node for a Condition.
ExpandoConditionStart
Signals node_parse() if the parsing started in a conditional statement or not.
@ 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.
Expando Node for an Expando.
void node_padding_repad(struct ExpandoNode **parent)
Rearrange Padding in a tree of ExpandoNodes.
Expando Node for Padding.
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.
Definition of a format string.
const char * end
End of string data.
struct ExpandoNode * next
Linked list.
const char * start
Start of string data.
Buffer for parsing errors.
char message[128]
Error message.
const char * position
Position of error in original string.