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