xref: /illumos-gate/usr/src/cmd/fm/eversholt/common/tree.h (revision 20a7641f9918de8574b8b3b47dbe35c4bfc78df1)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  *
25  * tree.h -- public definitions for tree module
26  *
27  * the parse tree is made up of struct node's.  the struct is
28  * a "variant record" with a type, the filename and line number
29  * related to the node, and then type-specific node data.
30  */
31 
32 #ifndef	_ESC_COMMON_TREE_H
33 #define	_ESC_COMMON_TREE_H
34 
35 #ifdef	__cplusplus
36 extern "C" {
37 #endif
38 
39 struct node {
40 	enum nodetype {
41 		T_NOTHING,		/* used to keep going on error cases */
42 		T_NAME,			/* identifiers, sometimes chained */
43 		T_GLOBID,		/* globals (e.g. $a) */
44 		T_EVENT,		/* class@path{expr} */
45 		T_ENGINE,		/* upset threshold engine (e.g. SERD) */
46 		T_ASRU,			/* ASRU declaration */
47 		T_FRU,			/* FRU declaration */
48 		T_TIMEVAL,		/* num w/time suffix (ns internally) */
49 		T_NUM,			/* num (ull internally) */
50 		T_QUOTE,		/* quoted string */
51 		T_FUNC,			/* func(arglist) */
52 		T_NVPAIR,		/* name=value pair in decl */
53 		T_ASSIGN,		/* assignment statement */
54 		T_CONDIF,		/* a and T_CONDELSE in (a ? b : c ) */
55 		T_CONDELSE,		/* lists b and c in (a ? b : c ) */
56 		T_NOT,			/* boolean ! operator */
57 		T_AND,			/* boolean && operator */
58 		T_OR,			/* boolean || operator */
59 		T_EQ,			/* boolean == operator */
60 		T_NE,			/* boolean != operator */
61 		T_SUB,			/* integer - operator */
62 		T_ADD,			/* integer + operator */
63 		T_MUL,			/* integer * operator */
64 		T_DIV,			/* integer / operator */
65 		T_MOD,			/* integer % operator */
66 		T_LT,			/* boolean < operator */
67 		T_LE,			/* boolean <= operator */
68 		T_GT,			/* boolean > operator */
69 		T_GE,			/* boolean >= operator */
70 		T_BITAND,		/* bitwise & operator */
71 		T_BITOR,		/* bitwise | operator */
72 		T_BITXOR,		/* bitwise ^ operator */
73 		T_BITNOT,		/* bitwise ~ operator */
74 		T_LSHIFT,		/* bitwise << operator */
75 		T_RSHIFT,		/* bitwise >> operator */
76 		T_ARROW,		/* lhs (N)->(K) rhs */
77 		T_LIST,			/* comma-separated list */
78 		T_FAULT,		/* fault declaration */
79 		T_UPSET,		/* upset declaration */
80 		T_DEFECT,		/* defect declaration */
81 		T_ERROR,		/* error declaration */
82 		T_EREPORT,		/* ereport declaration */
83 		T_SERD,			/* SERD engine declaration */
84 		T_STAT,			/* STAT engine declaration */
85 		T_PROP,			/* prop statement */
86 		T_MASK,			/* mask statement */
87 		T_CONFIG		/* config statement */
88 	} t:8;
89 
90 	/*
91 	 * regardless of the type of node, filename and line number
92 	 * information from the original .esc file is tracked here.
93 	 */
94 	int line:24;
95 	const char *file;
96 
97 	/*
98 	 * the variant part of a struct node...
99 	 */
100 	union {
101 		struct {
102 			/*
103 			 * info kept for T_NAME, used in several ways:
104 			 *
105 			 *	1 for simple variable names.
106 			 *		example: j
107 			 *
108 			 *	2 for event class names, with component
109 			 *	  names chained together via the "next"
110 			 *	  pointers.
111 			 *		example: fault.fan.broken
112 			 *
113 			 *	3 for component pathnames, with component
114 			 *	  names chained together via the "next"
115 			 *	  pointers and iterators or instance numbers
116 			 *	  attached via the "child" pointers.
117 			 *		example: sysboard[0]/cpu[n]
118 			 *
119 			 * case 3 is the most interesting.
120 			 *	- if child is set, there's an iterator
121 			 *	- if child is a T_NAME, it is x[j] or x<j> and
122 			 *	  iterator type tells you vertical or horizontal
123 			 *	- if child is a T_NUM, it is x[0] or x<0> or
124 			 *	  x0 and iterator type tells you which one
125 			 *	- if cp pointer is set, then we recently
126 			 *	  matched it to a config cache entry and one
127 			 *	  can ignore child for now because it still
128 			 *	  represents the *pattern* you're matching.
129 			 *	  cp represents what you matched.  ptree()
130 			 *	  knows that if cp is set, to print that number
131 			 *	  instead of following child.
132 			 *
133 			 * when T_NAME nodes are chained:
134 			 * the "last" pointer takes you to the end of the
135 			 * chain, but only the first component's last pointer
136 			 * is kept up to date.  it is used to determine
137 			 * where to append newly-created T_NAME nodes (see
138 			 * tree_name_append()).
139 			 */
140 			const char *s;		/* the name itself */
141 
142 			struct node *child;
143 			struct node *next;
144 			struct node *last;
145 
146 			/* opaque pointer used during config matching */
147 			struct config *cp;
148 
149 			/*
150 			 * note nametype is also declared as a three bit enum
151 			 * in itree.h, so if this ever needs expanding that
152 			 * will need changing too.
153 			 */
154 			enum nametype {
155 				N_UNSPEC,
156 				N_FAULT,
157 				N_UPSET,
158 				N_DEFECT,
159 				N_ERROR,
160 				N_EREPORT,
161 				N_SERD,
162 				N_STAT
163 			} t:3;
164 			enum itertype {
165 				IT_NONE,
166 				IT_VERTICAL,
167 				IT_HORIZONTAL,
168 				IT_ENAME
169 			} it:2;
170 			unsigned childgen:1;	/* child was auto-generated */
171 		} name;
172 
173 		struct {
174 			/*
175 			 * info kept for T_GLOBID
176 			 */
177 			const char *s;		/* the name itself */
178 		} globid;
179 
180 		/*
181 		 * info kept for T_TIMEVAL and T_NUM
182 		 *
183 		 * timevals are kept in nanoseconds.
184 		 */
185 		unsigned long long ull;
186 
187 		struct {
188 			/*
189 			 * info kept for T_QUOTE
190 			 */
191 			const char *s;		/* the quoted string */
192 		} quote;
193 
194 		struct {
195 			/*
196 			 * info kept for T_FUNC
197 			 */
198 			const char *s;		/* name of function */
199 			struct node *arglist;
200 		} func;
201 
202 		struct {
203 			/*
204 			 * info kept for T_PROP and T_MASK statements
205 			 * as well as declarations for:
206 			 *	T_FAULT
207 			 *	T_UPSET
208 			 *	T_DEFECT
209 			 *	T_ERROR
210 			 *	T_EREPORT
211 			 *	T_ASRU
212 			 *	T_FRU
213 			 *	T_CONFIG
214 			 */
215 			struct node *np;
216 			struct node *nvpairs;	/* for declarations */
217 			struct lut *lutp;	/* for declarations */
218 			struct node *next;	/* for Props & Masks lists */
219 			struct node *expr;	/* for if statements */
220 			unsigned char flags;	/* see STMT_ flags below */
221 		} stmt;			/* used for stmt */
222 
223 		struct {
224 			/*
225 			 * info kept for T_EVENT
226 			 */
227 			struct node *ename;	/* event class name */
228 			struct node *epname;	/* component path name */
229 			struct node *oldepname;	/* unwildcarded path name */
230 			struct node *ewname;	/* wildcarded portion */
231 			struct node *eexprlist;	/* constraint expression */
232 			struct node *declp;	/* event declaration */
233 		} event;
234 
235 		struct {
236 			/*
237 			 * info kept for T_ARROW
238 			 */
239 			struct node *lhs;	/* left side of arrow */
240 			struct node *rhs;	/* right side of arrow */
241 			struct node *nnp;	/* N value */
242 			struct node *knp;	/* K value */
243 			struct node *prop;	/* arrow is part of this prop */
244 			int needed;
245 			struct node *parent;
246 		} arrow;
247 
248 		struct {
249 			/*
250 			 * info kept for everything else (T_ADD, T_LIST, etc.)
251 			 */
252 			struct node *left;
253 			struct node *right;
254 			int temp;
255 		} expr;
256 	} u;
257 	/*
258 	 * Note to save memory the nodesize() function trims the end of this
259 	 * structure, so best not to add anything after this point
260 	 */
261 };
262 
263 /* flags we keep with stmts */
264 #define	STMT_REF	0x01	/* declared item is referenced */
265 #define	STMT_CYMARK	0x02	/* declared item is marked for cycle check */
266 #define	STMT_CYCLE	0x04	/* cycle detected and already reported */
267 
268 #define	TIMEVAL_EVENTUALLY (1000000000ULL*60*60*24*365*100)	/* 100 years */
269 
270 void tree_init(void);
271 void tree_fini(void);
272 struct node *newnode(enum nodetype t, const char *file, int line);
273 void tree_free(struct node *root);
274 struct node *tree_root(struct node *np);
275 struct node *tree_nothing(void);
276 struct node *tree_expr(enum nodetype t, struct node *left, struct node *right);
277 struct node *tree_event(struct node *ename, struct node *epname,
278     struct node *eexprlist);
279 struct node *tree_if(struct node *expr, struct node *stmts,
280     const char *file, int line);
281 struct node *tree_name(const char *s, enum itertype it,
282     const char *file, int line);
283 struct node *tree_iname(const char *s, const char *file, int line);
284 struct node *tree_globid(const char *s, const char *file, int line);
285 struct node *tree_name_append(struct node *np1, struct node *np2);
286 struct node *tree_name_repairdash(struct node *np1, const char *s);
287 struct node *tree_name_repairdash2(const char *s, struct node *np1);
288 struct node *tree_name_iterator(struct node *np1, struct node *np2);
289 struct node *tree_timeval(const char *s, const char *suffix,
290     const char *file, int line);
291 struct node *tree_num(const char *s, const char *file, int line);
292 struct node *tree_quote(const char *s, const char *file, int line);
293 struct node *tree_func(const char *s, struct node *np,
294     const char *file, int line);
295 struct node *tree_pname(struct node *np);
296 struct node *tree_arrow(struct node *lhs, struct node *nnp, struct node *knp,
297     struct node *rhs);
298 struct lut *tree_s2np_lut_add(struct lut *root, const char *s, struct node *np);
299 struct node *tree_s2np_lut_lookup(struct lut *root, const char *s);
300 struct lut *tree_name2np_lut_add(struct lut *root,
301     struct node *namep, struct node *np);
302 struct node *tree_name2np_lut_lookup(struct lut *root, struct node *namep);
303 struct node *tree_name2np_lut_lookup_name(struct lut *root, struct node *namep);
304 struct lut *tree_event2np_lut_add(struct lut *root,
305     struct node *enp, struct node *np);
306 struct node *tree_event2np_lut_lookup(struct lut *root, struct node *enp);
307 struct node *tree_event2np_lut_lookup_event(struct lut *root,
308     struct node *enp);
309 struct node *tree_decl(enum nodetype t, struct node *enp, struct node *nvpairs,
310     const char *file, int line);
311 struct node *tree_stmt(enum nodetype t, struct node *np,
312     const char *file, int line);
313 void tree_report();
314 int tree_namecmp(struct node *np1, struct node *np2);
315 int tree_eventcmp(struct node *np1, struct node *np2);
316 
317 extern struct lut *Faults;
318 extern struct lut *Upsets;
319 extern struct lut *Defects;
320 extern struct lut *Errors;
321 extern struct lut *Ereports;
322 extern struct lut *Ereportenames;
323 extern struct lut *Ereportenames_discard;
324 extern struct lut *SERDs;
325 extern struct lut *STATs;
326 extern struct lut *ASRUs;
327 extern struct lut *FRUs;
328 extern struct lut *Configs;
329 extern struct node *Props;
330 extern struct node *Lastprops;
331 extern struct node *Masks;
332 extern struct node *Lastmasks;
333 extern struct node *Problems;
334 extern struct node *Lastproblems;
335 
336 #ifdef	__cplusplus
337 }
338 #endif
339 
340 #endif	/* _ESC_COMMON_TREE_H */
341