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 */ 22 23 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <stdio.h> 31 32 #include "zonecfg.h" 33 34 static cmd_t *cmd = NULL; /* Command being processed */ 35 static complex_property_ptr_t complex = NULL; 36 static list_property_ptr_t new_list = NULL, tmp_list, last, 37 list[MAX_EQ_PROP_PAIRS]; 38 static property_value_t property[MAX_EQ_PROP_PAIRS]; 39 40 extern bool newline_terminated; 41 extern int num_prop_vals; /* # of property values */ 42 43 /* yacc externals */ 44 extern int yydebug; 45 extern void yyerror(char *s); 46 47 %} 48 49 %union { 50 int ival; 51 char *strval; 52 cmd_t *cmd; 53 complex_property_ptr_t complex; 54 list_property_ptr_t list; 55 } 56 57 %start commands 58 59 %token HELP CREATE EXPORT ADD DELETE REMOVE SELECT SET INFO CANCEL END VERIFY 60 %token COMMIT REVERT EXIT SEMICOLON TOKEN ZONENAME ZONEPATH AUTOBOOT POOL NET 61 %token FS IPD ATTR DEVICE RCTL SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL 62 %token NAME MATCH PRIV LIMIT ACTION VALUE EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET 63 %token OPEN_PAREN CLOSE_PAREN COMMA DATASET LIMITPRIV 64 65 %type <strval> TOKEN EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET 66 property_value OPEN_PAREN CLOSE_PAREN COMMA simple_prop_val 67 %type <complex> complex_piece complex_prop_val 68 %type <ival> resource_type NET FS IPD DEVICE RCTL ATTR 69 %type <ival> property_name SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL NAME 70 MATCH ZONENAME ZONEPATH AUTOBOOT POOL LIMITPRIV VALUE PRIV LIMIT ACTION 71 %type <cmd> command 72 %type <cmd> add_command ADD 73 %type <cmd> cancel_command CANCEL 74 %type <cmd> commit_command COMMIT 75 %type <cmd> create_command CREATE 76 %type <cmd> delete_command DELETE 77 %type <cmd> end_command END 78 %type <cmd> exit_command EXIT 79 %type <cmd> export_command EXPORT 80 %type <cmd> help_command HELP 81 %type <cmd> info_command INFO 82 %type <cmd> remove_command REMOVE 83 %type <cmd> revert_command REVERT 84 %type <cmd> select_command SELECT 85 %type <cmd> set_command SET 86 %type <cmd> verify_command VERIFY 87 %type <cmd> terminator 88 89 %% 90 91 commands: command terminator 92 { 93 if ($1 != NULL) { 94 if ($1->cmd_handler != NULL) 95 $1->cmd_handler($1); 96 free_cmd($1); 97 bzero(list, sizeof (list_property_t)); 98 num_prop_vals = 0; 99 } 100 return (0); 101 } 102 | command error terminator 103 { 104 if ($1 != NULL) { 105 free_cmd($1); 106 bzero(list, sizeof (list_property_t)); 107 num_prop_vals = 0; 108 } 109 if (YYRECOVERING()) 110 YYABORT; 111 yyclearin; 112 yyerrok; 113 } 114 | error terminator 115 { 116 if (YYRECOVERING()) 117 YYABORT; 118 yyclearin; 119 yyerrok; 120 } 121 | terminator 122 { 123 return (0); 124 } 125 126 command: add_command 127 | cancel_command 128 | create_command 129 | commit_command 130 | delete_command 131 | end_command 132 | exit_command 133 | export_command 134 | help_command 135 | info_command 136 | remove_command 137 | revert_command 138 | select_command 139 | set_command 140 | verify_command 141 142 terminator: '\n' { newline_terminated = TRUE; } 143 | ';' { newline_terminated = FALSE; } 144 145 add_command: ADD 146 { 147 short_usage(CMD_ADD); 148 (void) fputs("\n", stderr); 149 usage(FALSE, HELP_RES_PROPS); 150 YYERROR; 151 } 152 | ADD TOKEN 153 { 154 if (($$ = alloc_cmd()) == NULL) 155 YYERROR; 156 cmd = $$; 157 $$->cmd_handler = &add_func; 158 $$->cmd_argc = 1; 159 $$->cmd_argv[0] = $2; 160 $$->cmd_argv[1] = NULL; 161 } 162 | ADD resource_type 163 { 164 if (($$ = alloc_cmd()) == NULL) 165 YYERROR; 166 cmd = $$; 167 $$->cmd_handler = &add_func; 168 $$->cmd_argc = 0; 169 $$->cmd_res_type = $2; 170 $$->cmd_prop_nv_pairs = 0; 171 } 172 | ADD property_name property_value 173 { 174 if (($$ = alloc_cmd()) == NULL) 175 YYERROR; 176 cmd = $$; 177 $$->cmd_handler = &add_func; 178 $$->cmd_argc = 0; 179 $$->cmd_prop_nv_pairs = 1; 180 $$->cmd_prop_name[0] = $2; 181 $$->cmd_property_ptr[0] = &property[0]; 182 } 183 184 cancel_command: CANCEL 185 { 186 if (($$ = alloc_cmd()) == NULL) 187 YYERROR; 188 cmd = $$; 189 $$->cmd_handler = &cancel_func; 190 $$->cmd_argc = 0; 191 $$->cmd_argv[0] = NULL; 192 } 193 | CANCEL TOKEN 194 { 195 if (($$ = alloc_cmd()) == NULL) 196 YYERROR; 197 cmd = $$; 198 $$->cmd_handler = &cancel_func; 199 $$->cmd_argc = 1; 200 $$->cmd_argv[0] = $2; 201 $$->cmd_argv[1] = NULL; 202 } 203 204 create_command: CREATE 205 { 206 if (($$ = alloc_cmd()) == NULL) 207 YYERROR; 208 cmd = $$; 209 $$->cmd_handler = &create_func; 210 $$->cmd_argc = 0; 211 $$->cmd_argv[0] = NULL; 212 } 213 | CREATE TOKEN 214 { 215 if (($$ = alloc_cmd()) == NULL) 216 YYERROR; 217 cmd = $$; 218 $$->cmd_handler = &create_func; 219 $$->cmd_argc = 1; 220 $$->cmd_argv[0] = $2; 221 $$->cmd_argv[1] = NULL; 222 } 223 | CREATE TOKEN TOKEN 224 { 225 if (($$ = alloc_cmd()) == NULL) 226 YYERROR; 227 cmd = $$; 228 $$->cmd_handler = &create_func; 229 $$->cmd_argc = 2; 230 $$->cmd_argv[0] = $2; 231 $$->cmd_argv[1] = $3; 232 $$->cmd_argv[2] = NULL; 233 } 234 | CREATE TOKEN TOKEN TOKEN 235 { 236 if (($$ = alloc_cmd()) == NULL) 237 YYERROR; 238 cmd = $$; 239 $$->cmd_handler = &create_func; 240 $$->cmd_argc = 3; 241 $$->cmd_argv[0] = $2; 242 $$->cmd_argv[1] = $3; 243 $$->cmd_argv[2] = $4; 244 $$->cmd_argv[3] = NULL; 245 } 246 247 commit_command: COMMIT 248 { 249 if (($$ = alloc_cmd()) == NULL) 250 YYERROR; 251 cmd = $$; 252 $$->cmd_handler = &commit_func; 253 $$->cmd_argc = 0; 254 $$->cmd_argv[0] = NULL; 255 } 256 | COMMIT TOKEN 257 { 258 if (($$ = alloc_cmd()) == NULL) 259 YYERROR; 260 cmd = $$; 261 $$->cmd_handler = &commit_func; 262 $$->cmd_argc = 1; 263 $$->cmd_argv[0] = $2; 264 $$->cmd_argv[1] = NULL; 265 } 266 267 delete_command: DELETE 268 { 269 if (($$ = alloc_cmd()) == NULL) 270 YYERROR; 271 cmd = $$; 272 $$->cmd_handler = &delete_func; 273 $$->cmd_argc = 0; 274 $$->cmd_argv[0] = NULL; 275 } 276 | DELETE TOKEN 277 { 278 if (($$ = alloc_cmd()) == NULL) 279 YYERROR; 280 cmd = $$; 281 $$->cmd_handler = &delete_func; 282 $$->cmd_argc = 1; 283 $$->cmd_argv[0] = $2; 284 $$->cmd_argv[1] = NULL; 285 } 286 287 end_command: END 288 { 289 if (($$ = alloc_cmd()) == NULL) 290 YYERROR; 291 cmd = $$; 292 $$->cmd_handler = &end_func; 293 $$->cmd_argc = 0; 294 $$->cmd_argv[0] = NULL; 295 } 296 | END TOKEN 297 { 298 if (($$ = alloc_cmd()) == NULL) 299 YYERROR; 300 cmd = $$; 301 $$->cmd_handler = &end_func; 302 $$->cmd_argc = 1; 303 $$->cmd_argv[0] = $2; 304 $$->cmd_argv[1] = NULL; 305 } 306 307 exit_command: EXIT 308 { 309 if (($$ = alloc_cmd()) == NULL) 310 YYERROR; 311 cmd = $$; 312 $$->cmd_handler = &exit_func; 313 $$->cmd_argc = 0; 314 $$->cmd_argv[0] = NULL; 315 } 316 | EXIT TOKEN 317 { 318 if (($$ = alloc_cmd()) == NULL) 319 YYERROR; 320 cmd = $$; 321 $$->cmd_handler = &exit_func; 322 $$->cmd_argc = 1; 323 $$->cmd_argv[0] = $2; 324 $$->cmd_argv[1] = NULL; 325 } 326 327 export_command: EXPORT 328 { 329 if (($$ = alloc_cmd()) == NULL) 330 YYERROR; 331 cmd = $$; 332 $$->cmd_handler = &export_func; 333 $$->cmd_argc = 0; 334 $$->cmd_argv[0] = NULL; 335 } 336 | EXPORT TOKEN 337 { 338 if (($$ = alloc_cmd()) == NULL) 339 YYERROR; 340 cmd = $$; 341 $$->cmd_handler = &export_func; 342 $$->cmd_argc = 1; 343 $$->cmd_argv[0] = $2; 344 $$->cmd_argv[1] = NULL; 345 } 346 | EXPORT TOKEN TOKEN 347 { 348 if (($$ = alloc_cmd()) == NULL) 349 YYERROR; 350 cmd = $$; 351 $$->cmd_handler = &export_func; 352 $$->cmd_argc = 2; 353 $$->cmd_argv[0] = $2; 354 $$->cmd_argv[1] = $3; 355 $$->cmd_argv[2] = NULL; 356 } 357 358 help_command: HELP 359 { 360 if (($$ = alloc_cmd()) == NULL) 361 YYERROR; 362 cmd = $$; 363 $$->cmd_handler = &help_func; 364 $$->cmd_argc = 0; 365 $$->cmd_argv[0] = NULL; 366 } 367 | HELP TOKEN 368 { 369 if (($$ = alloc_cmd()) == NULL) 370 YYERROR; 371 cmd = $$; 372 $$->cmd_handler = &help_func; 373 $$->cmd_argc = 1; 374 $$->cmd_argv[0] = $2; 375 $$->cmd_argv[1] = NULL; 376 } 377 378 info_command: INFO 379 { 380 if (($$ = alloc_cmd()) == NULL) 381 YYERROR; 382 cmd = $$; 383 $$->cmd_handler = &info_func; 384 $$->cmd_res_type = RT_UNKNOWN; 385 $$->cmd_prop_nv_pairs = 0; 386 } 387 | INFO TOKEN 388 { 389 short_usage(CMD_INFO); 390 (void) fputs("\n", stderr); 391 usage(FALSE, HELP_RES_PROPS); 392 free($2); 393 YYERROR; 394 } 395 | INFO resource_type 396 { 397 if (($$ = alloc_cmd()) == NULL) 398 YYERROR; 399 cmd = $$; 400 $$->cmd_handler = &info_func; 401 $$->cmd_res_type = $2; 402 $$->cmd_prop_nv_pairs = 0; 403 } 404 | INFO ZONENAME 405 { 406 if (($$ = alloc_cmd()) == NULL) 407 YYERROR; 408 cmd = $$; 409 $$->cmd_handler = &info_func; 410 $$->cmd_res_type = RT_ZONENAME; 411 $$->cmd_prop_nv_pairs = 0; 412 } 413 | INFO ZONEPATH 414 { 415 if (($$ = alloc_cmd()) == NULL) 416 YYERROR; 417 cmd = $$; 418 $$->cmd_handler = &info_func; 419 $$->cmd_res_type = RT_ZONEPATH; 420 $$->cmd_prop_nv_pairs = 0; 421 } 422 | INFO AUTOBOOT 423 { 424 if (($$ = alloc_cmd()) == NULL) 425 YYERROR; 426 cmd = $$; 427 $$->cmd_handler = &info_func; 428 $$->cmd_res_type = RT_AUTOBOOT; 429 $$->cmd_prop_nv_pairs = 0; 430 } 431 | INFO POOL 432 { 433 if (($$ = alloc_cmd()) == NULL) 434 YYERROR; 435 cmd = $$; 436 $$->cmd_handler = &info_func; 437 $$->cmd_res_type = RT_POOL; 438 $$->cmd_prop_nv_pairs = 0; 439 } 440 | INFO LIMITPRIV 441 { 442 if (($$ = alloc_cmd()) == NULL) 443 YYERROR; 444 cmd = $$; 445 $$->cmd_handler = &info_func; 446 $$->cmd_res_type = RT_LIMITPRIV; 447 $$->cmd_prop_nv_pairs = 0; 448 } 449 | INFO resource_type property_name EQUAL property_value 450 { 451 if (($$ = alloc_cmd()) == NULL) 452 YYERROR; 453 cmd = $$; 454 $$->cmd_handler = &info_func; 455 $$->cmd_res_type = $2; 456 $$->cmd_prop_nv_pairs = 1; 457 $$->cmd_prop_name[0] = $3; 458 $$->cmd_property_ptr[0] = &property[0]; 459 } 460 | INFO resource_type property_name EQUAL property_value property_name EQUAL property_value 461 { 462 if (($$ = alloc_cmd()) == NULL) 463 YYERROR; 464 cmd = $$; 465 $$->cmd_handler = &info_func; 466 $$->cmd_res_type = $2; 467 $$->cmd_prop_nv_pairs = 2; 468 $$->cmd_prop_name[0] = $3; 469 $$->cmd_property_ptr[0] = &property[0]; 470 $$->cmd_prop_name[1] = $6; 471 $$->cmd_property_ptr[1] = &property[1]; 472 } 473 | INFO resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value 474 { 475 if (($$ = alloc_cmd()) == NULL) 476 YYERROR; 477 cmd = $$; 478 $$->cmd_handler = &info_func; 479 $$->cmd_res_type = $2; 480 $$->cmd_prop_nv_pairs = 3; 481 $$->cmd_prop_name[0] = $3; 482 $$->cmd_property_ptr[0] = &property[0]; 483 $$->cmd_prop_name[1] = $6; 484 $$->cmd_property_ptr[1] = &property[1]; 485 $$->cmd_prop_name[2] = $9; 486 $$->cmd_property_ptr[2] = &property[2]; 487 } 488 489 remove_command: REMOVE 490 { 491 short_usage(CMD_REMOVE); 492 (void) fputs("\n", stderr); 493 usage(FALSE, HELP_RES_PROPS); 494 YYERROR; 495 } 496 | REMOVE resource_type 497 { 498 short_usage(CMD_REMOVE); 499 YYERROR; 500 } 501 | REMOVE property_name property_value 502 { 503 if (($$ = alloc_cmd()) == NULL) 504 YYERROR; 505 cmd = $$; 506 $$->cmd_handler = &remove_func; 507 $$->cmd_prop_nv_pairs = 1; 508 $$->cmd_prop_name[0] = $2; 509 $$->cmd_property_ptr[0] = &property[0]; 510 } 511 | REMOVE resource_type property_name EQUAL property_value 512 { 513 if (($$ = alloc_cmd()) == NULL) 514 YYERROR; 515 cmd = $$; 516 $$->cmd_handler = &remove_func; 517 $$->cmd_res_type = $2; 518 $$->cmd_prop_nv_pairs = 1; 519 $$->cmd_prop_name[0] = $3; 520 $$->cmd_property_ptr[0] = &property[0]; 521 } 522 | REMOVE resource_type property_name EQUAL property_value property_name EQUAL property_value 523 { 524 if (($$ = alloc_cmd()) == NULL) 525 YYERROR; 526 cmd = $$; 527 $$->cmd_handler = &remove_func; 528 $$->cmd_res_type = $2; 529 $$->cmd_prop_nv_pairs = 2; 530 $$->cmd_prop_name[0] = $3; 531 $$->cmd_property_ptr[0] = &property[0]; 532 $$->cmd_prop_name[1] = $6; 533 $$->cmd_property_ptr[1] = &property[1]; 534 } 535 | REMOVE resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value 536 { 537 if (($$ = alloc_cmd()) == NULL) 538 YYERROR; 539 cmd = $$; 540 $$->cmd_handler = &remove_func; 541 $$->cmd_res_type = $2; 542 $$->cmd_prop_nv_pairs = 3; 543 $$->cmd_prop_name[0] = $3; 544 $$->cmd_property_ptr[0] = &property[0]; 545 $$->cmd_prop_name[1] = $6; 546 $$->cmd_property_ptr[1] = &property[1]; 547 $$->cmd_prop_name[2] = $9; 548 $$->cmd_property_ptr[2] = &property[2]; 549 } 550 551 revert_command: REVERT 552 { 553 if (($$ = alloc_cmd()) == NULL) 554 YYERROR; 555 cmd = $$; 556 $$->cmd_handler = &revert_func; 557 $$->cmd_argc = 0; 558 $$->cmd_argv[0] = NULL; 559 } 560 | REVERT TOKEN 561 { 562 if (($$ = alloc_cmd()) == NULL) 563 YYERROR; 564 cmd = $$; 565 $$->cmd_handler = &revert_func; 566 $$->cmd_argc = 1; 567 $$->cmd_argv[0] = $2; 568 $$->cmd_argv[1] = NULL; 569 } 570 571 select_command: SELECT 572 { 573 short_usage(CMD_SELECT); 574 (void) fputs("\n", stderr); 575 usage(FALSE, HELP_RES_PROPS); 576 YYERROR; 577 } 578 | SELECT resource_type 579 { 580 short_usage(CMD_SELECT); 581 YYERROR; 582 } 583 | SELECT resource_type property_name EQUAL property_value 584 { 585 if (($$ = alloc_cmd()) == NULL) 586 YYERROR; 587 cmd = $$; 588 $$->cmd_handler = &select_func; 589 $$->cmd_res_type = $2; 590 $$->cmd_prop_nv_pairs = 1; 591 $$->cmd_prop_name[0] = $3; 592 $$->cmd_property_ptr[0] = &property[0]; 593 } 594 | SELECT resource_type property_name EQUAL property_value property_name EQUAL property_value 595 { 596 if (($$ = alloc_cmd()) == NULL) 597 YYERROR; 598 cmd = $$; 599 $$->cmd_handler = &select_func; 600 $$->cmd_res_type = $2; 601 $$->cmd_prop_nv_pairs = 2; 602 $$->cmd_prop_name[0] = $3; 603 $$->cmd_property_ptr[0] = &property[0]; 604 $$->cmd_prop_name[1] = $6; 605 $$->cmd_property_ptr[1] = &property[1]; 606 } 607 | SELECT resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value 608 { 609 if (($$ = alloc_cmd()) == NULL) 610 YYERROR; 611 cmd = $$; 612 $$->cmd_handler = &select_func; 613 $$->cmd_res_type = $2; 614 $$->cmd_prop_nv_pairs = 3; 615 $$->cmd_prop_name[0] = $3; 616 $$->cmd_property_ptr[0] = &property[0]; 617 $$->cmd_prop_name[1] = $6; 618 $$->cmd_property_ptr[1] = &property[1]; 619 $$->cmd_prop_name[2] = $9; 620 $$->cmd_property_ptr[2] = &property[2]; 621 } 622 623 set_command: SET 624 { 625 short_usage(CMD_SET); 626 (void) fputs("\n", stderr); 627 usage(FALSE, HELP_PROPS); 628 YYERROR; 629 } 630 | SET property_name EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET 631 { 632 if (($$ = alloc_cmd()) == NULL) 633 YYERROR; 634 cmd = $$; 635 $$->cmd_handler = &set_func; 636 $$->cmd_prop_nv_pairs = 0; 637 $$->cmd_prop_name[0] = $2; 638 property[0].pv_type = PROP_VAL_LIST; 639 property[0].pv_list = NULL; 640 $$->cmd_property_ptr[0] = &property[0]; 641 } 642 | SET property_name EQUAL property_value 643 { 644 if (($$ = alloc_cmd()) == NULL) 645 YYERROR; 646 cmd = $$; 647 $$->cmd_handler = &set_func; 648 $$->cmd_prop_nv_pairs = 1; 649 $$->cmd_prop_name[0] = $2; 650 $$->cmd_property_ptr[0] = &property[0]; 651 } 652 653 verify_command: VERIFY 654 { 655 if (($$ = alloc_cmd()) == NULL) 656 YYERROR; 657 cmd = $$; 658 $$->cmd_handler = &verify_func; 659 $$->cmd_argc = 0; 660 $$->cmd_argv[0] = NULL; 661 } 662 | VERIFY TOKEN 663 { 664 if (($$ = alloc_cmd()) == NULL) 665 YYERROR; 666 cmd = $$; 667 $$->cmd_handler = &verify_func; 668 $$->cmd_argc = 1; 669 $$->cmd_argv[0] = $2; 670 $$->cmd_argv[1] = NULL; 671 } 672 673 resource_type: NET { $$ = RT_NET; } 674 | FS { $$ = RT_FS; } 675 | IPD { $$ = RT_IPD; } 676 | DEVICE { $$ = RT_DEVICE; } 677 | RCTL { $$ = RT_RCTL; } 678 | ATTR { $$ = RT_ATTR; } 679 | DATASET { $$ = RT_DATASET; } 680 681 property_name: SPECIAL { $$ = PT_SPECIAL; } 682 | RAW { $$ = PT_RAW; } 683 | DIR { $$ = PT_DIR; } 684 | TYPE { $$ = PT_TYPE; } 685 | OPTIONS { $$ = PT_OPTIONS; } 686 | ZONENAME { $$ = PT_ZONENAME; } 687 | ZONEPATH { $$ = PT_ZONEPATH; } 688 | AUTOBOOT { $$ = PT_AUTOBOOT; } 689 | POOL { $$ = PT_POOL; } 690 | LIMITPRIV { $$ = PT_LIMITPRIV; } 691 | ADDRESS { $$ = PT_ADDRESS; } 692 | PHYSICAL { $$ = PT_PHYSICAL; } 693 | NAME { $$ = PT_NAME; } 694 | VALUE { $$ = PT_VALUE; } 695 | MATCH { $$ = PT_MATCH; } 696 | PRIV { $$ = PT_PRIV; } 697 | LIMIT { $$ = PT_LIMIT; } 698 | ACTION { $$ = PT_ACTION; } 699 700 /* 701 * The grammar builds data structures from the bottom up. Thus various 702 * strings are lexed into TOKENs or commands or resource or property values. 703 * Below is where the resource and property values are built up into more 704 * complex data structures. 705 * 706 * There are three kinds of properties: simple (single valued), complex 707 * (one or more name=value pairs) and list (concatenation of one or more 708 * simple or complex properties). 709 * 710 * So the property structure has a type which is one of these, and the 711 * corresponding _simple, _complex or _list is set to the corresponding 712 * lower-level data structure. 713 */ 714 715 property_value: simple_prop_val 716 { 717 property[num_prop_vals].pv_type = PROP_VAL_SIMPLE; 718 property[num_prop_vals].pv_simple = $1; 719 if (list[num_prop_vals] != NULL) { 720 free_outer_list(list[num_prop_vals]); 721 list[num_prop_vals] = NULL; 722 } 723 num_prop_vals++; 724 } 725 | complex_prop_val 726 { 727 property[num_prop_vals].pv_type = PROP_VAL_COMPLEX; 728 property[num_prop_vals].pv_complex = complex; 729 if (list[num_prop_vals] != NULL) { 730 free_outer_list(list[num_prop_vals]); 731 list[num_prop_vals] = NULL; 732 } 733 num_prop_vals++; 734 } 735 | list_prop_val 736 { 737 property[num_prop_vals].pv_type = PROP_VAL_LIST; 738 property[num_prop_vals].pv_list = list[num_prop_vals]; 739 num_prop_vals++; 740 } 741 742 /* 743 * One level lower, lists are made up of simple or complex values, so 744 * simple_prop_val and complex_prop_val fill in a list structure and 745 * insert it into the linked list which is built up. And because 746 * complex properties can have multiple name=value pairs, we keep 747 * track of them in another linked list. 748 * 749 * The complex and list structures for the linked lists are allocated 750 * below, and freed by recursive functions which are ultimately called 751 * by free_cmd(), which is called from the top-most "commands" part of 752 * the grammar. 753 */ 754 755 simple_prop_val: TOKEN 756 { 757 if ((new_list = alloc_list()) == NULL) 758 YYERROR; 759 new_list->lp_simple = $1; 760 new_list->lp_complex = NULL; 761 new_list->lp_next = NULL; 762 if (list[num_prop_vals] == NULL) { 763 list[num_prop_vals] = new_list; 764 } else { 765 for (tmp_list = list[num_prop_vals]; tmp_list != NULL; 766 tmp_list = tmp_list->lp_next) 767 last = tmp_list; 768 last->lp_next = new_list; 769 } 770 } 771 772 complex_prop_val: OPEN_PAREN complex_piece CLOSE_PAREN 773 { 774 if ((new_list = alloc_list()) == NULL) 775 YYERROR; 776 new_list->lp_simple = NULL; 777 new_list->lp_complex = complex; 778 new_list->lp_next = NULL; 779 if (list[num_prop_vals] == NULL) { 780 list[num_prop_vals] = new_list; 781 } else { 782 for (tmp_list = list[num_prop_vals]; tmp_list != NULL; 783 tmp_list = tmp_list->lp_next) 784 last = tmp_list; 785 last->lp_next = new_list; 786 } 787 } 788 789 complex_piece: property_name EQUAL TOKEN 790 { 791 if (($$ = alloc_complex()) == NULL) 792 YYERROR; 793 $$->cp_type = $1; 794 $$->cp_value = $3; 795 $$->cp_next = NULL; 796 complex = $$; 797 } 798 | property_name EQUAL TOKEN COMMA complex_piece 799 { 800 if (($$ = alloc_complex()) == NULL) 801 YYERROR; 802 $$->cp_type = $1; 803 $$->cp_value = $3; 804 $$->cp_next = complex; 805 complex = $$; 806 } 807 808 list_piece: simple_prop_val 809 | complex_prop_val 810 | simple_prop_val COMMA list_piece 811 | complex_prop_val COMMA list_piece 812 813 list_prop_val: OPEN_SQ_BRACKET list_piece CLOSE_SQ_BRACKET 814 %% 815