1 /* SPDX-License-Identifier: GPL-2.0 */
18 /* Opaque, only known to ast.c. Passed to the generated txp_yyparse(). */
22 * Since we use a reentrant lexer, all functions generated by flex(1)
23 * receive an additional argument of this type.
25 typedef void *txp_yyscan_t;
27 /* Parsed regex pattern. */
28 struct txp_re_pattern {
29 regex_t preg; /* Pre-compiled regex. */
30 unsigned flags; /* Subset of the cflags described in regex(3). */
34 * The possible values of a node in the abstract syntax tree (AST).
36 * Constant semantic values (string literals, numeric constants and regex
37 * patterns which are part of the tag expression) are determined during
38 * txp_init() while values which depend on the epigram (tags, number of lines,
39 * etc.) are determined during txp_eval_row().
41 * This union, and the txp_ast_node structure below are used extensively in
42 * txp.y. However, both need to be public because the lexer must be able to
43 * create AST nodes for the constant semantic values.
45 union txp_semantic_value {
46 bool boolval; /* Comparators, =~ and =|. */
47 char *strval; /* String literals, tags, path. */
48 int64_t intval; /* Constants, bitrate, frequency, etc. */
49 struct txp_re_pattern re_pattern; /*< Right-hand side operand of =~. */
53 * A node is either interior or a leaf node. Interior nodes have at least one
54 * child while leaf nodes have a semantic value and no children.
56 * Examples: (a) STRING_LITERAL has a semantic value (the unescaped string
57 * literal) and no children, (b) NEG (unary minus) has no semantic value but
58 * one child (the numeric expression that is to be negated), (c) LESS_OR_EQUAL
59 * has no semantic value and two children (the two numeric expressions being
63 /* Corresponds to a token type, for example LESS_OR_EQUAL. */
66 /* Pointers to the child nodes (interior nodes only). */
67 struct txp_ast_node **children;
68 /* Leaf nodes only. */
69 union txp_semantic_value sv;
72 * The number of children is implicitly given by the id, but we include
73 * it here to avoid having to maintain a lookup table. The AST is
74 * usually small, so we can afford to waste a byte per node.
79 enum loglevels {LOGLEVELS, NUM_LOGLEVELS};
80 #define DEBUG_LOG(f,...) txp_log(LL_DEBUG, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
81 #define INFO_LOG(f,...) txp_log(LL_INFO, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
82 #define NOTICE_LOG(f,...) txp_log(LL_NOTICE, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
83 #define WARNING_LOG(f,...) txp_log(LL_WARNING, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
84 #define ERROR_LOG(f,...) txp_log(LL_ERROR, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
85 #define CRIT_LOG(f,...) txp_log(LL_CRIT, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
86 #define EMERG_LOG(f,...) txp_log(LL_EMERG, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
90 void txp_log(int ll, const char* fmt,...);
92 /* Called from both the lexer and the parser. */
93 __attribute__ ((format (printf, 3, 4)))
94 void txp_parse_error(int line, struct txp_context *ctx, const char *fmt, ...);
96 /* Helper functions for the lexer. */
97 unsigned parse_quoted_string(const char *src, const char quote_chars[2],
99 int txp_parse_regex_pattern(const char *src, struct txp_re_pattern *result);
102 struct txp_ast_node *ast_node_new_unary(int id, struct txp_ast_node *child);
103 struct txp_ast_node *ast_node_new_binary(int id, struct txp_ast_node *left,
104 struct txp_ast_node *right);
107 * Allocate a new leaf node for the abstract syntax tree.
109 * This returns a pointer to a node whose ->num_children field is initialized
110 * to zero. The ->id field is initialized with the given id. The caller is
111 * expected to initialize the ->sv field.
113 struct txp_ast_node *txp_new_ast_leaf_node(int id);
116 * Evaluate an abstract syntax tree, starting at the root node.
118 * The root node argument should be the pointer that was returned from an
119 * earlier call to txp_init() via the context pointer. The context contains the
120 * information about the epigram.
122 * Returns true if the AST evaluates to true, a non-empty string, or a non-zero
123 * number, false otherwise.
125 bool txp_eval_ast(struct txp_ast_node *root, struct txp_context *ctx);
128 * Deallocate an abstract syntax tree.
130 * This frees the memory occupied by the nodes of the AST, the child pointers
131 * of the internal nodes and the (constant) semantic values of the leaf nodes
132 * (string literals and pre-compiled regular expressions).
134 void txp_free_ast(struct txp_ast_node *root);
138 int atoi64(const char *str, int64_t *value);
139 unsigned xvasprintf(char **result, const char *fmt, va_list ap);
140 unsigned xasprintf(char **result, const char *fmt, ...);
141 void *xmalloc(size_t size);
142 void *xcalloc(size_t size);
143 int xregcomp(regex_t *preg, const char *regex, int cflags);