1 /* SPDX-License-Identifier: GPL-3.0-only */
23 #include <sys/types.h>
29 /** Compute the minimum of \a x and \a y. */
30 #define MIN(x, y) ({ \
31 typeof(x) _min1 = (x); \
32 typeof(y) _min2 = (y); \
33 (void) (&_min1 == &_min2); \
34 _min1 < _min2 ? _min1 : _min2; })
36 /** Compute the maximum of \a x and \a y. */
37 #define MAX(x, y) ({ \
38 typeof(x) _max1 = (x); \
39 typeof(y) _max2 = (y); \
40 (void) (&_max1 == &_max2); \
41 _max1 < _max2 ? _max2 : _max1; })
43 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
47 extern int loglevel_arg_val;
48 enum loglevels {LOGLEVELS, NUM_LOGLEVELS};
49 void tf_log(int ll, const char* fmt,...);
50 #define DEBUG_LOG(f,...) tf_log(LL_DEBUG, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
51 #define INFO_LOG(f,...) tf_log(LL_INFO, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
52 #define NOTICE_LOG(f,...) tf_log(LL_NOTICE, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
53 #define WARNING_LOG(f,...) tf_log(LL_WARNING, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
54 #define ERROR_LOG(f,...) tf_log(LL_ERROR, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
55 #define CRIT_LOG(f,...) tf_log(LL_CRIT, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
56 #define EMERG_LOG(f,...) tf_log(LL_EMERG, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
58 int atoi64(const char *str, int64_t *value);
59 unsigned xvasprintf(char **result, const char *fmt, va_list ap);
60 unsigned xasprintf(char **result, const char *fmt, ...);
61 void *xrealloc(void *p, size_t size);
62 void *xmalloc(size_t size);
63 void *xcalloc(size_t size);
64 char *xstrdup(const char *str);
65 char *get_homedir(void);
66 int xregcomp(regex_t *preg, const char *regex, int cflags);
67 void mmap_file(const char *path, struct iovec *iov);
68 int fd2buf(int fd, struct iovec *result);
70 struct regfile_iter; /* opaque */
71 void regfile_iter_new(const char *dirname, struct regfile_iter **result);
72 bool regfile_iter_map(const struct regfile_iter *iter, struct iovec *result);
73 const char *regfile_iter_basename(const struct regfile_iter *iter);
74 const struct stat *regfile_iter_stat(const struct regfile_iter *iter);
75 void regfile_iter_next(struct regfile_iter *iter);
76 void regfile_iter_free(struct regfile_iter *iter);
79 struct epi_properties; /* opaque */
80 unsigned epi_len(const struct epi_properties *props);
81 bool epi_has_tag(const char *tag, const struct epi_properties *props);
82 char *epi_text(const struct epi_properties *props);
85 const char *tf_version(void);
87 /* tag expression parser (ast.c, txp.lex, txp.y) */
89 /* Opaque, only known to ast.c. Passed to the generated txp_yyparse(). */
92 int txp_init(const struct iovec *definition, struct txp_context **result,
94 bool txp_eval_ast(const struct txp_context *ctx,
95 const struct epi_properties *props);
96 void txp_free(struct txp_context *ctx);
98 /* non-public API of the tag expression parser */
101 * Since we use a reentrant lexer, all functions generated by flex(1)
102 * receive an additional argument of this type.
104 typedef void *txp_yyscan_t;
106 /* Parsed regex pattern. */
107 struct txp_re_pattern {
108 regex_t preg; /* Pre-compiled regex. */
109 unsigned flags; /* Subset of the cflags described in regex(3). */
113 * The possible values of a node in the abstract syntax tree (AST).
115 * Constant semantic values (string literals, numeric constants and regex
116 * patterns which are part of the tag expression) are determined during
117 * txp_init() while values which depend on the epigram (tags, number of lines,
118 * etc.) are determined during txp_eval_row().
120 * This union, and the txp_ast_node structure below are used extensively in
121 * txp.y. However, both need to be public because the lexer must be able to
122 * create AST nodes for the constant semantic values.
124 union txp_semantic_value {
125 bool boolval; /* Comparators, =~ and =|. */
126 char *strval; /* String literals (e.g., argument of tag()) */
127 int64_t intval; /* Constants, num_lines, etc. */
128 struct txp_re_pattern re_pattern; /* Right-hand side operand of =~. */
132 * A node is either interior or a leaf node. Interior nodes have at least one
133 * child while leaf nodes have a semantic value and no children.
135 * Examples: (a) STRING_LITERAL has a semantic value (the unescaped string
136 * literal) and no children, (b) NEG (unary minus) has no semantic value but
137 * one child (the numeric expression that is to be negated), (c) LESS_OR_EQUAL
138 * has no semantic value and two children (the two numeric expressions being
141 struct txp_ast_node {
142 /* Corresponds to a token type, for example LESS_OR_EQUAL. */
145 /* Pointers to the child nodes (interior nodes only). */
146 struct txp_ast_node **children;
147 /* Leaf nodes only. */
148 union txp_semantic_value sv;
151 * The number of children is implicitly given by the id, but we include
152 * it here to avoid having to maintain a lookup table. The AST is
153 * usually small, so we can afford to waste a byte per node.
155 uint8_t num_children;
158 /* Called from both the lexer and the parser. */
159 __attribute__ ((format (printf, 3, 4)))
160 void txp_parse_error(int line, struct txp_context *ctx, const char *fmt, ...);
162 /* Helper functions for the lexer. */
163 unsigned parse_quoted_string(const char *src, const char quote_chars[2],
165 int txp_parse_regex_pattern(const char *src, struct txp_re_pattern *result);
167 struct txp_ast_node *ast_node_new_unary(int id, struct txp_ast_node *child);
168 struct txp_ast_node *ast_node_new_binary(int id, struct txp_ast_node *left,
169 struct txp_ast_node *right);
171 struct txp_ast_node *txp_new_ast_leaf_node(int id);
175 struct linhash_item {
180 typedef int linhash_comparator(const struct linhash_item **a,
181 const struct linhash_item **b);
183 struct linhash_table;
184 struct linhash_iterator;
186 struct linhash_table *linhash_new(uint32_t order);
187 int linhash_insert(struct linhash_item *item, struct linhash_table *t,
189 struct linhash_item *linhash_lookup(const char *key,
190 const struct linhash_table *t);
191 void *linhash_remove(const char *key, struct linhash_table *t);
192 void linhash_free(struct linhash_table *t);
194 struct linhash_iterator *linhash_iterator_new(struct linhash_table *t,
195 linhash_comparator *comp, bool reverse);
196 struct linhash_item *linhash_iterator_item(const struct linhash_iterator *iter);
197 void linhash_iterator_next(struct linhash_iterator *iter);
198 void linhash_iterator_free(struct linhash_iterator *iter);
200 char *linhash_statistics(const struct linhash_table *t);
201 uint32_t linhash_num_items(const struct linhash_table *t);