initial revision
[ucgine.git] / tools / cfzy / libconfizery / cfzy_expr.h
1 /*
2  * Copyright (c) 2013, Olivier MATZ <zer0@droids-corp.org>
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifndef _CFZY_EXPR_H_
29 #define _CFZY_EXPR_H_
30
31 /**
32  * @file
33  * Confizery Expression
34  *
35  * This module provides functions to parse an expression string and
36  * convert it in a logical expression tree, that can be evaluated,
37  * according to the variables defined in the configuration tree.
38  *
39  * It is used in configuration tree file, for instance in the "if"
40  * node or the "default" attribute.
41  */
42
43 #include <sys/queue.h>
44
45 #include "cfzy_list.h"
46
47 /**
48  * Type of operand in expression tree (from low to high priority)
49  */
50 enum cfzy_expr_op {
51         OP_OR,
52         OP_AND,
53         OP_EQUAL,
54         OP_OBRACKET,
55         OP_CBRACKET,
56         OP_NOT,
57         OP_VAR,
58         OP_EOF,
59 };
60
61 /**
62  * Structure describing an expression tree
63  *
64  * An expression tree is a binary tree. Each node contains an
65  * operator, or a variable name. If it's a unary operator, only the
66  * right child is used, else both left and right children are set.
67  */
68 struct cfzy_expr {
69         TAILQ_ENTRY(expr) next;   /**< next entry in list */
70         enum cfzy_expr_op optype; /**< operator type */
71         char *varname;            /**< var name, only valid if type is OP_VAR */
72         struct cfzy_expr *left;   /**< left child */
73         struct cfzy_expr *right;  /**< right child */
74 };
75
76 /**
77  * Parse a string and convert it in an expression tree
78  *
79  * @param buf
80  *   String containing an expression
81  * @return
82  *   Expression tree, or NULL on error
83  */
84 struct cfzy_expr *cfzy_expr_parse(const char *buf);
85
86 /**
87  * Free an expression tree previously allocated with cfzy_expr_parse()
88  *
89  * @param exp
90  *   Expression to free
91  */
92 void cfzy_expr_free(struct cfzy_expr *exp);
93
94 /**
95  * Write an expression tree in a string buffer
96  *
97  * Dump the expression 'exp' as a string into the buffer 'buf' of
98  * length 'len'. The output string is always nul-terminated.
99  *
100  * @param exp
101  *   Expression tree to dump
102  * @param buf
103  *   Destination buffer
104  * @param len
105  *   Len of the destination buffer
106  * @return
107  *   Number of written bytes on success (not including '\0'), else
108  *   return -1.
109  */
110 int cfzy_expr_to_str(const struct cfzy_expr *exp, char *buf, int len);
111
112 /**
113  * Evaluate an expression tree
114  *
115  * Evaluate the given expression tree according to variables defined
116  * in conftree.
117  *
118  * @param exp
119  *   Expression tree to evaluate
120  * @param getvalue
121  *   Function used to evaluate a variable. This function should
122  *   return the value of the variable (positive), or a negative value
123  *   on error (variable invalid or not found).
124  *   This argument can be NULL, in this case only "true" and "false" are
125  *   evaluated.
126  * @param opaque_arg
127  *   Second argument given as-is to getvalue() function.
128  * @return
129  *   The value of the expression (greater or equal to 0), or -1 on
130  *   error
131  */
132 int cfzy_expr_eval(const struct cfzy_expr *exp,
133                    int (*getvalue)(const char *, void *), void *opaque_arg);
134
135 /**
136  * Dump the expression graph in a file
137  *
138  * Useful for debug purpose only. The output can be parsed with
139  * cfzy_expr_graph.py.
140  *
141  * @param filename
142  *   Name of file
143  * @param exp
144  *   Expression tree to dump
145  * @return
146  *   0 on succes, -1 on error
147  */
148 int cfzy_expr_graph_dump(const char *filename, const struct cfzy_expr *exp);
149
150 /**
151  * Return a list containing all variables on which expression depend
152  *
153  * Allocate a list head, and for each variable of the expression,
154  * allocate an element and add it in the list. Each element points to
155  * a string which is allocated and should be freed by the user. Each
156  * variable is present only once in the list.
157  *
158  * @param exp
159  *   Expression tree
160  * @return
161  *   List containing the variables (it can be empty), or NULL on error.
162  */
163 struct cfzy_list_head *cfzy_expr_get_vars(const struct cfzy_expr *exp);
164
165 #endif /* _CFZY_EXPR_H_ */