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