8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / zonecfg / zonecfg_lex.l
blob8714c554990c1c7589b2f0c68bef5d4257a77fa6
1 %{
2 /*
3  * CDDL HEADER START
4  *
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.
8  *
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.
13  *
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]
19  *
20  * CDDL HEADER END
21  */
24  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
25  */
27 #include <assert.h>
28 #include <string.h>
29 #include <libintl.h>
30 #include "zonecfg.h"
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.
36  */
37 #define UNCLAIMED_TOKENS_BUFFER_GROWTH  4
40  * Invariants:
41  *
42  *      unclaimed_tokens == NULL IFF unclaimed_tokens_size == 0
43  *      unclaimed_tokens_size == 0 IFF num_unclaimed_tokens == 0
44  */
45 static char **unclaimed_tokens;         /* TOKENs produced by Lex (see below) */
46                                         /* but not claimed by YACC reduction */
47                                         /* rules */
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);
60 %a 7000
61 %p 5000
62 %e 2000
63 %n 1000
67  * The three states below are for tokens, lists and complex property values.
68  * Note that simple property values are a subset of tokens.
69  */
71 %s TSTATE
72 %s LSTATE
73 %s CSTATE
76 <INITIAL>"#"[^\n]*      { }
78 <INITIAL>add    {
79                         BEGIN TSTATE;
80                         state = TSTATE;
81                         return ADD;
82                 }
84 <INITIAL>cancel {
85                         BEGIN TSTATE;
86                         state = TSTATE;
87                         return CANCEL;
88                 }
90 <INITIAL>commit {
91                         BEGIN TSTATE;
92                         state = TSTATE;
93                         return COMMIT;
94                 }
96 <INITIAL>create {
97                         BEGIN TSTATE;
98                         state = TSTATE;
99                         return CREATE;
100                 }
102 <INITIAL>delete {
103                         BEGIN TSTATE;
104                         state = TSTATE;
105                         return DELETE;
106                 }
108 <INITIAL>end    {
109                         BEGIN TSTATE;
110                         state = TSTATE;
111                         return END;
112                 }
114 <INITIAL>exit   {
115                         BEGIN TSTATE;
116                         state = TSTATE;
117                         return EXIT;
118                 }
120 <INITIAL>export {
121                         BEGIN TSTATE;
122                         state = TSTATE;
123                         return EXPORT;
124                 }
126 <INITIAL>"?"|help {
127                         BEGIN TSTATE;
128                         state = TSTATE;
129                         return HELP;
130                 }
132 <INITIAL>info   {
133                         BEGIN TSTATE;
134                         state = TSTATE;
135                         return INFO;
136                 }
138 <INITIAL>remove {
139                         BEGIN TSTATE;
140                         state = TSTATE;
141                         return REMOVE;
142                 }
144 <INITIAL>revert {
145                         BEGIN TSTATE;
146                         state = TSTATE;
147                         return REVERT;
148                 }
150 <INITIAL>select {
151                         BEGIN TSTATE;
152                         state = TSTATE;
153                         return SELECT;
154                 }
156 <INITIAL>set {
157                         BEGIN TSTATE;
158                         state = TSTATE;
159                         return SET;
160                 }
162 <INITIAL>clear {
163                         BEGIN TSTATE;
164                         state = TSTATE;
165                         return CLEAR;
166                 }
168 <INITIAL>verify {
169                         BEGIN TSTATE;
170                         state = TSTATE;
171                         return VERIFY;
172                 }
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; }
326 <TSTATE>"["     {
327                         BEGIN LSTATE;
328                         state = LSTATE;
329                         return OPEN_SQ_BRACKET;
330                 }
332 <LSTATE>"]"     {
333                         BEGIN TSTATE;
334                         state = TSTATE;
335                         return CLOSE_SQ_BRACKET;
336                 }
338 <TSTATE>"("     {
339                         BEGIN CSTATE;
340                         return OPEN_PAREN;
341                 }
343 <LSTATE>"("     {
344                         BEGIN CSTATE;
345                         return OPEN_PAREN;
346                 }
348 <CSTATE>")"     {
349                         BEGIN state;
350                         return CLOSE_PAREN;
351                 }
353 <LSTATE>","     { return COMMA; }
354 <CSTATE>","     { return COMMA; }
356 <TSTATE>[^ \t\n\";=\[\]\(\)]+   {
357                         yylval.strval = create_token(yytext);
358                         return TOKEN;
359                 }
361 <LSTATE>[^ \t\n\",;=\[\]\(\)]+  {
362                         yylval.strval = create_token(yytext);
363                         return TOKEN;
364                 }
366 <CSTATE>[^ \t\n\",;=\(\)]+      {
367                         yylval.strval = create_token(yytext);
368                         return TOKEN;
369                 }
371 <TSTATE>\"[^\"\n]*[\"\n] {
372                         yylval.strval = create_token(yytext + 1);
373                         if (yylval.strval[yyleng - 2] == '"')
374                                 yylval.strval[yyleng - 2] = 0;
375                         return TOKEN;
376                 }
378 <LSTATE>\"[^\"\n]*[\"\n] {
379                         yylval.strval = create_token(yytext + 1);
380                         if (yylval.strval[yyleng - 2] == '"')
381                                 yylval.strval[yyleng - 2] = 0;
382                         return TOKEN;
383                 }
385 ";"             {
386                         BEGIN INITIAL;
387                         return (yytext[0]);
388                 }
390 \n              {
391                         lex_lineno++;
392                         BEGIN INITIAL;
393                         return (yytext[0]);
394                 }
396 [ \t]           ;       /* Ignore whitespace */
398 .               {
399                         return (yytext[0]);
400                 }
405  * Assert that there are no unclaimed tokens.  This function enforces the
406  * invariants mentioned at the top of this file.
407  */
408 void
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.
424  */
425 char *
426 claim_token(char *token)
428         unsigned int index;
430         /*
431          * Find the token in the list of unclaimed tokens.
432          */
433         assert(num_unclaimed_tokens > 0);
434         for (index = 0; index < num_unclaimed_tokens; index++) {
435                 if (unclaimed_tokens[index] == token)
436                         break;
437         }
439         /*
440          * Abort if we didn't find the token.
441          */
442         assert(index != num_unclaimed_tokens);
444         /*
445          * Replace the token with the last unclaimed token.
446          */
447         num_unclaimed_tokens--;
448         unclaimed_tokens[index] = unclaimed_tokens[num_unclaimed_tokens];
450         /*
451          * Delete the list of unclaimed tokens if it's empty.
452          */
453         if (num_unclaimed_tokens == 0) {
454                 free(unclaimed_tokens);
455                 unclaimed_tokens = NULL;
456                 unclaimed_tokens_size = 0;
457         }
459         return (token);
463  * Free all unclaimed TOKENs.  This should only be invoked when the YACC
464  * parser encounters errors.
465  */
466 static void
467 free_tokens(void)
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;
475         }
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.
483  */
484 char *
485 create_token(char *s)
487         char *result;
489         if ((result = strdup(s)) == NULL) {
490                 yyerror("Out of memory");
491                 exit(Z_ERR);
492         }
494         /*
495          * Add the new TOKEN to the list of unclaimed TOKENs.  The list might
496          * have to be resized.
497          *
498          * Reduction rules should claim TOKENs via claim_token() (see above).
499          */
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");
508                         free(result);
509                         exit(Z_ERR);
510                 }
511                 unclaimed_tokens = new_unclaimed_tokens;
512         }
513         unclaimed_tokens[num_unclaimed_tokens] = result;
514         num_unclaimed_tokens++;
515         return (result);
518 void
519 yyerror(char *s)
521         /*
522          * Ensure that we won't leak unclaimed tokens.
523          */
524         free_tokens();
526         /* feof(yyin) is not an error; anything else is, so we set saw_error */
527         if (yytext[0] == '\0') {
528                 if (!feof(yyin)) {
529                         saw_error = B_TRUE;
530                         (void) fprintf(stderr, gettext("%s, token expected\n"),
531                             s);
532                 }
533                 return;
534         }
536         saw_error = B_TRUE;
537         if (cmd_file_mode)
538                 (void) fprintf(stderr, gettext("%s on line %d at '%s'\n"), s,
539                     lex_lineno, (yytext[0] == '\n') ? "\\n" : yytext);
540         else
541                 (void) fprintf(stderr, gettext("%s at '%s'\n"), s,
542                     (yytext[0] == '\n') ? "\\n" : yytext);
543         usage(B_FALSE, HELP_SUBCMDS);