7 #include "strictmalloc.h"
8 #include "expression.h"
9 #include "conf_parser.h"
11 #include "conf_htable.h"
13 /* XXX prefix all with "expression_" */
15 struct expr_node *node_create(void)
18 n = strictmalloc(sizeof(struct expr_node));
22 /* free an expression */
23 void expression_free(struct expr_node *exp)
29 expression_free(exp->left);
34 expression_free(exp->right);
41 const char *op_print(const struct expr_op *op)
63 void __dump(struct expr_node *n)
69 printf("\"%p <%s>\" -> \"%p <%s>\"\n",
71 n->left, op_print(&n->left->op));
76 printf("\"%p <%s>\" -> \"%p <%s>\"\n",
78 n->right, op_print(&n->right->op));
83 void dump(struct expr_node *n)
85 printf("digraph unix {\n"
87 "node [color=lightblue2, style=filled];\n");
92 int isbiop(enum op_type optype)
94 if (optype == OP_AND ||
102 * Dump the expression 'node' as a string into the buffer 'buf' of
103 * length 'len'. The string is nul-terminated. Return the number of
104 * written bytes on success (not including \0), else return -1.
106 int expression_to_str(struct expr_node *node, char *buf, int len)
112 if (isbiop(node->op.optype) || node->op.optype == OP_OBRACKET) {
113 n = snprintf(buf, len, "(");
114 if (n == -1 || n >= len || len <= 0)
120 if (isbiop(node->op.optype)) {
121 n = expression_to_str(node->left, buf, len);
122 if (n == -1 || n >= len || len <= 0)
128 if (node->op.optype != OP_OBRACKET) {
129 if (isbiop(node->op.optype))
130 n = snprintf(buf, len, " %s ", op_print(&node->op));
132 n = snprintf(buf, len, "%s", op_print(&node->op));
133 if (n == -1 || n >= len || len <= 0)
139 if (node->op.optype != OP_VAR) {
140 n = expression_to_str(node->right, buf, len);
141 if (n == -1 || n >= len || len <= 0)
147 if (isbiop(node->op.optype) || node->op.optype == OP_OBRACKET) {
148 n = snprintf(buf, len, ")");
149 if (n == -1 || n >= len || len <= 0)
155 return orig_len - len;
159 * Evaluate an expression. Return -1 on error, else the value of the
160 * expression (greater or equal than 0).
162 int expression_eval(struct expr_node *node)
164 struct confnode *conf;
166 switch (node->op.optype) {
168 return expression_eval(node->left) || expression_eval(node->right);
170 return expression_eval(node->left) && expression_eval(node->right);
172 return expression_eval(node->left) == expression_eval(node->right);
174 return expression_eval(node->right);
176 return !expression_eval(node->right);
178 conf = conf_htable_lookup(node->op.name);
181 return confnode_get_boolvalue(conf);
183 printf("%s(): bad operator\n", __FUNCTION__);
188 int get_brac_len(const char *buf)
197 while(*s != '\0' && i != 0) {
212 static struct expr_op *get_operand(const char *buf, unsigned *eatlen)
218 //printf("%s\n", buf);
219 op = strictmalloc(sizeof(struct expr_op));
226 *eatlen = s - buf + 1;
230 *eatlen = s - buf + 1;
233 op->optype = OP_OBRACKET;
234 *eatlen = s - buf + 1;
237 op->optype = OP_CBRACKET;
238 *eatlen = s - buf + 1;
242 *eatlen = s - buf + 1;
250 *eatlen = s - buf + 2;
258 *eatlen = s - buf + 2;
261 op->optype = OP_EQUAL;
262 *eatlen = s - buf + 1;
268 /* It's a variable, get name */
283 /* alloc string for variable name */
285 op->name = strictmalloc(len+1);
286 memcpy(op->name, buf, len);
287 op->name[len+1] = '\0';
291 struct expr_node *parse_expression(char *buf)
293 struct expr_node *top = NULL, *n, *tmp;
299 //printf("parse <%s>\n", buf);
310 op = get_operand(s, &eatlen);
312 printf("Parse error\n");
313 return NULL; /* XXX */
315 if (op->optype == OP_EOF)
318 //printf("%s\n", op_print(op));
324 switch (n->op.optype) {
329 (!isbiop(top->op.optype) ||
330 top->op.optype > n->op.optype)) {
341 len = get_brac_len(s);
343 printf("Parse error, cannot find closing bracket\n");
344 return NULL; /* XXX */
347 n->right = parse_expression(s+1);
348 if (n->right == NULL)
375 printf("Parse error\n");
376 return NULL; /* XXX */
388 char s[] = "!(A&&! (B || CONFIG_C ) )";
391 n = parse_expression(s);
393 //printf("--------------\n");
395 return 0; /* XXX free ! */