5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
24 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
31 #include "zonecfg_grammar.tab.h"
34 * This constant defines the number of entries added to unclaimed_tokens[]
35 * when it runs out of space.
37 #define UNCLAIMED_TOKENS_BUFFER_GROWTH 4
42 * unclaimed_tokens == NULL IFF unclaimed_tokens_size == 0
43 * unclaimed_tokens_size == 0 IFF num_unclaimed_tokens == 0
45 static char **unclaimed_tokens; /* TOKENs produced by Lex (see below) */
46 /* but not claimed by YACC reduction */
48 static unsigned int unclaimed_tokens_size; /* size of unclaimed_tokens */
49 static unsigned int num_unclaimed_tokens; /* number of unclaimed TOKENs */
51 int lex_lineno = 1; /* line number for error reporting */
52 static int state = INITIAL;
53 extern boolean_t cmd_file_mode;
54 extern boolean_t saw_error;
55 extern void yyerror(char *s);
57 static char *create_token(char *s);
67 * The three states below are for tokens, lists and complex property values.
68 * Note that simple property values are a subset of tokens.
76 <INITIAL>"#"[^\n]* { }
174 <TSTATE>net { return NET; }
176 <TSTATE>fs { return FS; }
178 <TSTATE>device { return DEVICE; }
180 <TSTATE>rctl { return RCTL; }
182 <TSTATE>attr { return ATTR; }
184 <TSTATE>admin { return ADMIN; }
186 <TSTATE>security-flags { return SECFLAGS; }
188 <TSTATE>zonename { return ZONENAME; }
189 <CSTATE>zonename { return ZONENAME; }
191 <TSTATE>dataset { return DATASET; }
193 <TSTATE>dedicated-cpu { return PSET; }
195 <TSTATE>capped-cpu { return PCAP; }
197 <TSTATE>capped-memory { return MCAP; }
199 <TSTATE>zonepath { return ZONEPATH; }
200 <CSTATE>zonepath { return ZONEPATH; }
202 <TSTATE>brand { return BRAND; }
203 <CSTATE>brand { return BRAND; }
205 <TSTATE>autoboot { return AUTOBOOT; }
206 <CSTATE>autoboot { return AUTOBOOT; }
208 <TSTATE>ip-type { return IPTYPE; }
209 <CSTATE>ip-type { return IPTYPE; }
211 <TSTATE>pool { return POOL; }
212 <CSTATE>pool { return POOL; }
214 <TSTATE>limitpriv { return LIMITPRIV; }
215 <CSTATE>limitpriv { return LIMITPRIV; }
217 <TSTATE>bootargs { return BOOTARGS; }
218 <CSTATE>bootargs { return BOOTARGS; }
220 <TSTATE>type { return TYPE; }
221 <CSTATE>type { return TYPE; }
223 <TSTATE>value { return VALUE; }
224 <CSTATE>value { return VALUE; }
226 <TSTATE>options { return OPTIONS; }
227 <CSTATE>options { return OPTIONS; }
229 <TSTATE>allowed-address { return ALLOWED_ADDRESS; }
230 <CSTATE>allowed-address { return ALLOWED_ADDRESS; }
232 <TSTATE>address { return ADDRESS; }
233 <CSTATE>address { return ADDRESS; }
235 <TSTATE>physical { return PHYSICAL; }
236 <CSTATE>physical { return PHYSICAL; }
238 <TSTATE>defrouter { return DEFROUTER; }
239 <CSTATE>defrouter { return DEFROUTER; }
241 <TSTATE>dir { return DIR; }
242 <CSTATE>dir { return DIR; }
244 <TSTATE>special { return SPECIAL; }
245 <CSTATE>special { return SPECIAL; }
247 <TSTATE>raw { return RAW; }
248 <CSTATE>raw { return RAW; }
250 <TSTATE>name { return NAME; }
251 <CSTATE>name { return NAME; }
253 <TSTATE>match { return MATCH; }
254 <CSTATE>match { return MATCH; }
256 <TSTATE>priv { return PRIV; }
257 <CSTATE>priv { return PRIV; }
259 <TSTATE>limit { return LIMIT; }
260 <CSTATE>limit { return LIMIT; }
262 <TSTATE>action { return ACTION; }
263 <CSTATE>action { return ACTION; }
265 <TSTATE>ncpus { return NCPUS; }
266 <CSTATE>ncpus { return NCPUS; }
268 <TSTATE>locked { return LOCKED; }
269 <CSTATE>locked { return LOCKED; }
271 <TSTATE>swap { return SWAP; }
272 <CSTATE>swap { return SWAP; }
274 <TSTATE>importance { return IMPORTANCE; }
275 <CSTATE>importance { return IMPORTANCE; }
277 <TSTATE>cpu-shares { return SHARES; }
278 <CSTATE>cpu-shares { return SHARES; }
280 <TSTATE>max-lwps { return MAXLWPS; }
281 <CSTATE>max-lwps { return MAXLWPS; }
283 <TSTATE>max-processes { return MAXPROCS; }
284 <CSTATE>max-processes { return MAXPROCS; }
286 <TSTATE>max-shm-memory { return MAXSHMMEM; }
287 <CSTATE>max-shm-memory { return MAXSHMMEM; }
289 <TSTATE>max-shm-ids { return MAXSHMIDS; }
290 <CSTATE>max-shm-ids { return MAXSHMIDS; }
292 <TSTATE>max-msg-ids { return MAXMSGIDS; }
293 <CSTATE>max-msg-ids { return MAXMSGIDS; }
295 <TSTATE>max-sem-ids { return MAXSEMIDS; }
296 <CSTATE>max-sem-ids { return MAXSEMIDS; }
298 <TSTATE>scheduling-class { return SCHED; }
299 <CSTATE>scheduling-class { return SCHED; }
301 <TSTATE>hostid { return HOSTID; }
302 <CSTATE>hostid { return HOSTID; }
304 <TSTATE>user { return USER; }
305 <CSTATE>user { return USER; }
307 <TSTATE>auths { return AUTHS; }
308 <CSTATE>auths { return AUTHS; }
310 <TSTATE>fs-allowed { return FS_ALLOWED; }
311 <CSTATE>fs-allowed { return FS_ALLOWED; }
313 <TSTATE>default { return DEFAULT; }
314 <CSTATE>default { return DEFAULT; }
316 <TSTATE>lower { return LOWER; }
317 <CSTATE>lower { return LOWER; }
319 <TSTATE>upper { return UPPER; }
320 <CSTATE>upper { return UPPER; }
322 <TSTATE>= { return EQUAL; }
323 <LSTATE>= { return EQUAL; }
324 <CSTATE>= { return EQUAL; }
329 return OPEN_SQ_BRACKET;
335 return CLOSE_SQ_BRACKET;
353 <LSTATE>"," { return COMMA; }
354 <CSTATE>"," { return COMMA; }
356 <TSTATE>[^ \t\n\";=\[\]\(\)]+ {
357 yylval.strval = create_token(yytext);
361 <LSTATE>[^ \t\n\",;=\[\]\(\)]+ {
362 yylval.strval = create_token(yytext);
366 <CSTATE>[^ \t\n\",;=\(\)]+ {
367 yylval.strval = create_token(yytext);
371 <TSTATE>\"[^\"\n]*[\"\n] {
372 yylval.strval = create_token(yytext + 1);
373 if (yylval.strval[yyleng - 2] == '"')
374 yylval.strval[yyleng - 2] = 0;
378 <LSTATE>\"[^\"\n]*[\"\n] {
379 yylval.strval = create_token(yytext + 1);
380 if (yylval.strval[yyleng - 2] == '"')
381 yylval.strval[yyleng - 2] = 0;
396 [ \t] ; /* Ignore whitespace */
405 * Assert that there are no unclaimed tokens. This function enforces the
406 * invariants mentioned at the top of this file.
409 assert_no_unclaimed_tokens(void)
411 assert(num_unclaimed_tokens == 0);
412 assert(unclaimed_tokens == NULL);
413 assert(unclaimed_tokens_size == 0);
417 * Claim the specified unclaimed TOKEN. YACC reduction rules that
418 * use TOKENs should invoke this function immediately before freeing the TOKENs
419 * or adding them to data structures that will be cleaned up when the YACC
420 * parser finishes or encounters errors. Reduction rules should only claim the
421 * TOKENs that they use.
423 * This function returns its argument but does not free its memory.
426 claim_token(char *token)
431 * Find the token in the list of unclaimed tokens.
433 assert(num_unclaimed_tokens > 0);
434 for (index = 0; index < num_unclaimed_tokens; index++) {
435 if (unclaimed_tokens[index] == token)
440 * Abort if we didn't find the token.
442 assert(index != num_unclaimed_tokens);
445 * Replace the token with the last unclaimed token.
447 num_unclaimed_tokens--;
448 unclaimed_tokens[index] = unclaimed_tokens[num_unclaimed_tokens];
451 * Delete the list of unclaimed tokens if it's empty.
453 if (num_unclaimed_tokens == 0) {
454 free(unclaimed_tokens);
455 unclaimed_tokens = NULL;
456 unclaimed_tokens_size = 0;
463 * Free all unclaimed TOKENs. This should only be invoked when the YACC
464 * parser encounters errors.
469 if (unclaimed_tokens != NULL) {
470 while (num_unclaimed_tokens > 0)
471 free(unclaimed_tokens[--num_unclaimed_tokens]);
472 free(unclaimed_tokens);
473 unclaimed_tokens = NULL;
474 unclaimed_tokens_size = 0;
476 assert_no_unclaimed_tokens();
480 * Create a TOKEN from the specified string. The TOKEN is merely a duplicate
481 * of the specified string. TOKENs must be claimed by the YACC reduction rules
482 * that use them; see claim_token() above.
485 create_token(char *s)
489 if ((result = strdup(s)) == NULL) {
490 yyerror("Out of memory");
495 * Add the new TOKEN to the list of unclaimed TOKENs. The list might
496 * have to be resized.
498 * Reduction rules should claim TOKENs via claim_token() (see above).
500 if (num_unclaimed_tokens == unclaimed_tokens_size) {
501 char **new_unclaimed_tokens;
503 unclaimed_tokens_size += UNCLAIMED_TOKENS_BUFFER_GROWTH;
504 new_unclaimed_tokens = (char **)realloc(unclaimed_tokens,
505 unclaimed_tokens_size * sizeof (char *));
506 if (new_unclaimed_tokens == NULL) {
507 yyerror("Out of memory");
511 unclaimed_tokens = new_unclaimed_tokens;
513 unclaimed_tokens[num_unclaimed_tokens] = result;
514 num_unclaimed_tokens++;
522 * Ensure that we won't leak unclaimed tokens.
526 /* feof(yyin) is not an error; anything else is, so we set saw_error */
527 if (yytext[0] == '\0') {
530 (void) fprintf(stderr, gettext("%s, token expected\n"),
538 (void) fprintf(stderr, gettext("%s on line %d at '%s'\n"), s,
539 lex_lineno, (yytext[0] == '\n') ? "\\n" : yytext);
541 (void) fprintf(stderr, gettext("%s at '%s'\n"), s,
542 (yytext[0] == '\n') ? "\\n" : yytext);
543 usage(B_FALSE, HELP_SUBCMDS);