Print this page
    
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/zonecfg/zonecfg_lex.l
          +++ new/usr/src/cmd/zonecfg/zonecfg_lex.l
   1    1  %{
   2    2  /*
   3    3   * CDDL HEADER START
   4    4   *
   5    5   * The contents of this file are subject to the terms of the
   6    6   * Common Development and Distribution License (the "License").
   7    7   * You may not use this file except in compliance with the License.
   8    8   *
   9    9   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10   10   * or http://www.opensolaris.org/os/licensing.
  11   11   * See the License for the specific language governing permissions
  12   12   * and limitations under the License.
  13   13   *
  14   14   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
  15   15   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   16   * If applicable, add the following below this CDDL HEADER, with the
  17   17   * fields enclosed by brackets "[]" replaced with your own identifying
  18   18   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   19   *
  20   20   * CDDL HEADER END
  21   21   */
  22   22  
  23   23  /*
  24   24   * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  25      - * Copyright (c) 2011, Joyent Inc. All rights reserved.
  26   25   */
  27   26  
  28   27  #include <assert.h>
  29   28  #include <string.h>
  30   29  #include <libintl.h>
  31   30  #include "zonecfg.h"
  32   31  #include "zonecfg_grammar.tab.h"
  33   32  
  34   33  /*
  35   34   * This constant defines the number of entries added to unclaimed_tokens[]
  36   35   * when it runs out of space.
  37   36   */
  38   37  #define UNCLAIMED_TOKENS_BUFFER_GROWTH  4
  39   38  
  40   39  /*
  41   40   * Invariants:
  42   41   *
  43   42   *      unclaimed_tokens == NULL IFF unclaimed_tokens_size == 0
  44   43   *      unclaimed_tokens_size == 0 IFF num_unclaimed_tokens == 0
  45   44   */
  46   45  static char **unclaimed_tokens;         /* TOKENs produced by Lex (see below) */
  47   46                                          /* but not claimed by YACC reduction */
  48   47                                          /* rules */
  49   48  static unsigned int unclaimed_tokens_size;      /* size of unclaimed_tokens */
  50   49  static unsigned int num_unclaimed_tokens;       /* number of unclaimed TOKENs */
  51   50  
  52   51  int lex_lineno = 1;     /* line number for error reporting */
  53   52  static int state = INITIAL;
  54   53  extern boolean_t cmd_file_mode;
  55   54  extern boolean_t saw_error;
  56   55  extern void yyerror(char *s);
  57   56  
  58   57  static char *create_token(char *s);
  59   58  %}
  60   59  
  61   60  %a 8000
  62   61  %p 5000
  63   62  %e 2000
  64   63  %n 1000
  65   64  %o 13000
  66   65  
  67   66  %{
  68   67  /*
  69   68   * The three states below are for tokens, lists and complex property values.
  70   69   * Note that simple property values are a subset of tokens.
  71   70   */
  72   71  %}
  73   72  %s TSTATE
  74   73  %s LSTATE
  75   74  %s CSTATE
  76   75  %%
  77   76  
  78   77  <INITIAL>"#"[^\n]*      { }
  79   78  
  80   79  <INITIAL>add    {
  81   80                          BEGIN TSTATE;
  82   81                          state = TSTATE;
  83   82                          return ADD;
  84   83                  }
  85   84  
  86   85  <INITIAL>cancel {
  87   86                          BEGIN TSTATE;
  88   87                          state = TSTATE;
  89   88                          return CANCEL;
  90   89                  }
  91   90  
  92   91  <INITIAL>commit {
  93   92                          BEGIN TSTATE;
  94   93                          state = TSTATE;
  95   94                          return COMMIT;
  96   95                  }
  97   96  
  98   97  <INITIAL>create {
  99   98                          BEGIN TSTATE;
 100   99                          state = TSTATE;
 101  100                          return CREATE;
 102  101                  }
 103  102  
 104  103  <INITIAL>delete {
 105  104                          BEGIN TSTATE;
 106  105                          state = TSTATE;
 107  106                          return DELETE;
 108  107                  }
 109  108  
 110  109  <INITIAL>end    {
 111  110                          BEGIN TSTATE;
 112  111                          state = TSTATE;
 113  112                          return END;
 114  113                  }
 115  114  
 116  115  <INITIAL>exit   {
 117  116                          BEGIN TSTATE;
 118  117                          state = TSTATE;
 119  118                          return EXIT;
 120  119                  }
 121  120  
 122  121  <INITIAL>export {
 123  122                          BEGIN TSTATE;
 124  123                          state = TSTATE;
 125  124                          return EXPORT;
 126  125                  }
 127  126  
 128  127  <INITIAL>"?"|help {
 129  128                          BEGIN TSTATE;
 130  129                          state = TSTATE;
 131  130                          return HELP;
 132  131                  }
 133  132  
 134  133  <INITIAL>info   {
 135  134                          BEGIN TSTATE;
 136  135                          state = TSTATE;
 137  136                          return INFO;
 138  137                  }
 139  138  
 140  139  <INITIAL>remove {
 141  140                          BEGIN TSTATE;
 142  141                          state = TSTATE;
 143  142                          return REMOVE;
 144  143                  }
 145  144  
 146  145  <INITIAL>revert {
 147  146                          BEGIN TSTATE;
 148  147                          state = TSTATE;
 149  148                          return REVERT;
 150  149                  }
 151  150  
 152  151  <INITIAL>select {
 153  152                          BEGIN TSTATE;
 154  153                          state = TSTATE;
 155  154                          return SELECT;
 156  155                  }
 157  156  
 158  157  <INITIAL>set {
 159  158                          BEGIN TSTATE;
 160  159                          state = TSTATE;
 161  160                          return SET;
 162  161                  }
 163  162  
 164  163  <INITIAL>clear {
 165  164                          BEGIN TSTATE;
 166  165                          state = TSTATE;
 167  166                          return CLEAR;
 168  167                  }
 169  168  
 170  169  <INITIAL>verify {
 171  170                          BEGIN TSTATE;
 172  171                          state = TSTATE;
 173  172                          return VERIFY;
 174  173                  }
 175  174  
 176  175  <TSTATE>net     { return NET; }
 177  176  
 178  177  <TSTATE>fs      { return FS; }
 179  178  
 180  179  <TSTATE>device  { return DEVICE; }
 181  180  
 182  181  <TSTATE>rctl    { return RCTL; }
 183  182  
 184  183  <TSTATE>attr    { return ATTR; }
 185  184  
 186  185  <TSTATE>admin   { return ADMIN; }
 187  186  
 188  187  <TSTATE>zonename        { return ZONENAME; }
 189  188  <CSTATE>zonename        { return ZONENAME; }
 190  189  
 191  190  <TSTATE>dataset { return DATASET; }
 192  191  
 193  192  <TSTATE>dedicated-cpu   { return PSET; }
 194  193  
 195  194  <TSTATE>capped-cpu      { return PCAP; }
 196  195  
 197  196  <TSTATE>capped-memory   { return MCAP; }
 198  197  
 199  198  <TSTATE>zonepath        { return ZONEPATH; }
 200  199  <CSTATE>zonepath        { return ZONEPATH; }
 201  200  
 202  201  <TSTATE>brand   { return BRAND; }
 203  202  <CSTATE>brand   { return BRAND; }
 204  203  
 205  204  <TSTATE>autoboot        { return AUTOBOOT; }
 206  205  <CSTATE>autoboot        { return AUTOBOOT; }
 207  206  
 208  207  <TSTATE>ip-type         { return IPTYPE; }
 209  208  <CSTATE>ip-type         { return IPTYPE; }
 210  209  
 211  210  <TSTATE>pool    { return POOL; }
 212  211  <CSTATE>pool    { return POOL; }
 213  212  
 214  213  <TSTATE>limitpriv       { return LIMITPRIV; }
 215  214  <CSTATE>limitpriv       { return LIMITPRIV; }
 216  215  
 217  216  <TSTATE>bootargs        { return BOOTARGS; }
 218  217  <CSTATE>bootargs        { return BOOTARGS; }
 219  218  
 220  219  <TSTATE>type    { return TYPE; }
 221  220  <CSTATE>type    { return TYPE; }
 222  221  
 223  222  <TSTATE>value   { return VALUE; }
 224  223  <CSTATE>value   { return VALUE; }
 225  224  
 226  225  <TSTATE>options { return OPTIONS; }
 227  226  <CSTATE>options { return OPTIONS; }
 228  227  
 229  228  <TSTATE>allowed-address { return ALLOWED_ADDRESS; }
 230  229  <CSTATE>allowed-address { return ALLOWED_ADDRESS; }
 231  230  
 232  231  <TSTATE>address { return ADDRESS; }
 233  232  <CSTATE>address { return ADDRESS; }
 234  233  
 235  234  <TSTATE>physical        { return PHYSICAL; }
 236  235  <CSTATE>physical        { return PHYSICAL; }
 237  236  
 238  237  <TSTATE>defrouter       { return DEFROUTER; }
 239  238  <CSTATE>defrouter       { return DEFROUTER; }
 240  239  
 241  240  <TSTATE>mac-addr        { return MAC; }
 242  241  <CSTATE>mac-addr        { return MAC; }
 243  242  
 244  243  <TSTATE>vlan-id         { return VLANID; }
 245  244  <CSTATE>vlan-id         { return VLANID; }
 246  245  
 247  246  <TSTATE>global-nic      { return GNIC; }
 248  247  <CSTATE>global-nic      { return GNIC; }
 249  248  
 250  249  <TSTATE>property        { return NPROP; }
 251  250  <CSTATE>property        { return NPROP; }
 252  251  
 253  252  <TSTATE>dir     { return DIR; }
 254  253  <CSTATE>dir     { return DIR; }
 255  254  
 256  255  <TSTATE>special { return SPECIAL; }
 257  256  <CSTATE>special { return SPECIAL; }
 258  257  
 259  258  <TSTATE>raw     { return RAW; }
 260  259  <CSTATE>raw     { return RAW; }
 261  260  
 262  261  <TSTATE>name    { return NAME; }
 263  262  <CSTATE>name    { return NAME; }
 264  263  
 265  264  <TSTATE>match   { return MATCH; }
 266  265  <CSTATE>match   { return MATCH; }
 267  266  
 268  267  <TSTATE>priv    { return PRIV; }
 269  268  <CSTATE>priv    { return PRIV; }
 270  269  
 271  270  <TSTATE>limit   { return LIMIT; }
 272  271  <CSTATE>limit   { return LIMIT; }
 273  272  
 274  273  <TSTATE>action  { return ACTION; }
 275  274  <CSTATE>action  { return ACTION; }
 276  275  
 277  276  <TSTATE>ncpus   { return NCPUS; }
 278  277  <CSTATE>ncpus   { return NCPUS; }
 279  278  
 280  279  <TSTATE>locked  { return LOCKED; }
 281  280  <CSTATE>locked  { return LOCKED; }
 282  281  
 283  282  <TSTATE>swap    { return SWAP; }
 284  283  <CSTATE>swap    { return SWAP; }
 285  284  
 286  285  <TSTATE>importance      { return IMPORTANCE; }
 287  286  <CSTATE>importance      { return IMPORTANCE; }
 288  287  
 289  288  <TSTATE>cpu-shares      { return SHARES; }
 290  289  <CSTATE>cpu-shares      { return SHARES; }
 291  290  
 292  291  <TSTATE>max-lwps        { return MAXLWPS; }
 293  292  <CSTATE>max-lwps        { return MAXLWPS; }
 294  293  
 295  294  <TSTATE>max-processes   { return MAXPROCS; }
 296  295  <CSTATE>max-processes   { return MAXPROCS; }
 297  296  
 298  297  <TSTATE>max-shm-memory  { return MAXSHMMEM; }
 299  298  <CSTATE>max-shm-memory  { return MAXSHMMEM; }
 300  299  
 301  300  <TSTATE>max-shm-ids     { return MAXSHMIDS; }
 302  301  <CSTATE>max-shm-ids     { return MAXSHMIDS; }
 303  302  
 304  303  <TSTATE>max-msg-ids     { return MAXMSGIDS; }
 305  304  <CSTATE>max-msg-ids     { return MAXMSGIDS; }
 306  305  
 307  306  <TSTATE>max-sem-ids     { return MAXSEMIDS; }
 308  307  <CSTATE>max-sem-ids     { return MAXSEMIDS; }
 309  308  
 310  309  <TSTATE>scheduling-class        { return SCHED; }
 311  310  <CSTATE>scheduling-class        { return SCHED; }
 312  311  
 313  312  <TSTATE>hostid          { return HOSTID; }
 314  313  <CSTATE>hostid          { return HOSTID; }
  
    | 
      ↓ open down ↓ | 
    279 lines elided | 
    
      ↑ open up ↑ | 
  
 315  314  
 316  315  <TSTATE>user    { return USER; }
 317  316  <CSTATE>user    { return USER; }
 318  317  
 319  318  <TSTATE>auths   { return AUTHS; }
 320  319  <CSTATE>auths   { return AUTHS; }
 321  320  
 322  321  <TSTATE>fs-allowed      { return FS_ALLOWED; }
 323  322  <CSTATE>fs-allowed      { return FS_ALLOWED; }
 324  323  
 325      -<TSTATE>uuid    { return UUID; }
 326      -<CSTATE>uuid    { return UUID; }
 327      -
 328      -<TSTATE>zfs-io-priority { return ZFSPRI; }
 329      -<CSTATE>zfs-io-priority { return ZFSPRI; }
 330      -
 331  324  <TSTATE>=       { return EQUAL; }
 332  325  <LSTATE>=       { return EQUAL; }
 333  326  <CSTATE>=       { return EQUAL; }
 334  327  
 335  328  <TSTATE>"["     {
 336  329                          BEGIN LSTATE;
 337  330                          state = LSTATE;
 338  331                          return OPEN_SQ_BRACKET;
 339  332                  }
 340  333  
 341  334  <LSTATE>"]"     {
 342  335                          BEGIN TSTATE;
 343  336                          state = TSTATE;
 344  337                          return CLOSE_SQ_BRACKET;
 345  338                  }
 346  339  
 347  340  <TSTATE>"("     {
 348  341                          BEGIN CSTATE;
 349  342                          return OPEN_PAREN;
 350  343                  }
 351  344  
 352  345  <LSTATE>"("     {
 353  346                          BEGIN CSTATE;
 354  347                          return OPEN_PAREN;
 355  348                  }
 356  349  
 357  350  <CSTATE>")"     {
 358  351                          BEGIN state;
 359  352                          return CLOSE_PAREN;
 360  353                  }
 361  354  
 362  355  <LSTATE>","     { return COMMA; }
 363  356  <CSTATE>","     { return COMMA; }
 364  357  
 365  358  <TSTATE>[^ \t\n\";=\[\]\(\)]+   {
 366  359                          yylval.strval = create_token(yytext);
 367  360                          return TOKEN;
 368  361                  }
 369  362  
 370  363  <LSTATE>[^ \t\n\",;=\[\]\(\)]+  {
 371  364                          yylval.strval = create_token(yytext);
 372  365                          return TOKEN;
 373  366                  }
 374  367  
 375  368  <CSTATE>[^ \t\n\",;=\(\)]+      {
 376  369                          yylval.strval = create_token(yytext);
 377  370                          return TOKEN;
 378  371                  }
 379  372  
 380  373  <CSTATE>\"[^\"\n]*[\"\n] {
 381  374                          yylval.strval = create_token(yytext + 1);
 382  375                          if (yylval.strval[yyleng - 2] == '"')
 383  376                                  yylval.strval[yyleng - 2] = 0;
 384  377                          return TOKEN;
 385  378                  }
 386  379  
 387  380  <TSTATE>\"[^\"\n]*[\"\n] {
 388  381                          yylval.strval = create_token(yytext + 1);
 389  382                          if (yylval.strval[yyleng - 2] == '"')
 390  383                                  yylval.strval[yyleng - 2] = 0;
 391  384                          return TOKEN;
 392  385                  }
 393  386  
 394  387  <LSTATE>\"[^\"\n]*[\"\n] {
 395  388                          yylval.strval = create_token(yytext + 1);
 396  389                          if (yylval.strval[yyleng - 2] == '"')
 397  390                                  yylval.strval[yyleng - 2] = 0;
 398  391                          return TOKEN;
 399  392                  }
 400  393  
 401  394  ";"             {
 402  395                          BEGIN INITIAL;
 403  396                          return (yytext[0]);
 404  397                  }
 405  398  
 406  399  \n              {
 407  400                          lex_lineno++;
 408  401                          BEGIN INITIAL;
 409  402                          return (yytext[0]);
 410  403                  }
 411  404  
 412  405  [ \t]           ;       /* Ignore whitespace */
 413  406  
 414  407  .               {
 415  408                          return (yytext[0]);
 416  409                  }
 417  410  
 418  411  %%
 419  412  
 420  413  /*
 421  414   * Assert that there are no unclaimed tokens.  This function enforces the
 422  415   * invariants mentioned at the top of this file.
 423  416   */
 424  417  void
 425  418  assert_no_unclaimed_tokens(void)
 426  419  {
 427  420          assert(num_unclaimed_tokens == 0);
 428  421          assert(unclaimed_tokens == NULL);
 429  422          assert(unclaimed_tokens_size == 0);
 430  423  }
 431  424  
 432  425  /*
 433  426   * Claim the specified unclaimed TOKEN.  YACC reduction rules that
 434  427   * use TOKENs should invoke this function immediately before freeing the TOKENs
 435  428   * or adding them to data structures that will be cleaned up when the YACC
 436  429   * parser finishes or encounters errors.  Reduction rules should only claim the
 437  430   * TOKENs that they use.
 438  431   *
 439  432   * This function returns its argument but does not free its memory.
 440  433   */
 441  434  char *
 442  435  claim_token(char *token)
 443  436  {
 444  437          unsigned int index;
 445  438  
 446  439          /*
 447  440           * Find the token in the list of unclaimed tokens.
 448  441           */
 449  442          assert(num_unclaimed_tokens > 0);
 450  443          for (index = 0; index < num_unclaimed_tokens; index++) {
 451  444                  if (unclaimed_tokens[index] == token)
 452  445                          break;
 453  446          }
 454  447  
 455  448          /*
 456  449           * Abort if we didn't find the token.
 457  450           */
 458  451          assert(index != num_unclaimed_tokens);
 459  452  
 460  453          /*
 461  454           * Replace the token with the last unclaimed token.
 462  455           */
 463  456          num_unclaimed_tokens--;
 464  457          unclaimed_tokens[index] = unclaimed_tokens[num_unclaimed_tokens];
 465  458  
 466  459          /*
 467  460           * Delete the list of unclaimed tokens if it's empty.
 468  461           */
 469  462          if (num_unclaimed_tokens == 0) {
 470  463                  free(unclaimed_tokens);
 471  464                  unclaimed_tokens = NULL;
 472  465                  unclaimed_tokens_size = 0;
 473  466          }
 474  467  
 475  468          return (token);
 476  469  }
 477  470  
 478  471  /*
 479  472   * Free all unclaimed TOKENs.  This should only be invoked when the YACC
 480  473   * parser encounters errors.
 481  474   */
 482  475  static void
 483  476  free_tokens(void)
 484  477  {
 485  478          if (unclaimed_tokens != NULL) {
 486  479                  while (num_unclaimed_tokens > 0)
 487  480                          free(unclaimed_tokens[--num_unclaimed_tokens]);
 488  481                  free(unclaimed_tokens);
 489  482                  unclaimed_tokens = NULL;
 490  483                  unclaimed_tokens_size = 0;
 491  484          }
 492  485          assert_no_unclaimed_tokens();
 493  486  }
 494  487  
 495  488  /*
 496  489   * Create a TOKEN from the specified string.  The TOKEN is merely a duplicate
 497  490   * of the specified string.  TOKENs must be claimed by the YACC reduction rules
 498  491   * that use them; see claim_token() above.
 499  492   */
 500  493  char *
 501  494  create_token(char *s)
 502  495  {
 503  496          char *result;
 504  497  
 505  498          if ((result = strdup(s)) == NULL) {
 506  499                  yyerror("Out of memory");
 507  500                  exit(Z_ERR);
 508  501          }
 509  502  
 510  503          /*
 511  504           * Add the new TOKEN to the list of unclaimed TOKENs.  The list might
 512  505           * have to be resized.
 513  506           *
 514  507           * Reduction rules should claim TOKENs via claim_token() (see above).
 515  508           */
 516  509          if (num_unclaimed_tokens == unclaimed_tokens_size) {
 517  510                  char **new_unclaimed_tokens;
 518  511  
 519  512                  unclaimed_tokens_size += UNCLAIMED_TOKENS_BUFFER_GROWTH;
 520  513                  new_unclaimed_tokens = (char **)realloc(unclaimed_tokens,
 521  514                      unclaimed_tokens_size * sizeof (char *));
 522  515                  if (new_unclaimed_tokens == NULL) {
 523  516                          yyerror("Out of memory");
 524  517                          free(result);
 525  518                          exit(Z_ERR);
 526  519                  }
 527  520                  unclaimed_tokens = new_unclaimed_tokens;
 528  521          }
 529  522          unclaimed_tokens[num_unclaimed_tokens] = result;
 530  523          num_unclaimed_tokens++;
 531  524          return (result);
 532  525  }
 533  526  
 534  527  void
 535  528  yyerror(char *s)
 536  529  {
 537  530          /*
 538  531           * Ensure that we won't leak unclaimed tokens.
 539  532           */
 540  533          free_tokens();
 541  534  
 542  535          /* feof(yyin) is not an error; anything else is, so we set saw_error */
 543  536          if (yytext[0] == '\0') {
 544  537                  if (!feof(yyin)) {
 545  538                          saw_error = B_TRUE;
 546  539                          (void) fprintf(stderr, gettext("%s, token expected\n"),
 547  540                              s);
 548  541                  }
 549  542                  return;
 550  543          }
 551  544  
 552  545          saw_error = B_TRUE;
 553  546          if (cmd_file_mode)
 554  547                  (void) fprintf(stderr, gettext("%s on line %d at '%s'\n"), s,
 555  548                      lex_lineno, (yytext[0] == '\n') ? "\\n" : yytext);
 556  549          else
 557  550                  (void) fprintf(stderr, gettext("%s at '%s'\n"), s,
 558  551                      (yytext[0] == '\n') ? "\\n" : yytext);
 559  552          usage(B_FALSE, HELP_SUBCMDS);
 560  553  }
  
    | 
      ↓ open down ↓ | 
    220 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX