dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fm / fminject / common / inj_grammar.y
blobdcc83d88d3f4a9825634856444dac5c3f4973268
1 %{
2 /*
3 * CDDL HEADER START
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License, Version 1.0 only
7 * (the "License"). You may not use this file except in compliance
8 * with the License.
10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 * or http://www.opensolaris.org/os/licensing.
12 * See the License for the specific language governing permissions
13 * and limitations under the License.
15 * When distributing Covered Code, include this CDDL HEADER in each
16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 * If applicable, add the following below this CDDL HEADER, with the
18 * fields enclosed by brackets "[]" replaced with your own identifying
19 * information: Portions Copyright [yyyy] [name of copyright owner]
21 * CDDL HEADER END
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * FMA Event Injector language parser
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <limits.h>
37 #include <inj.h>
38 #include <inj_err.h>
39 #include <inj_event.h>
40 #include <inj_hash.h>
41 #include <inj_lex.h>
45 %union {
46 inj_decl_t *l_decl;
47 inj_declmem_t *l_declmem;
48 inj_defn_t *l_defn;
49 inj_defnmem_t *l_defnmem;
50 inj_cmd_t *l_command;
51 inj_randelem_t *l_randelem;
53 inj_hash_t *l_hash;
55 char *l_string;
56 uint_t l_number;
57 hrtime_t l_hrtime;
60 %type <l_decl> decl_memlist
61 %type <l_declmem> decl_mem
62 %type <l_declmem> decl_baremem
63 %type <l_declmem> decl_mem_intr
64 %type <l_number> decl_intr_type
65 %type <l_number> decl_arraydim
66 %type <l_declmem> decl_mem_cplx
67 %type <l_hash> decl_enumlist
69 %type <l_defn> defn_memlist
70 %type <l_defnmem> defn_memvals
71 %type <l_defnmem> defn_val
73 %type <l_command> command
74 %type <l_command> cmd_repeatable
75 %type <l_randelem> rand_problist
76 %type <l_randelem> rand_element
78 %type <l_defn> defined_event
79 %type <l_number> number
80 %type <l_hrtime> hrtime
82 %token INJ_TOK_EVDEF
83 %token INJ_TOK_FMRIDEF
84 %token INJ_TOK_AUTHDEF
85 %token INJ_TOK_LISTDEF
87 %token INJ_TOK_INT8
88 %token INJ_TOK_INT16
89 %token INJ_TOK_INT32
90 %token INJ_TOK_INT64
91 %token INJ_TOK_UINT8
92 %token INJ_TOK_UINT16
93 %token INJ_TOK_UINT32
94 %token INJ_TOK_UINT64
95 %token INJ_TOK_BOOLEAN
96 %token INJ_TOK_STRING
97 %token INJ_TOK_ENUM
99 %token INJ_TOK_EVENT
100 %token INJ_TOK_FMRI
101 %token INJ_TOK_AUTH
102 %token INJ_TOK_LIST
104 %token INJ_TOK_ADDHRT
105 %token INJ_TOK_ENDHRT
106 %token INJ_TOK_SLEEP
107 %token INJ_TOK_REPEAT
108 %token INJ_TOK_RANDOMIZE
110 %token <l_string> INJ_TOK_IDENT
111 %token <l_string> INJ_TOK_FMACLASS
112 %token <l_string> INJ_TOK_IMM
113 %token <l_string> INJ_TOK_QSTRING
117 statement_list: /* EMPTY */
118 | statement_list statement ';'
121 statement: decl
122 | defn
123 | command {
124 if ($1 != NULL)
125 inj_cmds_add($1);
130 * Event, FMRI, Authority, and list declarations
133 decl: INJ_TOK_EVDEF INJ_TOK_FMACLASS '{' decl_memlist '}' {
134 if ($4 != NULL)
135 inj_decl_finish($4, $2, ITEMTYPE_EVENT);
137 | INJ_TOK_FMRIDEF INJ_TOK_IDENT '{' decl_memlist '}' {
138 if ($4 != NULL)
139 inj_decl_finish($4, $2, ITEMTYPE_FMRI);
141 | INJ_TOK_AUTHDEF INJ_TOK_IDENT '{' decl_memlist '}' {
142 if ($4 != NULL)
143 inj_decl_finish($4, $2, ITEMTYPE_AUTH);
145 | INJ_TOK_LISTDEF INJ_TOK_IDENT '{' decl_memlist '}' {
146 if ($4 != NULL)
147 inj_decl_finish($4, $2, ITEMTYPE_LIST);
151 decl_memlist: /* EMPTY */ { $$ = NULL; }
152 | decl_memlist decl_mem ';' {
153 if ($2 == NULL) {
154 $$ = $1;
155 } else if ($1 == NULL) {
156 $$ = inj_decl_create($2);
157 } else {
158 inj_decl_addmem($1, $2);
159 $$ = $1;
164 decl_mem: decl_baremem
165 | decl_baremem decl_arraydim {
166 if ($1 != NULL)
167 inj_decl_mem_make_array($1, $2);
168 $$ = $1;
172 decl_baremem: decl_mem_intr
173 | decl_mem_cplx
176 decl_mem_intr: decl_intr_type INJ_TOK_IDENT {
177 $$ = inj_decl_mem_create($2, $1);
181 decl_intr_type: INJ_TOK_INT8 { $$ = MEMTYPE_INT8; }
182 | INJ_TOK_INT16 { $$ = MEMTYPE_INT16; }
183 | INJ_TOK_INT32 { $$ = MEMTYPE_INT32; }
184 | INJ_TOK_INT64 { $$ = MEMTYPE_INT64; }
185 | INJ_TOK_UINT8 { $$ = MEMTYPE_UINT8; }
186 | INJ_TOK_UINT16 { $$ = MEMTYPE_UINT16; }
187 | INJ_TOK_UINT32 { $$ = MEMTYPE_UINT32; }
188 | INJ_TOK_UINT64 { $$ = MEMTYPE_UINT64; }
189 | INJ_TOK_BOOLEAN { $$ = MEMTYPE_BOOL; }
190 | INJ_TOK_STRING { $$ = MEMTYPE_STRING; }
193 decl_arraydim: '[' number ']' {
194 $$ = $2;
196 | '[' ']' {
197 $$ = 0;
201 decl_mem_cplx: INJ_TOK_ENUM INJ_TOK_IDENT '{' decl_enumlist '}' {
202 $$ = inj_decl_mem_create_enum($2, $4);
204 | INJ_TOK_EVENT INJ_TOK_FMACLASS INJ_TOK_IDENT {
205 $$ = inj_decl_mem_create_defined($3, $2,
206 ITEMTYPE_EVENT);
208 | INJ_TOK_FMRI INJ_TOK_IDENT INJ_TOK_IDENT {
209 $$ = inj_decl_mem_create_defined($3, $2,
210 ITEMTYPE_FMRI);
212 | INJ_TOK_AUTH INJ_TOK_IDENT INJ_TOK_IDENT {
213 $$ = inj_decl_mem_create_defined($3, $2,
214 ITEMTYPE_AUTH);
216 | INJ_TOK_LIST INJ_TOK_IDENT INJ_TOK_IDENT {
217 $$ = inj_decl_mem_create_defined($3, $2,
218 ITEMTYPE_LIST);
222 decl_enumlist: INJ_TOK_IDENT {
223 $$ = inj_zalloc(sizeof (inj_hash_t));
224 inj_strhash_create($$);
226 inj_strhash_insert($$, $1, 1);
228 | decl_enumlist ',' INJ_TOK_IDENT {
229 if (inj_strhash_lookup($1, $3) != NULL)
230 yyerror("duplicate enum value \"%s\"", $3);
231 else
232 inj_strhash_insert($1, $3, 1);
233 $$ = $1;
238 * Event, FMRI, Authority, and list definitions
241 defn: INJ_TOK_EVENT INJ_TOK_FMACLASS INJ_TOK_IDENT '='
242 '{' defn_memlist '}' {
243 inj_defn_finish($6, $2, $3, ITEMTYPE_EVENT);
244 inj_strfree($2);
246 | INJ_TOK_FMRI INJ_TOK_IDENT INJ_TOK_IDENT '='
247 '{' defn_memlist '}' {
248 inj_defn_finish($6, $2, $3, ITEMTYPE_FMRI);
249 inj_strfree($2);
251 | INJ_TOK_AUTH INJ_TOK_IDENT INJ_TOK_IDENT '='
252 '{' defn_memlist '}' {
253 inj_defn_finish($6, $2, $3, ITEMTYPE_AUTH);
254 inj_strfree($2);
258 defn_memlist: defn_memvals {
259 $$ = inj_defn_create($1);
261 | defn_memlist ',' defn_memvals {
262 inj_defn_addmem($1, $3);
263 $$ = $1;
267 defn_memvals: defn_val
268 | INJ_TOK_EVENT INJ_TOK_FMACLASS {
269 $$ = inj_defn_mem_create($2, DEFNMEM_EVENT);
271 | INJ_TOK_FMRI INJ_TOK_IDENT {
272 $$ = inj_defn_mem_create($2, DEFNMEM_FMRI);
274 | INJ_TOK_AUTH INJ_TOK_IDENT {
275 $$ = inj_defn_mem_create($2, DEFNMEM_AUTH);
277 | '[' defn_memlist ']' {
278 $$ = inj_defn_mem_create_list($2, DEFNMEM_ARRAY);
280 | '{' defn_memlist '}' {
281 $$ = inj_defn_mem_create_list($2, DEFNMEM_LIST);
285 defn_val: INJ_TOK_IMM {
286 $$ = inj_defn_mem_create($1, DEFNMEM_IMM);
288 | INJ_TOK_IDENT {
289 $$ = inj_defn_mem_create($1, DEFNMEM_IDENT);
291 | INJ_TOK_QSTRING {
292 $$ = inj_defn_mem_create($1, DEFNMEM_QSTRING);
297 * Commands
300 command: cmd_repeatable
301 | INJ_TOK_ADDHRT hrtime { $$ = inj_cmd_addhrt($2); }
302 | INJ_TOK_ENDHRT { $$ = inj_cmd_endhrt(); }
303 | INJ_TOK_SLEEP number { $$ = inj_cmd_sleep($2); }
304 | INJ_TOK_REPEAT number cmd_repeatable {
305 $$ = ($3 == NULL ? NULL : inj_cmd_repeat($3, $2));
309 cmd_repeatable: defined_event {
310 $$ = ($1 == NULL ? NULL : inj_cmd_send($1));
312 | INJ_TOK_RANDOMIZE '{' rand_problist '}' {
313 $$ = ($3 == NULL ? NULL : inj_cmd_rand($3));
317 rand_problist: rand_element
318 | rand_problist ',' rand_element {
319 $$ = ($1 == NULL || $3 == NULL) ?
320 NULL : inj_rand_add($1, $3);
324 rand_element: '{' defined_event ',' number '}' {
325 $$ = ($2 == NULL ? NULL : inj_rand_create($2, $4));
329 defined_event: INJ_TOK_IDENT {
330 inj_defn_t *ev;
332 if ((ev = inj_defn_lookup($1, MEMTYPE_EVENT)) ==
333 NULL) {
334 yyerror("unknown event \"%s\"\n", $1);
335 $$ = NULL;
336 } else
337 $$ = ev;
340 number: INJ_TOK_IMM {
341 u_longlong_t val;
343 if (inj_strtoull($1, 32, &val) < 0) {
344 yyerror("invalid number");
345 $$ = 0;
346 } else
347 $$ = (uint32_t)val;
350 hrtime: INJ_TOK_IMM INJ_TOK_IDENT {
351 longlong_t val;
353 if (inj_strtoll($1, 64, &val) < 0 ||
354 inj_strtime(&val, $2) < 0) {
355 yyerror("invalid time");
356 $$ = 0;
357 } else
358 $$ = val;
363 inj_list_t *
364 inj_program_read(const char *file)
366 if (strcmp(file, "-") == 0) {
367 yyin = stdin;
368 yyinname = "stdin";
369 } else {
370 if ((yyin = fopen(file, "r")) == NULL)
371 die("failed to open %s", file);
373 yyinname = strrchr(file, '/');
374 if (yyinname != NULL)
375 yyinname++;
376 else
377 yyinname = file;
380 yyreset();
381 (void) yyparse();
383 if (yyin != stdin)
384 (void) fclose(yyin);
386 if (yynerrors != 0) {
387 die("parsing failed - %d error%s\n", yynerrors,
388 (yynerrors > 1 ? "s" : ""));
391 return (inj_cmds_get());