1/** 2 * @file yang.y 3 * @author Pavol Vican 4 * @brief YANG parser for libyang (bison grammar) 5 * 6 * Copyright (c) 2015 CESNET, z.s.p.o. 7 * 8 * This source code is licensed under BSD 3-Clause License (the "License"). 9 * You may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * https://opensource.org/licenses/BSD-3-Clause 13 */ 14 15%define api.pure full 16%locations 17 18%parse-param {void *scanner} 19%parse-param {struct yang_parameter *param} 20 21%lex-param {void *scanner} 22 23%{ 24#include <stdio.h> 25#include <stdarg.h> 26#include <string.h> 27#include <stdlib.h> 28#include "libyang.h" 29#include "common.h" 30#include "context.h" 31#include "resolve.h" 32#include "parser_yang.h" 33#include "parser_yang_lex.h" 34#include "parser.h" 35 36#define YANG_ADDELEM(current_ptr, size, array_name) \ 37 if ((size) == LY_ARRAY_MAX(size)) { \ 38 LOGERR(trg->ctx, LY_EINT, "Reached limit (%"PRIu64") for storing %s.", LY_ARRAY_MAX(size), array_name); \ 39 free(s); \ 40 YYABORT; \ 41 } else if (!((size) % LY_YANG_ARRAY_SIZE)) { \ 42 void *tmp; \ 43 \ 44 tmp = realloc((current_ptr), (sizeof *(current_ptr)) * ((size) + LY_YANG_ARRAY_SIZE)); \ 45 if (!tmp) { \ 46 LOGMEM(trg->ctx); \ 47 free(s); \ 48 YYABORT; \ 49 } \ 50 memset((char *)tmp + (sizeof *(current_ptr)) * (size), 0, (sizeof *(current_ptr)) * LY_YANG_ARRAY_SIZE); \ 51 (current_ptr) = tmp; \ 52 } \ 53 (size)++; \ 54 actual = &(current_ptr)[(size)-1]; \ 55 56void yyerror(YYLTYPE *yylloc, void *scanner, struct yang_parameter *param, ...); 57/* pointer on the current parsed element 'actual' */ 58%} 59 60%union { 61 int64_t i; 62 uint32_t uint; 63 char *str; 64 char **p_str; 65 void *v; 66 char ch; 67 struct yang_type *type; 68 struct lys_deviation *dev; 69 struct lys_deviate *deviate; 70 union { 71 uint32_t index; 72 struct lys_node_container *container; 73 struct lys_node_anydata *anydata; 74 struct type_node node; 75 struct lys_node_case *cs; 76 struct lys_node_grp *grouping; 77 struct lys_refine *refine; 78 struct lys_node_notif *notif; 79 struct lys_node_uses *uses; 80 struct lys_node_inout *inout; 81 struct lys_node_augment *augment; 82 } nodes; 83 enum yytokentype token; 84 struct { 85 void *actual; 86 enum yytokentype token; 87 } backup_token; 88 struct { 89 struct lys_revision **revision; 90 int index; 91 } revisions; 92} 93 94%token UNION_KEYWORD 95%token ANYXML_KEYWORD 96%token WHITESPACE 97%token ERROR 98%token EOL 99%token STRING 100%token STRINGS 101%token IDENTIFIER 102%token IDENTIFIERPREFIX 103%token REVISION_DATE 104%token TAB 105%token DOUBLEDOT 106%token URI 107%token INTEGER 108%token NON_NEGATIVE_INTEGER 109%token ZERO 110%token DECIMAL 111%token ARGUMENT_KEYWORD 112%token AUGMENT_KEYWORD 113%token BASE_KEYWORD 114%token BELONGS_TO_KEYWORD 115%token BIT_KEYWORD 116%token CASE_KEYWORD 117%token CHOICE_KEYWORD 118%token CONFIG_KEYWORD 119%token CONTACT_KEYWORD 120%token CONTAINER_KEYWORD 121%token DEFAULT_KEYWORD 122%token DESCRIPTION_KEYWORD 123%token ENUM_KEYWORD 124%token ERROR_APP_TAG_KEYWORD 125%token ERROR_MESSAGE_KEYWORD 126%token EXTENSION_KEYWORD 127%token DEVIATION_KEYWORD 128%token DEVIATE_KEYWORD 129%token FEATURE_KEYWORD 130%token FRACTION_DIGITS_KEYWORD 131%token GROUPING_KEYWORD 132%token IDENTITY_KEYWORD 133%token IF_FEATURE_KEYWORD 134%token IMPORT_KEYWORD 135%token INCLUDE_KEYWORD 136%token INPUT_KEYWORD 137%token KEY_KEYWORD 138%token LEAF_KEYWORD 139%token LEAF_LIST_KEYWORD 140%token LENGTH_KEYWORD 141%token LIST_KEYWORD 142%token MANDATORY_KEYWORD 143%token MAX_ELEMENTS_KEYWORD 144%token MIN_ELEMENTS_KEYWORD 145%token MODULE_KEYWORD 146%token MUST_KEYWORD 147%token NAMESPACE_KEYWORD 148%token NOTIFICATION_KEYWORD 149%token ORDERED_BY_KEYWORD 150%token ORGANIZATION_KEYWORD 151%token OUTPUT_KEYWORD 152%token PATH_KEYWORD 153%token PATTERN_KEYWORD 154%token POSITION_KEYWORD 155%token PREFIX_KEYWORD 156%token PRESENCE_KEYWORD 157%token RANGE_KEYWORD 158%token REFERENCE_KEYWORD 159%token REFINE_KEYWORD 160%token REQUIRE_INSTANCE_KEYWORD 161%token REVISION_KEYWORD 162%token REVISION_DATE_KEYWORD 163%token RPC_KEYWORD 164%token STATUS_KEYWORD 165%token SUBMODULE_KEYWORD 166%token TYPE_KEYWORD 167%token TYPEDEF_KEYWORD 168%token UNIQUE_KEYWORD 169%token UNITS_KEYWORD 170%token USES_KEYWORD 171%token VALUE_KEYWORD 172%token WHEN_KEYWORD 173%token YANG_VERSION_KEYWORD 174%token YIN_ELEMENT_KEYWORD 175%token ADD_KEYWORD 176%token CURRENT_KEYWORD 177%token DELETE_KEYWORD 178%token DEPRECATED_KEYWORD 179%token FALSE_KEYWORD 180%token NOT_SUPPORTED_KEYWORD 181%token OBSOLETE_KEYWORD 182%token REPLACE_KEYWORD 183%token SYSTEM_KEYWORD 184%token TRUE_KEYWORD 185%token UNBOUNDED_KEYWORD 186%token USER_KEYWORD 187%token ACTION_KEYWORD 188%token MODIFIER_KEYWORD 189%token ANYDATA_KEYWORD 190%token NODE 191%token NODE_PRINT 192%token EXTENSION_INSTANCE 193%token SUBMODULE_EXT_KEYWORD 194 195%type <uint> positive_integer_value 196%type <uint> non_negative_integer_value 197%type <uint> max_value_arg_str 198%type <uint> max_value_arg 199%type <uint> max_elements_stmt 200%type <uint> min_value_arg_str 201%type <uint> min_value_arg 202%type <uint> min_elements_stmt 203%type <uint> fraction_digits_arg_str 204%type <uint> fraction_digits_arg 205%type <uint> position_value_arg_str 206%type <uint> position_value_arg 207%type <uint> yin_element_arg_str 208%type <uint> yin_element_arg 209%type <uint> fraction_digits_stmt 210%type <uint> position_stmt 211%type <i> value_stmt 212%type <i> require_instance_stmt 213%type <i> require_instance_arg_str 214%type <i> require_instance_arg 215%type <i> import_opt_stmt 216%type <i> include_opt_stmt 217%type <i> module_header_stmt 218%type <i> submodule_header_stmt 219%type <str> message_opt_stmt 220%type <i> status_stmt 221%type <i> status_arg_str 222%type <i> status_arg 223%type <i> config_stmt 224%type <i> config_arg_str 225%type <i> config_arg 226%type <i> mandatory_stmt 227%type <i> mandatory_arg_str 228%type <i> mandatory_arg 229%type <i> ordered_by_stmt 230%type <i> ordered_by_arg_str 231%type <i> ordered_by_arg 232%type <i> integer_value_arg_str 233%type <i> value_arg 234%type <i> integer_value 235%type <i> ext_substatements 236%type <str> pattern_arg_str 237%type <nodes> container_opt_stmt 238%type <nodes> anyxml_opt_stmt 239%type <nodes> choice_opt_stmt 240%type <nodes> case_opt_stmt 241%type <nodes> grouping_opt_stmt 242%type <nodes> leaf_opt_stmt 243%type <nodes> leaf_list_opt_stmt 244%type <nodes> list_opt_stmt 245%type <nodes> type_opt_stmt 246%type <nodes> uses_opt_stmt 247%type <nodes> refine_body_opt_stmts 248%type <nodes> augment_opt_stmt 249%type <nodes> rpc_opt_stmt 250%type <nodes> notification_opt_stmt 251%type <dev> deviation_opt_stmt 252%type <deviate> deviate_add_opt_stmt 253%type <deviate> deviate_delete_opt_stmt 254%type <deviate> deviate_replace_opt_stmt 255%type <ch> pattern_opt_stmt 256%type <ch> pattern_end 257%type <ch> modifier_stmt 258%type <p_str> tmp_string 259%type <str> string_opt_part1 260%type <str> semicolom 261%type <str> curly_bracket_open 262%type <str> unknown_statement2_yang_stmt 263%type <str> unknown_statement2_module_stmt 264%type <v> type_ext_alloc 265%type <v> typedef_ext_alloc 266%type <v> iffeature_ext_alloc 267%type <v> restriction_ext_alloc 268%type <v> when_ext_alloc 269%type <revisions> revision_ext_alloc 270%type <token> import_arg_str 271%type <token> include_arg_str 272%type <token> argument_str 273%type <token> belongs_to_arg_str 274%type <backup_token> revision_arg_stmt 275%type <backup_token> grouping_arg_str 276%type <backup_token> container_arg_str 277%type <backup_token> leaf_arg_str 278%type <backup_token> leaf_list_arg_str 279%type <backup_token> list_arg_str 280%type <backup_token> choice_arg_str 281%type <backup_token> case_arg_str 282%type <backup_token> anyxml_arg_str 283%type <backup_token> anydata_arg_str 284%type <backup_token> uses_arg_str 285%type <backup_token> uses_augment_arg 286%type <backup_token> augment_arg 287%type <backup_token> action_arg_str 288%type <backup_token> rpc_arg_str 289%type <backup_token> input_arg 290%type <backup_token> output_arg 291%type <backup_token> notification_arg_str 292%type <backup_token> extension_arg_str 293%type <backup_token> feature_arg_str 294%type <backup_token> identity_arg_str 295%type <backup_token> if_feature_arg 296%type <backup_token> typedef_arg_str 297%type <backup_token> type_arg_str 298%type <backup_token> length_arg_str 299%type <backup_token> pattern_sep 300%type <backup_token> range_arg_str 301%type <backup_token> union_spec 302%type <backup_token> enum_arg_str 303%type <backup_token> bit_arg_str 304%type <backup_token> when_arg_str 305%type <backup_token> must_agr_str 306%type <backup_token> refine_arg_str 307%type <backup_token> deviation_arg 308%type <backup_token> deviate_not_supported 309%type <backup_token> deviate_add 310%type <backup_token> deviate_delete 311%type <backup_token> deviate_replace 312%type <backup_token> string_opt 313 314%destructor { free($$); } pattern_arg_str string_opt_part1 semicolom curly_bracket_open 315%destructor { free(($$) ? *$$ : NULL); } tmp_string 316%destructor { yang_type_free(param->module->ctx, $$); } type_ext_alloc 317%destructor { yang_type_free(param->module->ctx, &((struct lys_tpdf *)$$)->type); } typedef_ext_alloc 318 319%initial-action { yylloc.last_column = 0; 320 if (param->flags & EXT_INSTANCE_SUBSTMT) { 321 is_ext_instance = 1; 322 ext_instance = (struct lys_ext_instance_complex *)param->actual_node; 323 ext_name = (char *)param->data_node; 324 } else { 325 is_ext_instance = 0; 326 } 327 yylloc.last_line = is_ext_instance; /* HACK for flex - return SUBMODULE_KEYWORD or SUBMODULE_EXT_KEYWORD */ 328 param->value = &s; 329 param->data_node = (void **)&data_node; 330 param->actual_node = &actual; 331 backup_type = NODE; 332 trg = (param->submodule) ? (struct lys_module *)param->submodule : param->module; 333 } 334 335%% 336 337/* to simplify code, store the module/submodule being processed as trg */ 338 339start: module_stmt 340 | submodule_stmt 341 | ext_substatements 342 343tmp_string: STRING { if (yyget_text(scanner)[0] == '"') { 344 char *tmp; 345 346 s = malloc(yyget_leng(scanner) - 1 + 7 * yylval.i); 347 if (!s) { 348 LOGMEM(trg->ctx); 349 YYABORT; 350 } 351 if (!(tmp = yang_read_string(trg->ctx, yyget_text(scanner) + 1, s, yyget_leng(scanner) - 2, 0, yylloc.first_column))) { 352 YYABORT; 353 } 354 s = tmp; 355 } else { 356 s = calloc(1, yyget_leng(scanner) - 1); 357 if (!s) { 358 LOGMEM(trg->ctx); 359 YYABORT; 360 } 361 memcpy(s, yyget_text(scanner) + 1, yyget_leng(scanner) - 2); 362 } 363 $$ = &s; 364 } 365 366string_1: tmp_string optsep string_2 367 368 369string_2: @EMPTYDIR@ 370 | string_2 '+' optsep 371 STRING { if (yyget_leng(scanner) > 2) { 372 int length_s = strlen(s), length_tmp = yyget_leng(scanner); 373 char *tmp; 374 375 tmp = realloc(s, length_s + length_tmp - 1); 376 if (!tmp) { 377 LOGMEM(trg->ctx); 378 YYABORT; 379 } 380 s = tmp; 381 if (yyget_text(scanner)[0] == '"') { 382 if (!(tmp = yang_read_string(trg->ctx, yyget_text(scanner) + 1, s, length_tmp - 2, length_s, yylloc.first_column))) { 383 YYABORT; 384 } 385 s = tmp; 386 } else { 387 memcpy(s + length_s, yyget_text(scanner) + 1, length_tmp - 2); 388 s[length_s + length_tmp - 2] = '\0'; 389 } 390 } 391 } 392 optsep; 393 394module_arg_str: identifier_arg_str { if (param->submodule) { 395 free(s); 396 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "module"); 397 YYABORT; 398 } 399 trg = param->module; 400 if (yang_read_common(trg,s,MODULE_KEYWORD)) { 401 YYABORT; 402 } 403 s = NULL; 404 actual_type = MODULE_KEYWORD; 405 } 406 407module_stmt: optsep MODULE_KEYWORD sep module_arg_str 408 '{' stmtsep 409 module_header_stmts 410 linkage_stmts 411 meta_stmts 412 revision_stmts 413 body_stmts_end 414 '}' optsep 415 416 417module_header_stmts: module_header_stmt { if (!param->module->ns) { 418 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "namespace", "module"); 419 YYABORT; 420 } 421 if (!param->module->prefix) { 422 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "prefix", "module"); 423 YYABORT; 424 } 425 } 426 427module_header_stmt: @EMPTYDIR@ { $$ = 0; } 428 | module_header_stmt yang_version_stmt { if (yang_check_version(param->module, param->submodule, s, $1)) { 429 YYABORT; 430 } 431 $$ = 1; 432 s = NULL; 433 } 434 | module_header_stmt namespace_stmt { if (yang_read_common(param->module, s, NAMESPACE_KEYWORD)) { 435 YYABORT; 436 } 437 s = NULL; 438 } 439 | module_header_stmt prefix_stmt { if (yang_read_prefix(trg, NULL, s)) { 440 YYABORT; 441 } 442 s = NULL; 443 } 444 445submodule_arg_str: identifier_arg_str { if (!param->submodule) { 446 free(s); 447 LOGVAL(trg->ctx, LYE_SUBMODULE, LY_VLOG_NONE, NULL); 448 YYABORT; 449 } 450 trg = (struct lys_module *)param->submodule; 451 if (yang_read_common(trg,s,MODULE_KEYWORD)) { 452 YYABORT; 453 } 454 s = NULL; 455 actual_type = SUBMODULE_KEYWORD; 456 } 457 458submodule_stmt: optsep SUBMODULE_KEYWORD sep submodule_arg_str 459 '{' stmtsep 460 submodule_header_stmts 461 linkage_stmts 462 meta_stmts 463 revision_stmts 464 body_stmts_end 465 '}' optsep 466 467 468submodule_header_stmts: submodule_header_stmt { if (!param->submodule->prefix) { 469 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "belongs-to", "submodule"); 470 YYABORT; 471 } 472 if (!$1) { 473 /* check version compatibility with the main module */ 474 if (param->module->version > 1) { 475 LOGVAL(trg->ctx, LYE_INVER, LY_VLOG_NONE, NULL); 476 YYABORT; 477 } 478 } 479 } 480 481submodule_header_stmt: @EMPTYDIR@ { $$ = 0; } 482 | submodule_header_stmt yang_version_stmt { if (yang_check_version(param->module, param->submodule, s, $1)) { 483 YYABORT; 484 } 485 $$ = 1; 486 s = NULL; 487 } 488 | submodule_header_stmt belongs_to_stmt stmtsep 489 490yang_version_arg: string { backup_type = actual_type; 491 actual_type = YANG_VERSION_KEYWORD; 492 } 493 494yang_version_stmt: YANG_VERSION_KEYWORD sep yang_version_arg stmtend 495 496namespace_arg_str: string { backup_type = actual_type; 497 actual_type = NAMESPACE_KEYWORD; 498 } 499 500namespace_stmt: NAMESPACE_KEYWORD sep namespace_arg_str stmtend 501 502linkage_stmts: @EMPTYDIR@ 503 | linkage_stmts import_stmt stmtsep 504 | linkage_stmts include_stmt stmtsep 505 506import_stmt: IMPORT_KEYWORD sep import_arg_str 507 '{' stmtsep 508 import_opt_stmt 509 '}' { actual_type = $3; 510 backup_type = NODE; 511 actual = NULL; 512 } 513 514import_arg_str: identifier_arg_str { YANG_ADDELEM(trg->imp, trg->imp_size, "imports"); 515 /* HACK for unres */ 516 ((struct lys_import *)actual)->module = (struct lys_module *)s; 517 s = NULL; 518 $$ = actual_type; 519 actual_type = IMPORT_KEYWORD; 520 } 521 522import_opt_stmt: @EMPTYDIR@ { $$ = 0; } 523 | import_opt_stmt prefix_stmt { if (yang_read_prefix(trg, actual, s)) { 524 YYABORT; 525 } 526 s = NULL; 527 } 528 | import_opt_stmt description_stmt { if (trg->version != 2) { 529 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "description"); 530 free(s); 531 YYABORT; 532 } 533 if (yang_read_description(trg, actual, s, "import", IMPORT_KEYWORD)) { 534 YYABORT; 535 } 536 s = NULL; 537 $$ = $1; 538 } 539 | import_opt_stmt reference_stmt { if (trg->version != 2) { 540 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "reference"); 541 free(s); 542 YYABORT; 543 } 544 if (yang_read_reference(trg, actual, s, "import", IMPORT_KEYWORD)) { 545 YYABORT; 546 } 547 s = NULL; 548 $$ = $1; 549 } 550 | import_opt_stmt revision_date_stmt { if ($1) { 551 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "revision-date", "import"); 552 free(s); 553 YYABORT; 554 } 555 memcpy(((struct lys_import *)actual)->rev, s, LY_REV_SIZE-1); 556 free(s); 557 s = NULL; 558 $$ = 1; 559 } 560 561include_arg_str: identifier_arg_str { YANG_ADDELEM(trg->inc, trg->inc_size, "includes"); 562 /* HACK for unres */ 563 ((struct lys_include *)actual)->submodule = (struct lys_submodule *)s; 564 s = NULL; 565 $$ = actual_type; 566 actual_type = INCLUDE_KEYWORD; 567 } 568 569include_stmt: INCLUDE_KEYWORD sep include_arg_str include_end { actual_type = $3; 570 backup_type = NODE; 571 actual = NULL; 572 } 573 574include_end: ';' 575 | '{' stmtsep 576 include_opt_stmt 577 '}' 578 579include_opt_stmt: @EMPTYDIR@ { $$ = 0; } 580 | include_opt_stmt description_stmt { if (trg->version != 2) { 581 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "description"); 582 free(s); 583 YYABORT; 584 } 585 if (yang_read_description(trg, actual, s, "include", INCLUDE_KEYWORD)) { 586 YYABORT; 587 } 588 s = NULL; 589 $$ = $1; 590 } 591 | include_opt_stmt reference_stmt { if (trg->version != 2) { 592 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "reference"); 593 free(s); 594 YYABORT; 595 } 596 if (yang_read_reference(trg, actual, s, "include", INCLUDE_KEYWORD)) { 597 YYABORT; 598 } 599 s = NULL; 600 $$ = $1; 601 } 602 | include_opt_stmt revision_date_stmt { if ($1) { 603 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "revision-date", "include"); 604 free(s); 605 YYABORT; 606 } 607 memcpy(((struct lys_include *)actual)->rev, s, LY_REV_SIZE-1); 608 free(s); 609 s = NULL; 610 $$ = 1; 611 } 612 613revision_date_arg: date_arg_str { backup_type = actual_type; 614 actual_type = REVISION_DATE_KEYWORD; 615 } 616 617revision_date_stmt: REVISION_DATE_KEYWORD sep revision_date_arg stmtend 618 619belongs_to_arg_str: identifier_arg_str { $$ = actual_type; 620 if (is_ext_instance) { 621 if (yang_read_extcomplex_str(trg, ext_instance, "belongs-to", ext_name, &s, 622 0, LY_STMT_BELONGSTO)) { 623 YYABORT; 624 } 625 } else { 626 if (param->submodule->prefix) { 627 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "belongs-to", "submodule"); 628 free(s); 629 YYABORT; 630 } 631 if (!ly_strequal(s, param->submodule->belongsto->name, 0)) { 632 LOGVAL(trg->ctx, LYE_INARG, LY_VLOG_NONE, NULL, s, "belongs-to"); 633 free(s); 634 YYABORT; 635 } 636 free(s); 637 } 638 s = NULL; 639 actual_type = BELONGS_TO_KEYWORD; 640 } 641 642belongs_to_stmt: BELONGS_TO_KEYWORD sep belongs_to_arg_str 643 '{' stmtsep 644 prefix_stmt 645 '}' { if (is_ext_instance) { 646 if (yang_read_extcomplex_str(trg, ext_instance, "prefix", "belongs-to", &s, 647 LY_STMT_BELONGSTO, LY_STMT_PREFIX)) { 648 YYABORT; 649 } 650 } else { 651 if (yang_read_prefix(trg, NULL, s)) { 652 YYABORT; 653 } 654 } 655 s = NULL; 656 actual_type = $3; 657 } 658 659prefix_arg: prefix_arg_str { backup_type = actual_type; 660 actual_type = PREFIX_KEYWORD; 661 } 662 663prefix_stmt: PREFIX_KEYWORD sep prefix_arg stmtend 664 665meta_stmts: @EMPTYDIR@ 666 | meta_stmts organization_stmt { if (yang_read_common(trg, s, ORGANIZATION_KEYWORD)) { 667 YYABORT; 668 } 669 s = NULL; 670 } 671 | meta_stmts contact_stmt { if (yang_read_common(trg, s, CONTACT_KEYWORD)) { 672 YYABORT; 673 } 674 s = NULL; 675 } 676 | meta_stmts description_stmt { if (yang_read_description(trg, NULL, s, NULL, MODULE_KEYWORD)) { 677 YYABORT; 678 } 679 s = NULL; 680 } 681 | meta_stmts reference_stmt { if (yang_read_reference(trg, NULL, s, NULL, MODULE_KEYWORD)) { 682 YYABORT; 683 } 684 s=NULL; 685 } 686 687organization_arg: string { backup_type = actual_type; 688 actual_type = ORGANIZATION_KEYWORD; 689 } 690 691organization_stmt: ORGANIZATION_KEYWORD sep organization_arg stmtend 692 693contact_arg: string { backup_type = actual_type; 694 actual_type = CONTACT_KEYWORD; 695 } 696 697contact_stmt: CONTACT_KEYWORD sep contact_arg stmtend 698 699description_arg: string { backup_type = actual_type; 700 actual_type = DESCRIPTION_KEYWORD; 701 } 702 703description_stmt: DESCRIPTION_KEYWORD sep description_arg stmtend 704 705reference_arg: string { backup_type = actual_type; 706 actual_type = REFERENCE_KEYWORD; 707 } 708 709reference_stmt: REFERENCE_KEYWORD sep reference_arg stmtend 710 711revision_stmts: revision_stmts_opt { if (trg->rev_size) { 712 struct lys_revision *tmp; 713 714 tmp = realloc(trg->rev, trg->rev_size * sizeof *trg->rev); 715 if (!tmp) { 716 LOGMEM(trg->ctx); 717 YYABORT; 718 } 719 trg->rev = tmp; 720 } 721 } 722 723 724revision_arg_stmt: date_arg_str { $$.token = actual_type; 725 $$.actual = actual; 726 if (!is_ext_instance) { 727 YANG_ADDELEM(trg->rev, trg->rev_size, "revisions"); 728 } 729 memcpy(((struct lys_revision *)actual)->date, s, LY_REV_SIZE); 730 free(s); 731 s = NULL; 732 actual_type = REVISION_KEYWORD; 733 } 734 735revision_stmts_opt: @EMPTYDIR@ 736 | revision_stmts_opt revision_stmt stmtsep { int i; 737 738 /* check uniqueness of the revision date - not required by RFC */ 739 for (i = 0; i < (trg->rev_size - 1); i++) { 740 if (!strcmp(trg->rev[i].date, trg->rev[trg->rev_size - 1].date)) { 741 LOGWRN(trg->ctx, "Module's revisions are not unique (%s).", 742 trg->rev[trg->rev_size - 1].date); 743 break; 744 } 745 } 746 } 747 748revision_stmt: REVISION_KEYWORD sep revision_arg_stmt revision_end { actual_type = $3.token; 749 actual = $3.actual; 750 } 751 752revision_end: ';' 753 | '{' stmtsep 754 revision_opt_stmt 755 '}' 756 757revision_opt_stmt: @EMPTYDIR@ 758 | revision_opt_stmt description_stmt { if (yang_read_description(trg, actual, s, "revision",REVISION_KEYWORD)) { 759 YYABORT; 760 } 761 s = NULL; 762 } 763 | revision_opt_stmt reference_stmt { if (yang_read_reference(trg, actual, s, "revision", REVISION_KEYWORD)) { 764 YYABORT; 765 } 766 s = NULL; 767 } 768 ; 769 770date_arg_str: REVISION_DATE { s = strdup(yyget_text(scanner)); 771 if (!s) { 772 LOGMEM(trg->ctx); 773 YYABORT; 774 } 775 if (lyp_check_date(trg->ctx, s)) { 776 free(s); 777 YYABORT; 778 } 779 } 780 optsep 781 | string_1 { if (lyp_check_date(trg->ctx, s)) { 782 free(s); 783 YYABORT; 784 } 785 } 786 787body_stmts_end: body_stmts { void *tmp; 788 789 if (trg->tpdf_size) { 790 tmp = realloc(trg->tpdf, trg->tpdf_size * sizeof *trg->tpdf); 791 if (!tmp) { 792 LOGMEM(trg->ctx); 793 YYABORT; 794 } 795 trg->tpdf = tmp; 796 } 797 798 if (trg->features_size) { 799 tmp = realloc(trg->features, trg->features_size * sizeof *trg->features); 800 if (!tmp) { 801 LOGMEM(trg->ctx); 802 YYABORT; 803 } 804 trg->features = tmp; 805 } 806 807 if (trg->ident_size) { 808 tmp = realloc(trg->ident, trg->ident_size * sizeof *trg->ident); 809 if (!tmp) { 810 LOGMEM(trg->ctx); 811 YYABORT; 812 } 813 trg->ident = tmp; 814 } 815 816 if (trg->augment_size) { 817 tmp = realloc(trg->augment, trg->augment_size * sizeof *trg->augment); 818 if (!tmp) { 819 LOGMEM(trg->ctx); 820 YYABORT; 821 } 822 trg->augment = tmp; 823 } 824 825 if (trg->extensions_size) { 826 tmp = realloc(trg->extensions, trg->extensions_size * sizeof *trg->extensions); 827 if (!tmp) { 828 LOGMEM(trg->ctx); 829 YYABORT; 830 } 831 trg->extensions = tmp; 832 } 833 } 834 835body_stmts: @EMPTYDIR@ { /* check the module with respect to the context now */ 836 if (!param->submodule) { 837 switch (lyp_ctx_check_module(trg)) { 838 case -1: 839 YYABORT; 840 case 0: 841 break; 842 case 1: 843 /* it's already there */ 844 param->flags |= YANG_EXIST_MODULE; 845 YYABORT; 846 } 847 } 848 param->flags &= (~YANG_REMOVE_IMPORT); 849 if (yang_check_imports(trg, param->unres)) { 850 YYABORT; 851 } 852 actual = NULL; 853 } 854 | body_stmts body_stmt stmtsep { actual = NULL; } 855 856 857body_stmt: extension_stmt 858 | feature_stmt 859 | identity_stmt 860 | typedef_stmt 861 | grouping_stmt 862 | data_def_stmt 863 | augment_stmt 864 | rpc_stmt 865 | notification_stmt 866 | deviation_stmt 867 868 869extension_arg_str: identifier_arg_str { $$.token = actual_type; 870 $$.actual = actual; 871 YANG_ADDELEM(trg->extensions, trg->extensions_size, "extensions"); 872 trg->extensions_size--; 873 ((struct lys_ext *)actual)->name = lydict_insert_zc(param->module->ctx, s); 874 ((struct lys_ext *)actual)->module = trg; 875 if (lyp_check_identifier(trg->ctx, ((struct lys_ext *)actual)->name, LY_IDENT_EXTENSION, trg, NULL)) { 876 trg->extensions_size++; 877 YYABORT; 878 } 879 trg->extensions_size++; 880 s = NULL; 881 actual_type = EXTENSION_KEYWORD; 882 } 883 884extension_stmt: EXTENSION_KEYWORD sep extension_arg_str extension_end 885 { struct lys_ext *ext = actual; 886 ext->plugin = ext_get_plugin(ext->name, ext->module->name, ext->module->rev ? ext->module->rev[0].date : NULL); 887 actual_type = $3.token; 888 actual = $3.actual; 889 } 890 891extension_end: ';' 892 | '{' stmtsep 893 extension_opt_stmt 894 '}' 895 896extension_opt_stmt: @EMPTYDIR@ 897 | extension_opt_stmt argument_stmt stmtsep 898 | extension_opt_stmt status_stmt { if (((struct lys_ext *)actual)->flags & LYS_STATUS_MASK) { 899 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "status", "extension"); 900 YYABORT; 901 } 902 ((struct lys_ext *)actual)->flags |= $2; 903 } 904 | extension_opt_stmt description_stmt { if (yang_read_description(trg, actual, s, "extension", NODE)) { 905 YYABORT; 906 } 907 s = NULL; 908 } 909 | extension_opt_stmt reference_stmt { if (yang_read_reference(trg, actual, s, "extension", NODE)) { 910 YYABORT; 911 } 912 s = NULL; 913 } 914 915argument_str: identifier_arg_str { $$ = actual_type; 916 if (is_ext_instance) { 917 if (yang_read_extcomplex_str(trg, ext_instance, "argument", ext_name, &s, 918 0, LY_STMT_ARGUMENT)) { 919 YYABORT; 920 } 921 } else { 922 if (((struct lys_ext *)actual)->argument) { 923 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "argument", "extension"); 924 free(s); 925 YYABORT; 926 } 927 ((struct lys_ext *)actual)->argument = lydict_insert_zc(param->module->ctx, s); 928 } 929 s = NULL; 930 actual_type = ARGUMENT_KEYWORD; 931 } 932 933argument_stmt: ARGUMENT_KEYWORD sep argument_str argument_end { actual_type = $3; } 934 935argument_end: ';' 936 | '{' stmtsep 937 yin_element_stmt 938 '}' 939 940yin_element_arg: yin_element_arg_str { $$ = $1; 941 backup_type = actual_type; 942 actual_type = YIN_ELEMENT_KEYWORD; 943 } 944 945yin_element_stmt: @EMPTYDIR@ 946 | YIN_ELEMENT_KEYWORD sep yin_element_arg stmtend 947 { if (is_ext_instance) { 948 int c; 949 const char ***p; 950 uint8_t *val; 951 struct lyext_substmt *info; 952 953 c = 0; 954 p = lys_ext_complex_get_substmt(LY_STMT_ARGUMENT, ext_instance, &info); 955 if (info->cardinality >= LY_STMT_CARD_SOME) { 956 /* get the index in the array to add new item */ 957 for (c = 0; p[0][c + 1]; c++); 958 val = (uint8_t *)p[1]; 959 } else { 960 val = (uint8_t *)(p + 1); 961 } 962 val[c] = ($3 == LYS_YINELEM) ? 1 : 2; 963 } else { 964 ((struct lys_ext *)actual)->flags |= $3; 965 } 966 } 967 968yin_element_arg_str: TRUE_KEYWORD optsep { $$ = LYS_YINELEM; } 969 | FALSE_KEYWORD optsep { $$ = 0; } 970 | string_1 { if (!strcmp(s, "true")) { 971 $$ = LYS_YINELEM; 972 } else if (!strcmp(s, "false")) { 973 $$ = 0; 974 } else { 975 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, s); 976 free(s); 977 YYABORT; 978 } 979 free(s); 980 s = NULL; 981 } 982 983status_arg: status_arg_str { $$ = $1; 984 backup_type = actual_type; 985 actual_type = STATUS_KEYWORD; 986 } 987 988status_stmt: STATUS_KEYWORD sep status_arg stmtend { $$ = $3; } 989 990status_arg_str: CURRENT_KEYWORD optsep { $$ = LYS_STATUS_CURR; } 991 | OBSOLETE_KEYWORD optsep { $$ = LYS_STATUS_OBSLT; } 992 | DEPRECATED_KEYWORD optsep { $$ = LYS_STATUS_DEPRC; } 993 | string_1 { if (!strcmp(s, "current")) { 994 $$ = LYS_STATUS_CURR; 995 } else if (!strcmp(s, "obsolete")) { 996 $$ = LYS_STATUS_OBSLT; 997 } else if (!strcmp(s, "deprecated")) { 998 $$ = LYS_STATUS_DEPRC; 999 } else { 1000 LOGVAL(trg->ctx,LYE_INSTMT, LY_VLOG_NONE, NULL, s); 1001 free(s); 1002 YYABORT; 1003 } 1004 free(s); 1005 s = NULL; 1006 } 1007 1008feature_arg_str: identifier_arg_str { /* check uniqueness of feature's names */ 1009 if (lyp_check_identifier(trg->ctx, s, LY_IDENT_FEATURE, trg, NULL)) { 1010 free(s); 1011 YYABORT; 1012 } 1013 $$.token = actual_type; 1014 $$.actual = actual; 1015 YANG_ADDELEM(trg->features, trg->features_size, "features"); 1016 ((struct lys_feature *)actual)->name = lydict_insert_zc(trg->ctx, s); 1017 ((struct lys_feature *)actual)->module = trg; 1018 s = NULL; 1019 actual_type = FEATURE_KEYWORD; 1020 } 1021 1022feature_stmt: FEATURE_KEYWORD sep feature_arg_str feature_end 1023 { actual = $3.actual; 1024 actual_type = $3.token; 1025 } 1026 1027feature_end: ';' 1028 | '{' stmtsep 1029 feature_opt_stmt 1030 '}' { struct lys_iffeature *tmp; 1031 1032 if (((struct lys_feature *)actual)->iffeature_size) { 1033 tmp = realloc(((struct lys_feature *)actual)->iffeature, 1034 ((struct lys_feature *)actual)->iffeature_size * sizeof *tmp); 1035 if (!tmp) { 1036 LOGMEM(trg->ctx); 1037 YYABORT; 1038 } 1039 ((struct lys_feature *)actual)->iffeature = tmp; 1040 } 1041 } 1042 1043feature_opt_stmt: @EMPTYDIR@ 1044 | feature_opt_stmt if_feature_stmt stmtsep 1045 | feature_opt_stmt status_stmt { if (((struct lys_feature *)actual)->flags & LYS_STATUS_MASK) { 1046 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "status", "feature"); 1047 YYABORT; 1048 } 1049 ((struct lys_feature *)actual)->flags |= $2; 1050 } 1051 | feature_opt_stmt description_stmt { if (yang_read_description(trg, actual, s, "feature", NODE)) { 1052 YYABORT; 1053 } 1054 s = NULL; 1055 } 1056 | feature_opt_stmt reference_stmt { if (yang_read_reference(trg, actual, s, "feature", NODE)) { 1057 YYABORT; 1058 } 1059 s = NULL; 1060 } 1061 1062if_feature_arg: string { $$.token = actual_type; 1063 $$.actual = actual; 1064 switch (actual_type) { 1065 case FEATURE_KEYWORD: 1066 YANG_ADDELEM(((struct lys_feature *)actual)->iffeature, 1067 ((struct lys_feature *)actual)->iffeature_size, "if-features"); 1068 break; 1069 case IDENTITY_KEYWORD: 1070 if (trg->version < 2) { 1071 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "if-feature", "identity"); 1072 free(s); 1073 YYABORT; 1074 } 1075 YANG_ADDELEM(((struct lys_ident *)actual)->iffeature, 1076 ((struct lys_ident *)actual)->iffeature_size, "if-features"); 1077 break; 1078 case ENUM_KEYWORD: 1079 if (trg->version < 2) { 1080 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "if-feature"); 1081 free(s); 1082 YYABORT; 1083 } 1084 YANG_ADDELEM(((struct lys_type_enum *)actual)->iffeature, 1085 ((struct lys_type_enum *)actual)->iffeature_size, "if-features"); 1086 break; 1087 case BIT_KEYWORD: 1088 if (trg->version < 2) { 1089 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "if-feature", "bit"); 1090 free(s); 1091 YYABORT; 1092 } 1093 YANG_ADDELEM(((struct lys_type_bit *)actual)->iffeature, 1094 ((struct lys_type_bit *)actual)->iffeature_size, "if-features"); 1095 break; 1096 case REFINE_KEYWORD: 1097 if (trg->version < 2) { 1098 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "if-feature"); 1099 free(s); 1100 YYABORT; 1101 } 1102 YANG_ADDELEM(((struct lys_refine *)actual)->iffeature, 1103 ((struct lys_refine *)actual)->iffeature_size, "if-features"); 1104 break; 1105 case EXTENSION_INSTANCE: 1106 /* nothing change */ 1107 break; 1108 default: 1109 /* lys_node_* */ 1110 YANG_ADDELEM(((struct lys_node *)actual)->iffeature, 1111 ((struct lys_node *)actual)->iffeature_size, "if-features"); 1112 break; 1113 } 1114 ((struct lys_iffeature *)actual)->features = (struct lys_feature **)s; 1115 s = NULL; 1116 actual_type = IF_FEATURE_KEYWORD; 1117 } 1118 1119if_feature_stmt: IF_FEATURE_KEYWORD sep if_feature_arg if_feature_end 1120 { actual = $3.actual; 1121 actual_type = $3.token; 1122 } 1123 1124if_feature_end: ';' 1125 | '{' stmtsep '}' 1126 1127identity_arg_str: identifier_arg_str { const char *tmp; 1128 1129 tmp = lydict_insert_zc(trg->ctx, s); 1130 s = NULL; 1131 if (dup_identities_check(tmp, trg)) { 1132 lydict_remove(trg->ctx, tmp); 1133 YYABORT; 1134 } 1135 $$.token = actual_type; 1136 $$.actual = actual; 1137 YANG_ADDELEM(trg->ident, trg->ident_size, "identities"); 1138 ((struct lys_ident *)actual)->name = tmp; 1139 ((struct lys_ident *)actual)->module = trg; 1140 actual_type = IDENTITY_KEYWORD; 1141 } 1142 1143identity_stmt: IDENTITY_KEYWORD sep identity_arg_str identity_end 1144 { actual = $3.actual; 1145 actual_type = $3.token; 1146 } 1147 1148identity_end: ';' 1149 | '{' stmtsep 1150 identity_opt_stmt 1151 '}' { void *tmp; 1152 1153 if (((struct lys_ident *)actual)->base_size) { 1154 tmp = realloc(((struct lys_ident *)actual)->base, 1155 ((struct lys_ident *)actual)->base_size * sizeof *((struct lys_ident *)actual)->base); 1156 if (!tmp) { 1157 LOGMEM(trg->ctx); 1158 YYABORT; 1159 } 1160 ((struct lys_ident *)actual)->base = tmp; 1161 } 1162 1163 if (((struct lys_ident *)actual)->iffeature_size) { 1164 tmp = realloc(((struct lys_ident *)actual)->iffeature, 1165 ((struct lys_ident *)actual)->iffeature_size * sizeof *((struct lys_ident *)actual)->iffeature); 1166 if (!tmp) { 1167 LOGMEM(trg->ctx); 1168 YYABORT; 1169 } 1170 ((struct lys_ident *)actual)->iffeature = tmp; 1171 } 1172 } 1173 1174identity_opt_stmt: @EMPTYDIR@ 1175 | identity_opt_stmt base_stmt { void *identity; 1176 1177 if ((trg->version < 2) && ((struct lys_ident *)actual)->base_size) { 1178 free(s); 1179 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "base", "identity"); 1180 YYABORT; 1181 } 1182 identity = actual; 1183 YANG_ADDELEM(((struct lys_ident *)actual)->base, 1184 ((struct lys_ident *)actual)->base_size, "bases"); 1185 *((struct lys_ident **)actual) = (struct lys_ident *)s; 1186 s = NULL; 1187 actual = identity; 1188 } 1189 | identity_opt_stmt if_feature_stmt stmtsep 1190 | identity_opt_stmt status_stmt { if (((struct lys_ident *)actual)->flags & LYS_STATUS_MASK) { 1191 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "status", "identity"); 1192 YYABORT; 1193 } 1194 ((struct lys_ident *)actual)->flags |= $2; 1195 } 1196 | identity_opt_stmt description_stmt { if (yang_read_description(trg, actual, s, "identity", NODE)) { 1197 YYABORT; 1198 } 1199 s = NULL; 1200 } 1201 | identity_opt_stmt reference_stmt { if (yang_read_reference(trg, actual, s, "identity", NODE)) { 1202 YYABORT; 1203 } 1204 s = NULL; 1205 } 1206 1207base_arg: identifier_ref_arg_str { backup_type = actual_type; 1208 actual_type = BASE_KEYWORD; 1209 } 1210 1211base_stmt: BASE_KEYWORD sep base_arg stmtend 1212 1213typedef_arg_str: identifier_arg_str { tpdf_parent = (actual_type == EXTENSION_INSTANCE) ? ext_instance : actual; 1214 $$.token = actual_type; 1215 $$.actual = actual; 1216 if (lyp_check_identifier(trg->ctx, s, LY_IDENT_TYPE, trg, tpdf_parent)) { 1217 free(s); 1218 YYABORT; 1219 } 1220 switch (actual_type) { 1221 case MODULE_KEYWORD: 1222 case SUBMODULE_KEYWORD: 1223 YANG_ADDELEM(trg->tpdf, trg->tpdf_size, "typedefs"); 1224 break; 1225 case GROUPING_KEYWORD: 1226 YANG_ADDELEM(((struct lys_node_grp *)tpdf_parent)->tpdf, 1227 ((struct lys_node_grp *)tpdf_parent)->tpdf_size, "typedefs"); 1228 break; 1229 case CONTAINER_KEYWORD: 1230 YANG_ADDELEM(((struct lys_node_container *)tpdf_parent)->tpdf, 1231 ((struct lys_node_container *)tpdf_parent)->tpdf_size, "typedefs"); 1232 break; 1233 case LIST_KEYWORD: 1234 YANG_ADDELEM(((struct lys_node_list *)tpdf_parent)->tpdf, 1235 ((struct lys_node_list *)tpdf_parent)->tpdf_size, "typedefs"); 1236 break; 1237 case RPC_KEYWORD: 1238 case ACTION_KEYWORD: 1239 YANG_ADDELEM(((struct lys_node_rpc_action *)tpdf_parent)->tpdf, 1240 ((struct lys_node_rpc_action *)tpdf_parent)->tpdf_size, "typedefs"); 1241 break; 1242 case INPUT_KEYWORD: 1243 case OUTPUT_KEYWORD: 1244 YANG_ADDELEM(((struct lys_node_inout *)tpdf_parent)->tpdf, 1245 ((struct lys_node_inout *)tpdf_parent)->tpdf_size, "typedefs"); 1246 break; 1247 case NOTIFICATION_KEYWORD: 1248 YANG_ADDELEM(((struct lys_node_notif *)tpdf_parent)->tpdf, 1249 ((struct lys_node_notif *)tpdf_parent)->tpdf_size, "typedefs"); 1250 break; 1251 case EXTENSION_INSTANCE: 1252 /* typedef is already allocated */ 1253 break; 1254 default: 1255 /* another type of nodetype is error*/ 1256 LOGINT(trg->ctx); 1257 free(s); 1258 YYABORT; 1259 } 1260 ((struct lys_tpdf *)actual)->name = lydict_insert_zc(param->module->ctx, s); 1261 ((struct lys_tpdf *)actual)->module = trg; 1262 s = NULL; 1263 actual_type = TYPEDEF_KEYWORD; 1264 } 1265 1266typedef_stmt: TYPEDEF_KEYWORD sep typedef_arg_str 1267 '{' stmtsep 1268 type_opt_stmt 1269 '}' { if (!($6.node.flag & LYS_TYPE_DEF)) { 1270 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "type", "typedef"); 1271 YYABORT; 1272 } 1273 actual_type = $3.token; 1274 actual = $3.actual; 1275 } 1276 1277type_opt_stmt: @EMPTYDIR@ { $$.node.ptr_tpdf = actual; 1278 $$.node.flag = 0; 1279 } 1280 | type_opt_stmt type_stmt stmtsep { $1.node.flag |= LYS_TYPE_DEF; 1281 $$ = $1; 1282 } 1283 | type_opt_stmt units_stmt { if (yang_read_units(trg, $1.node.ptr_tpdf, s, TYPEDEF_KEYWORD)) { 1284 YYABORT; 1285 } 1286 s = NULL; 1287 } 1288 | type_opt_stmt default_stmt { if (yang_read_default(trg, $1.node.ptr_tpdf, s, TYPEDEF_KEYWORD)) { 1289 YYABORT; 1290 } 1291 s = NULL; 1292 } 1293 | type_opt_stmt status_stmt { if ($1.node.ptr_tpdf->flags & LYS_STATUS_MASK) { 1294 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "status", "typedef"); 1295 YYABORT; 1296 } 1297 $1.node.ptr_tpdf->flags |= $2; 1298 } 1299 | type_opt_stmt description_stmt { if (yang_read_description(trg, $1.node.ptr_tpdf, s, "typedef", NODE)) { 1300 YYABORT; 1301 } 1302 s = NULL; 1303 } 1304 | type_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.node.ptr_tpdf, s, "typedef", NODE)) { 1305 YYABORT; 1306 } 1307 s = NULL; 1308 } 1309 1310type_stmt: TYPE_KEYWORD sep type_arg_str type_end 1311 { actual_type = $3.token; 1312 actual = $3.actual; 1313 } 1314 1315type_arg_str: identifier_ref_arg_str { $$.token = actual_type; 1316 $$.actual = actual; 1317 if (!(actual = yang_read_type(trg->ctx, actual, s, actual_type))) { 1318 YYABORT; 1319 } 1320 s = NULL; 1321 actual_type = TYPE_KEYWORD; 1322 } 1323 1324type_end: ';' 1325 | '{' stmtsep 1326 type_body_stmts 1327 '}' 1328 1329type_body_stmts: some_restrictions { if (((struct yang_type *)actual)->base == LY_TYPE_STRING && 1330 ((struct yang_type *)actual)->type->info.str.pat_count) { 1331 void *tmp; 1332 1333 tmp = realloc(((struct yang_type *)actual)->type->info.str.patterns, 1334 ((struct yang_type *)actual)->type->info.str.pat_count * sizeof *((struct yang_type *)actual)->type->info.str.patterns); 1335 if (!tmp) { 1336 LOGMEM(trg->ctx); 1337 YYABORT; 1338 } 1339 ((struct yang_type *)actual)->type->info.str.patterns = tmp; 1340 1341#ifdef LY_ENABLED_CACHE 1342 if (!(trg->ctx->models.flags & LY_CTX_TRUSTED) && ((struct yang_type *)actual)->type->info.str.patterns_pcre) { 1343 tmp = realloc(((struct yang_type *)actual)->type->info.str.patterns_pcre, 1344 2 * ((struct yang_type *)actual)->type->info.str.pat_count * sizeof *((struct yang_type *)actual)->type->info.str.patterns_pcre); 1345 if (!tmp) { 1346 LOGMEM(trg->ctx); 1347 YYABORT; 1348 } 1349 ((struct yang_type *)actual)->type->info.str.patterns_pcre = tmp; 1350 } 1351#endif 1352 } 1353 if (((struct yang_type *)actual)->base == LY_TYPE_UNION) { 1354 struct lys_type *tmp; 1355 1356 tmp = realloc(((struct yang_type *)actual)->type->info.uni.types, 1357 ((struct yang_type *)actual)->type->info.uni.count * sizeof *tmp); 1358 if (!tmp) { 1359 LOGMEM(trg->ctx); 1360 YYABORT; 1361 } 1362 ((struct yang_type *)actual)->type->info.uni.types = tmp; 1363 } 1364 if (((struct yang_type *)actual)->base == LY_TYPE_IDENT) { 1365 struct lys_ident **tmp; 1366 1367 tmp = realloc(((struct yang_type *)actual)->type->info.ident.ref, 1368 ((struct yang_type *)actual)->type->info.ident.count* sizeof *tmp); 1369 if (!tmp) { 1370 LOGMEM(trg->ctx); 1371 YYABORT; 1372 } 1373 ((struct yang_type *)actual)->type->info.ident.ref = tmp; 1374 } 1375 } 1376 | enum_specification 1377 | bits_specification 1378 1379some_restrictions: @EMPTYDIR@ 1380 | some_restrictions require_instance_stmt { if (yang_read_require_instance(trg->ctx, actual, $2)) { 1381 YYABORT; 1382 } 1383 } 1384 | some_restrictions path_stmt { /* leafref_specification */ 1385 if (yang_read_leafref_path(trg, actual, s)) { 1386 YYABORT; 1387 } 1388 s = NULL; 1389 } 1390 | some_restrictions base_stmt { /* identityref_specification */ 1391 if (((struct yang_type *)actual)->base && ((struct yang_type *)actual)->base != LY_TYPE_IDENT) { 1392 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "base"); 1393 return EXIT_FAILURE; 1394 } 1395 ((struct yang_type *)actual)->base = LY_TYPE_IDENT; 1396 yang_type = actual; 1397 YANG_ADDELEM(((struct yang_type *)actual)->type->info.ident.ref, 1398 ((struct yang_type *)actual)->type->info.ident.count, "identity refs"); 1399 *((struct lys_ident **)actual) = (struct lys_ident *)s; 1400 actual = yang_type; 1401 s = NULL; 1402 } 1403 | some_restrictions length_stmt stmtsep 1404 | some_restrictions pattern_stmt stmtsep 1405 | some_restrictions fraction_digits_stmt { if (yang_read_fraction(trg->ctx, actual, $2)) { 1406 YYABORT; 1407 } 1408 } 1409 | some_restrictions range_stmt stmtsep 1410 | some_restrictions union_stmt stmtsep 1411 1412union_stmt: union_spec type_stmt { actual_type = $1.token; 1413 actual = $1.actual; 1414 } 1415 1416union_spec: @EMPTYDIR@ { struct yang_type *stype = (struct yang_type *)actual; 1417 1418 $$.token = actual_type; 1419 $$.actual = actual; 1420 if (stype->base != 0 && stype->base != LY_TYPE_UNION) { 1421 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected type statement."); 1422 YYABORT; 1423 } 1424 stype->base = LY_TYPE_UNION; 1425 if (strcmp(stype->name, "union")) { 1426 /* type can be a substatement only in "union" type, not in derived types */ 1427 LOGVAL(trg->ctx, LYE_INCHILDSTMT, LY_VLOG_NONE, NULL, "type", "derived type"); 1428 YYABORT; 1429 } 1430 YANG_ADDELEM(stype->type->info.uni.types, stype->type->info.uni.count, "union types") 1431 actual_type = UNION_KEYWORD; 1432 } 1433 1434fraction_digits_arg: fraction_digits_arg_str { $$ = $1; 1435 backup_type = actual_type; 1436 actual_type = FRACTION_DIGITS_KEYWORD; 1437 } 1438 1439fraction_digits_stmt: FRACTION_DIGITS_KEYWORD sep fraction_digits_arg stmtend { $$ = $3; } 1440 1441fraction_digits_arg_str: positive_integer_value optsep { $$ = $1; } 1442 | string_1 { char *endptr = NULL; 1443 unsigned long val; 1444 errno = 0; 1445 1446 val = strtoul(s, &endptr, 10); 1447 if (*endptr || s[0] == '-' || errno || val == 0 || val > UINT32_MAX) { 1448 LOGVAL(trg->ctx, LYE_INARG, LY_VLOG_NONE, NULL, s, "fraction-digits"); 1449 free(s); 1450 s = NULL; 1451 YYABORT; 1452 } 1453 $$ = (uint32_t) val; 1454 free(s); 1455 s =NULL; 1456 } 1457 1458length_stmt: LENGTH_KEYWORD sep length_arg_str length_end 1459 { actual = $3.actual; 1460 actual_type = $3.token; 1461 } 1462 1463length_arg_str: string { $$.token = actual_type; 1464 $$.actual = actual; 1465 if (!(actual = yang_read_length(trg->ctx, actual, s, is_ext_instance))) { 1466 YYABORT; 1467 } 1468 actual_type = LENGTH_KEYWORD; 1469 s = NULL; 1470 } 1471 1472length_end: ';' 1473 | '{' stmtsep 1474 message_opt_stmt 1475 '}' 1476 1477message_opt_stmt: @EMPTYDIR@ { switch (actual_type) { 1478 case MUST_KEYWORD: 1479 $$ = "must"; 1480 break; 1481 case LENGTH_KEYWORD: 1482 $$ = "length"; 1483 break; 1484 case RANGE_KEYWORD: 1485 $$ = "range"; 1486 break; 1487 default: 1488 LOGINT(trg->ctx); 1489 YYABORT; 1490 break; 1491 } 1492 } 1493 | message_opt_stmt error_message_stmt { if (yang_read_message(trg, actual, s, $1, ERROR_MESSAGE_KEYWORD)) { 1494 YYABORT; 1495 } 1496 s = NULL; 1497 } 1498 | message_opt_stmt error_app_tag_stmt { if (yang_read_message(trg, actual, s, $1, ERROR_APP_TAG_KEYWORD)) { 1499 YYABORT; 1500 } 1501 s = NULL; 1502 } 1503 | message_opt_stmt description_stmt { if (yang_read_description(trg, actual, s, $1, NODE)) { 1504 YYABORT; 1505 } 1506 s = NULL; 1507 } 1508 | message_opt_stmt reference_stmt { if (yang_read_reference(trg, actual, s, $1, NODE)) { 1509 YYABORT; 1510 } 1511 s = NULL; 1512 } 1513 1514pattern_sep: sep { $$.token = actual_type; 1515 $$.actual = actual; 1516 } 1517 1518pattern_stmt: PATTERN_KEYWORD pattern_sep pattern_arg_str pattern_end {struct lys_restr *pattern = actual; 1519 actual = NULL; 1520#ifdef LY_ENABLED_CACHE 1521 if ($2.token != EXTENSION_INSTANCE && 1522 !(data_node && data_node->nodetype != LYS_GROUPING && lys_ingrouping(data_node))) { 1523 unsigned int c = 2 * (((struct yang_type *)$2.actual)->type->info.str.pat_count - 1); 1524 YANG_ADDELEM(((struct yang_type *)$2.actual)->type->info.str.patterns_pcre, c, "patterns"); 1525 ++c; 1526 YANG_ADDELEM(((struct yang_type *)$2.actual)->type->info.str.patterns_pcre, c, "patterns"); 1527 actual = &(((struct yang_type *)$2.actual)->type->info.str.patterns_pcre)[2 * (((struct yang_type *)$2.actual)->type->info.str.pat_count - 1)]; 1528 } 1529#endif 1530 if (yang_read_pattern(trg->ctx, pattern, actual, $3, $4)) { 1531 YYABORT; 1532 } 1533 actual_type = $2.token; 1534 actual = $2.actual; 1535 } 1536 1537pattern_arg_str: string { if (actual_type != EXTENSION_INSTANCE) { 1538 if (((struct yang_type *)actual)->base != 0 && ((struct yang_type *)actual)->base != LY_TYPE_STRING) { 1539 free(s); 1540 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Unexpected pattern statement."); 1541 YYABORT; 1542 } 1543 ((struct yang_type *)actual)->base = LY_TYPE_STRING; 1544 YANG_ADDELEM(((struct yang_type *)actual)->type->info.str.patterns, 1545 ((struct yang_type *)actual)->type->info.str.pat_count, "patterns"); 1546 } 1547 $$ = s; 1548 s = NULL; 1549 actual_type = PATTERN_KEYWORD; 1550 } 1551 1552pattern_end: ';' { $$ = 0x06; } 1553 | '{' stmtsep 1554 pattern_opt_stmt 1555 '}' { $$ = $3; } 1556 1557pattern_opt_stmt: @EMPTYDIR@ { $$ = 0x06; /* ACK */ } 1558 | pattern_opt_stmt modifier_stmt { if (trg->version < 2) { 1559 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, "modifier"); 1560 YYABORT; 1561 } 1562 if ($1 != 0x06) { 1563 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "modifier", "pattern"); 1564 YYABORT; 1565 } 1566 $$ = $2; 1567 } 1568 | pattern_opt_stmt error_message_stmt { if (yang_read_message(trg, actual, s, "pattern", ERROR_MESSAGE_KEYWORD)) { 1569 YYABORT; 1570 } 1571 s = NULL; 1572 } 1573 | pattern_opt_stmt error_app_tag_stmt { if (yang_read_message(trg, actual, s, "pattern", ERROR_APP_TAG_KEYWORD)) { 1574 YYABORT; 1575 } 1576 s = NULL; 1577 } 1578 | pattern_opt_stmt description_stmt { if (yang_read_description(trg, actual, s, "pattern", NODE)) { 1579 YYABORT; 1580 } 1581 s = NULL; 1582 } 1583 | pattern_opt_stmt reference_stmt { if (yang_read_reference(trg, actual, s, "pattern", NODE)) { 1584 YYABORT; 1585 } 1586 s = NULL; 1587 } 1588 1589modifier_arg: string { backup_type = actual_type; 1590 actual_type = MODIFIER_KEYWORD; 1591 } 1592 1593modifier_stmt: MODIFIER_KEYWORD sep modifier_arg stmtend { if (!strcmp(s, "invert-match")) { 1594 $$ = 0x15; 1595 free(s); 1596 s = NULL; 1597 } else { 1598 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, s); 1599 free(s); 1600 YYABORT; 1601 } 1602 } 1603 1604enum_specification: enum_stmt stmtsep enum_stmts { struct lys_type_enum * tmp; 1605 1606 cnt_val = 0; 1607 tmp = realloc(((struct yang_type *)actual)->type->info.enums.enm, 1608 ((struct yang_type *)actual)->type->info.enums.count * sizeof *tmp); 1609 if (!tmp) { 1610 LOGMEM(trg->ctx); 1611 YYABORT; 1612 } 1613 ((struct yang_type *)actual)->type->info.enums.enm = tmp; 1614 } 1615 1616enum_stmts: @EMPTYDIR@ 1617 | enum_stmts enum_stmt stmtsep; 1618 1619 1620enum_stmt: ENUM_KEYWORD sep enum_arg_str enum_end 1621 { if (yang_check_enum(trg->ctx, yang_type, actual, &cnt_val, is_value)) { 1622 YYABORT; 1623 } 1624 actual = $3.actual; 1625 actual_type = $3.token; 1626 } 1627 1628enum_arg_str: string { $$.token = actual_type; 1629 $$.actual = yang_type = actual; 1630 YANG_ADDELEM(((struct yang_type *)actual)->type->info.enums.enm, ((struct yang_type *)actual)->type->info.enums.count, "enums"); 1631 if (yang_read_enum(trg->ctx, yang_type, actual, s)) { 1632 YYABORT; 1633 } 1634 s = NULL; 1635 is_value = 0; 1636 actual_type = ENUM_KEYWORD; 1637 } 1638 1639enum_end: ';' 1640 | '{' stmtsep 1641 enum_opt_stmt 1642 '}' { if (((struct lys_type_enum *)actual)->iffeature_size) { 1643 struct lys_iffeature *tmp; 1644 1645 tmp = realloc(((struct lys_type_enum *)actual)->iffeature, 1646 ((struct lys_type_enum *)actual)->iffeature_size * sizeof *tmp); 1647 if (!tmp) { 1648 LOGMEM(trg->ctx); 1649 YYABORT; 1650 } 1651 ((struct lys_type_enum *)actual)->iffeature = tmp; 1652 } 1653 } 1654 1655enum_opt_stmt: @EMPTYDIR@ 1656 | enum_opt_stmt if_feature_stmt stmtsep 1657 | enum_opt_stmt value_stmt { if (is_value) { 1658 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "value", "enum"); 1659 YYABORT; 1660 } 1661 ((struct lys_type_enum *)actual)->value = $2; 1662 1663 /* keep the highest enum value for automatic increment */ 1664 if ($2 >= cnt_val) { 1665 cnt_val = $2 + 1; 1666 } 1667 is_value = 1; 1668 } 1669 | enum_opt_stmt status_stmt { if (((struct lys_type_enum *)actual)->flags & LYS_STATUS_MASK) { 1670 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "status", "enum"); 1671 YYABORT; 1672 } 1673 ((struct lys_type_enum *)actual)->flags |= $2; 1674 } 1675 | enum_opt_stmt description_stmt { if (yang_read_description(trg, actual, s, "enum", NODE)) { 1676 YYABORT; 1677 } 1678 s = NULL; 1679 } 1680 | enum_opt_stmt reference_stmt { if (yang_read_reference(trg, actual, s, "enum", NODE)) { 1681 YYABORT; 1682 } 1683 s = NULL; 1684 } 1685 1686value_arg: integer_value_arg_str { $$ = $1; 1687 backup_type = actual_type; 1688 actual_type = VALUE_KEYWORD; 1689 } 1690 1691value_stmt: VALUE_KEYWORD sep value_arg stmtend { $$ = $3; } 1692 1693integer_value_arg_str: integer_value optsep { $$ = $1; } 1694 | string_1 { /* convert it to int32_t */ 1695 int64_t val; 1696 char *endptr; 1697 1698 val = strtoll(s, &endptr, 10); 1699 if (val < INT32_MIN || val > INT32_MAX || *endptr) { 1700 LOGVAL(trg->ctx, LYE_INARG, LY_VLOG_NONE, NULL, s, "value"); 1701 free(s); 1702 YYABORT; 1703 } 1704 free(s); 1705 s = NULL; 1706 $$ = (int32_t) val; 1707 } 1708 1709range_stmt: RANGE_KEYWORD sep range_arg_str range_end { actual_type = $3.token; 1710 actual = $3.actual; 1711 } 1712 1713 1714range_end: ';' 1715 | '{' stmtsep 1716 message_opt_stmt 1717 '}' 1718 ; 1719 1720path_arg: path_arg_str { backup_type = actual_type; 1721 actual_type = PATH_KEYWORD; 1722 } 1723 1724path_stmt: PATH_KEYWORD sep path_arg stmtend 1725 1726require_instance_arg: require_instance_arg_str { $$ = $1; 1727 backup_type = actual_type; 1728 actual_type = REQUIRE_INSTANCE_KEYWORD; 1729 } 1730 1731require_instance_stmt: REQUIRE_INSTANCE_KEYWORD sep require_instance_arg stmtend { $$ = $3; } 1732 1733require_instance_arg_str: TRUE_KEYWORD optsep { $$ = 1; } 1734 | FALSE_KEYWORD optsep { $$ = -1; } 1735 | string_1 { if (!strcmp(s,"true")) { 1736 $$ = 1; 1737 } else if (!strcmp(s,"false")) { 1738 $$ = -1; 1739 } else { 1740 LOGVAL(trg->ctx, LYE_INARG, LY_VLOG_NONE, NULL, s, "require-instance"); 1741 free(s); 1742 YYABORT; 1743 } 1744 free(s); 1745 s = NULL; 1746 } 1747 1748bits_specification: bit_stmt bit_stmts { struct lys_type_bit * tmp; 1749 1750 cnt_val = 0; 1751 tmp = realloc(((struct yang_type *)actual)->type->info.bits.bit, 1752 ((struct yang_type *)actual)->type->info.bits.count * sizeof *tmp); 1753 if (!tmp) { 1754 LOGMEM(trg->ctx); 1755 YYABORT; 1756 } 1757 ((struct yang_type *)actual)->type->info.bits.bit = tmp; 1758 } 1759 1760bit_stmts: @EMPTYDIR@ 1761 | bit_stmts bit_stmt; 1762 1763bit_stmt: BIT_KEYWORD sep bit_arg_str bit_end 1764 stmtsep { if (yang_check_bit(trg->ctx, yang_type, actual, &cnt_val, is_value)) { 1765 YYABORT; 1766 } 1767 actual = $3.actual; 1768 actual_type = $3.token; 1769 } 1770 1771bit_arg_str: identifier_arg_str { $$.token = actual_type; 1772 $$.actual = yang_type = actual; 1773 YANG_ADDELEM(((struct yang_type *)actual)->type->info.bits.bit, 1774 ((struct yang_type *)actual)->type->info.bits.count, "bits"); 1775 if (yang_read_bit(trg->ctx, yang_type, actual, s)) { 1776 YYABORT; 1777 } 1778 s = NULL; 1779 is_value = 0; 1780 actual_type = BIT_KEYWORD; 1781 } 1782 1783bit_end: ';' 1784 | '{' stmtsep 1785 bit_opt_stmt 1786 '}' { if (((struct lys_type_bit *)actual)->iffeature_size) { 1787 struct lys_iffeature *tmp; 1788 1789 tmp = realloc(((struct lys_type_bit *)actual)->iffeature, 1790 ((struct lys_type_bit *)actual)->iffeature_size * sizeof *tmp); 1791 if (!tmp) { 1792 LOGMEM(trg->ctx); 1793 YYABORT; 1794 } 1795 ((struct lys_type_bit *)actual)->iffeature = tmp; 1796 } 1797 } 1798 1799bit_opt_stmt: @EMPTYDIR@ 1800 | bit_opt_stmt if_feature_stmt stmtsep 1801 | bit_opt_stmt position_stmt { if (is_value) { 1802 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "position", "bit"); 1803 YYABORT; 1804 } 1805 ((struct lys_type_bit *)actual)->pos = $2; 1806 1807 /* keep the highest position value for automatic increment */ 1808 if ($2 >= cnt_val) { 1809 cnt_val = $2 + 1; 1810 } 1811 is_value = 1; 1812 } 1813 | bit_opt_stmt status_stmt { if (((struct lys_type_bit *)actual)->flags & LYS_STATUS_MASK) { 1814 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "status", "bit"); 1815 YYABORT; 1816 } 1817 ((struct lys_type_bit *)actual)->flags |= $2; 1818 } 1819 | bit_opt_stmt description_stmt { if (yang_read_description(trg, actual, s, "bit", NODE)) { 1820 YYABORT; 1821 } 1822 s = NULL; 1823 } 1824 | bit_opt_stmt reference_stmt { if (yang_read_reference(trg, actual, s, "bit", NODE)) { 1825 YYABORT; 1826 } 1827 s = NULL; 1828 } 1829 1830position_value_arg: position_value_arg_str { $$ = $1; 1831 backup_type = actual_type; 1832 actual_type = POSITION_KEYWORD; 1833 } 1834 1835position_stmt: POSITION_KEYWORD sep position_value_arg stmtend { $$ = $3; } 1836 1837position_value_arg_str: non_negative_integer_value optsep { $$ = $1; } 1838 | string_1 { /* convert it to uint32_t */ 1839 unsigned long val; 1840 char *endptr = NULL; 1841 errno = 0; 1842 1843 val = strtoul(s, &endptr, 10); 1844 if (s[0] == '-' || *endptr || errno || val > UINT32_MAX) { 1845 LOGVAL(trg->ctx, LYE_INARG, LY_VLOG_NONE, NULL, s, "position"); 1846 free(s); 1847 YYABORT; 1848 } 1849 free(s); 1850 s = NULL; 1851 $$ = (uint32_t) val; 1852 } 1853 1854error_message_arg: string { backup_type = actual_type; 1855 actual_type = ERROR_MESSAGE_KEYWORD; 1856 } 1857 1858error_message_stmt: ERROR_MESSAGE_KEYWORD sep error_message_arg stmtend 1859 1860error_app_tag_arg: string { backup_type = actual_type; 1861 actual_type = ERROR_APP_TAG_KEYWORD; 1862 } 1863 1864error_app_tag_stmt: ERROR_APP_TAG_KEYWORD sep error_app_tag_arg stmtend 1865 1866units_arg: string { backup_type = actual_type; 1867 actual_type = UNITS_KEYWORD; 1868 } 1869 1870units_stmt: UNITS_KEYWORD sep units_arg stmtend 1871 1872default_arg: string { backup_type = actual_type; 1873 actual_type = DEFAULT_KEYWORD; 1874 } 1875 1876default_stmt: DEFAULT_KEYWORD sep default_arg stmtend 1877 1878grouping_arg_str: identifier_arg_str { $$.token = actual_type; 1879 $$.actual = actual; 1880 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_GROUPING, sizeof(struct lys_node_grp)))) { 1881 YYABORT; 1882 } 1883 s = NULL; 1884 data_node = actual; 1885 actual_type = GROUPING_KEYWORD; 1886 } 1887 1888grouping_stmt: GROUPING_KEYWORD sep grouping_arg_str grouping_end 1889 { LOGDBG(LY_LDGYANG, "finished parsing grouping statement \"%s\"", data_node->name); 1890 actual_type = $3.token; 1891 actual = $3.actual; 1892 data_node = $3.actual; 1893 } 1894 1895grouping_end: ';' 1896 | '{' stmtsep 1897 grouping_opt_stmt 1898 '}' 1899 1900grouping_opt_stmt: @EMPTYDIR@ { $$.grouping = actual; } 1901 | grouping_opt_stmt status_stmt { if ($1.grouping->flags & LYS_STATUS_MASK) { 1902 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.grouping, "status", "grouping"); 1903 YYABORT; 1904 } 1905 $1.grouping->flags |= $2; 1906 } 1907 | grouping_opt_stmt description_stmt { if (yang_read_description(trg, $1.grouping, s, "grouping", NODE_PRINT)) { 1908 YYABORT; 1909 } 1910 s = NULL; 1911 } 1912 | grouping_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.grouping, s, "grouping", NODE_PRINT)) { 1913 YYABORT; 1914 } 1915 s = NULL; 1916 } 1917 | grouping_opt_stmt grouping_stmt stmtsep 1918 | grouping_opt_stmt typedef_stmt stmtsep 1919 | grouping_opt_stmt data_def_stmt stmtsep 1920 | grouping_opt_stmt action_stmt stmtsep 1921 | grouping_opt_stmt notification_stmt stmtsep { if (trg->version < 2) { 1922 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_LYS, $1.grouping, "notification"); 1923 YYABORT; 1924 } 1925 } 1926 1927data_def_stmt: container_stmt 1928 | leaf_stmt 1929 | leaf_list_stmt 1930 | list_stmt 1931 | choice_stmt 1932 | anyxml_stmt 1933 | anydata_stmt 1934 | uses_stmt 1935 ; 1936 1937container_arg_str: identifier_arg_str { $$.token = actual_type; 1938 $$.actual = actual; 1939 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_CONTAINER, sizeof(struct lys_node_container)))) { 1940 YYABORT; 1941 } 1942 data_node = actual; 1943 s = NULL; 1944 actual_type = CONTAINER_KEYWORD; 1945 } 1946 1947container_stmt: CONTAINER_KEYWORD sep container_arg_str container_end 1948 { LOGDBG(LY_LDGYANG, "finished parsing container statement \"%s\"", data_node->name); 1949 actual_type = $3.token; 1950 actual = $3.actual; 1951 data_node = $3.actual; 1952 } 1953 1954container_end: ';' 1955 | '{' stmtsep 1956 container_opt_stmt 1957 '}' { void *tmp; 1958 1959 if ($3.container->iffeature_size) { 1960 tmp = realloc($3.container->iffeature, $3.container->iffeature_size * sizeof *$3.container->iffeature); 1961 if (!tmp) { 1962 LOGMEM(trg->ctx); 1963 YYABORT; 1964 } 1965 $3.container->iffeature = tmp; 1966 } 1967 1968 if ($3.container->must_size) { 1969 tmp = realloc($3.container->must, $3.container->must_size * sizeof *$3.container->must); 1970 if (!tmp) { 1971 LOGMEM(trg->ctx); 1972 YYABORT; 1973 } 1974 $3.container->must = tmp; 1975 } 1976 } 1977 1978container_opt_stmt: @EMPTYDIR@ { $$.container = actual; } 1979 | container_opt_stmt when_stmt stmtsep 1980 | container_opt_stmt if_feature_stmt stmtsep 1981 | container_opt_stmt must_stmt stmtsep 1982 | container_opt_stmt presence_stmt { if (yang_read_presence(trg, $1.container, s)) { 1983 YYABORT; 1984 } 1985 s = NULL; 1986 } 1987 | container_opt_stmt config_stmt { if ($1.container->flags & LYS_CONFIG_MASK) { 1988 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.container, "config", "container"); 1989 YYABORT; 1990 } 1991 $1.container->flags |= $2; 1992 } 1993 | container_opt_stmt status_stmt { if ($1.container->flags & LYS_STATUS_MASK) { 1994 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.container, "status", "container"); 1995 YYABORT; 1996 } 1997 $1.container->flags |= $2; 1998 } 1999 | container_opt_stmt description_stmt { if (yang_read_description(trg, $1.container, s, "container", NODE_PRINT)) { 2000 YYABORT; 2001 } 2002 s = NULL; 2003 } 2004 | container_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.container, s, "container", NODE_PRINT)) { 2005 YYABORT; 2006 } 2007 s = NULL; 2008 } 2009 | container_opt_stmt grouping_stmt stmtsep 2010 | container_opt_stmt action_stmt stmtsep 2011 | container_opt_stmt notification_stmt stmtsep { if (trg->version < 2) { 2012 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_LYS, $1.container, "notification"); 2013 YYABORT; 2014 } 2015 } 2016 | container_opt_stmt typedef_stmt stmtsep 2017 | container_opt_stmt data_def_stmt stmtsep 2018 2019leaf_stmt: LEAF_KEYWORD sep leaf_arg_str 2020 '{' stmtsep 2021 leaf_opt_stmt 2022 '}' { void *tmp; 2023 2024 if (!($6.node.flag & LYS_TYPE_DEF)) { 2025 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_LYS, $6.node.ptr_leaf, "type", "leaf"); 2026 YYABORT; 2027 } 2028 if ($6.node.ptr_leaf->dflt && ($6.node.ptr_leaf->flags & LYS_MAND_TRUE)) { 2029 /* RFC 6020, 7.6.4 - default statement must not with mandatory true */ 2030 LOGVAL(trg->ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, $6.node.ptr_leaf, "mandatory", "leaf"); 2031 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $6.node.ptr_leaf, "The \"mandatory\" statement is forbidden on leaf with \"default\"."); 2032 YYABORT; 2033 } 2034 2035 if ($6.node.ptr_leaf->iffeature_size) { 2036 tmp = realloc($6.node.ptr_leaf->iffeature, $6.node.ptr_leaf->iffeature_size * sizeof *$6.node.ptr_leaf->iffeature); 2037 if (!tmp) { 2038 LOGMEM(trg->ctx); 2039 YYABORT; 2040 } 2041 $6.node.ptr_leaf->iffeature = tmp; 2042 } 2043 2044 if ($6.node.ptr_leaf->must_size) { 2045 tmp = realloc($6.node.ptr_leaf->must, $6.node.ptr_leaf->must_size * sizeof *$6.node.ptr_leaf->must); 2046 if (!tmp) { 2047 LOGMEM(trg->ctx); 2048 YYABORT; 2049 } 2050 $6.node.ptr_leaf->must = tmp; 2051 } 2052 2053 LOGDBG(LY_LDGYANG, "finished parsing leaf statement \"%s\"", data_node->name); 2054 actual_type = $3.token; 2055 actual = $3.actual; 2056 data_node = $3.actual; 2057 } 2058 2059leaf_arg_str: identifier_arg_str { $$.token = actual_type; 2060 $$.actual = actual; 2061 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_LEAF, sizeof(struct lys_node_leaf)))) { 2062 YYABORT; 2063 } 2064 data_node = actual; 2065 s = NULL; 2066 actual_type = LEAF_KEYWORD; 2067 } 2068 2069leaf_opt_stmt: @EMPTYDIR@ { $$.node.ptr_leaf = actual; 2070 $$.node.flag = 0; 2071 } 2072 | leaf_opt_stmt when_stmt stmtsep 2073 | leaf_opt_stmt if_feature_stmt stmtsep 2074 | leaf_opt_stmt type_stmt stmtsep { $1.node.flag |= LYS_TYPE_DEF; 2075 $$ = $1; 2076 } 2077 | leaf_opt_stmt units_stmt { if (yang_read_units(trg, $1.node.ptr_leaf, s, LEAF_KEYWORD)) { 2078 YYABORT; 2079 } 2080 s = NULL; 2081 } 2082 | leaf_opt_stmt must_stmt stmtsep 2083 | leaf_opt_stmt default_stmt { if (yang_read_default(trg, $1.node.ptr_leaf, s, LEAF_KEYWORD)) { 2084 YYABORT; 2085 } 2086 s = NULL; 2087 } 2088 | leaf_opt_stmt config_stmt { if ($1.node.ptr_leaf->flags & LYS_CONFIG_MASK) { 2089 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_leaf, "config", "leaf"); 2090 YYABORT; 2091 } 2092 $1.node.ptr_leaf->flags |= $2; 2093 } 2094 | leaf_opt_stmt mandatory_stmt { if ($1.node.ptr_leaf->flags & LYS_MAND_MASK) { 2095 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_leaf, "mandatory", "leaf"); 2096 YYABORT; 2097 } 2098 $1.node.ptr_leaf->flags |= $2; 2099 } 2100 | leaf_opt_stmt status_stmt { if ($1.node.ptr_leaf->flags & LYS_STATUS_MASK) { 2101 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_leaf, "status", "leaf"); 2102 YYABORT; 2103 } 2104 $1.node.ptr_leaf->flags |= $2; 2105 } 2106 | leaf_opt_stmt description_stmt { if (yang_read_description(trg, $1.node.ptr_leaf, s, "leaf", NODE_PRINT)) { 2107 YYABORT; 2108 } 2109 s = NULL; 2110 } 2111 | leaf_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.node.ptr_leaf, s, "leaf", NODE_PRINT)) { 2112 YYABORT; 2113 } 2114 s = NULL; 2115 } 2116 2117leaf_list_arg_str: identifier_arg_str { $$.token = actual_type; 2118 $$.actual = actual; 2119 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_LEAFLIST, sizeof(struct lys_node_leaflist)))) { 2120 YYABORT; 2121 } 2122 data_node = actual; 2123 s = NULL; 2124 actual_type = LEAF_LIST_KEYWORD; 2125 } 2126 2127 leaf_list_stmt: LEAF_LIST_KEYWORD sep leaf_list_arg_str 2128 '{' stmtsep 2129 leaf_list_opt_stmt 2130 '}' { void *tmp; 2131 2132 if ($6.node.ptr_leaflist->flags & LYS_CONFIG_R) { 2133 /* RFC 6020, 7.7.5 - ignore ordering when the list represents state data 2134 * ignore oredering MASK - 0x7F 2135 */ 2136 $6.node.ptr_leaflist->flags &= 0x7F; 2137 } 2138 if (!($6.node.flag & LYS_TYPE_DEF)) { 2139 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_LYS, $6.node.ptr_leaflist, "type", "leaf-list"); 2140 YYABORT; 2141 } 2142 if ($6.node.ptr_leaflist->dflt_size && $6.node.ptr_leaflist->min) { 2143 LOGVAL(trg->ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, $6.node.ptr_leaflist, "min-elements", "leaf-list"); 2144 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $6.node.ptr_leaflist, 2145 "The \"min-elements\" statement with non-zero value is forbidden on leaf-lists with the \"default\" statement."); 2146 YYABORT; 2147 } 2148 2149 if ($6.node.ptr_leaflist->iffeature_size) { 2150 tmp = realloc($6.node.ptr_leaflist->iffeature, $6.node.ptr_leaflist->iffeature_size * sizeof *$6.node.ptr_leaflist->iffeature); 2151 if (!tmp) { 2152 LOGMEM(trg->ctx); 2153 YYABORT; 2154 } 2155 $6.node.ptr_leaflist->iffeature = tmp; 2156 } 2157 2158 if ($6.node.ptr_leaflist->must_size) { 2159 tmp = realloc($6.node.ptr_leaflist->must, $6.node.ptr_leaflist->must_size * sizeof *$6.node.ptr_leaflist->must); 2160 if (!tmp) { 2161 LOGMEM(trg->ctx); 2162 YYABORT; 2163 } 2164 $6.node.ptr_leaflist->must = tmp; 2165 } 2166 2167 if ($6.node.ptr_leaflist->dflt_size) { 2168 tmp = realloc($6.node.ptr_leaflist->dflt, $6.node.ptr_leaflist->dflt_size * sizeof *$6.node.ptr_leaflist->dflt); 2169 if (!tmp) { 2170 LOGMEM(trg->ctx); 2171 YYABORT; 2172 } 2173 $6.node.ptr_leaflist->dflt = tmp; 2174 } 2175 2176 LOGDBG(LY_LDGYANG, "finished parsing leaf-list statement \"%s\"", data_node->name); 2177 actual_type = $3.token; 2178 actual = $3.actual; 2179 data_node = $3.actual; 2180 } 2181 2182leaf_list_opt_stmt: @EMPTYDIR@ { $$.node.ptr_leaflist = actual; 2183 $$.node.flag = 0; 2184 } 2185 | leaf_list_opt_stmt when_stmt stmtsep 2186 | leaf_list_opt_stmt if_feature_stmt stmtsep 2187 | leaf_list_opt_stmt type_stmt stmtsep { $1.node.flag |= LYS_TYPE_DEF; 2188 $$ = $1; 2189 } 2190 | leaf_list_opt_stmt default_stmt { if (trg->version < 2) { 2191 free(s); 2192 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_LYS, $1.node.ptr_leaflist, "default"); 2193 YYABORT; 2194 } 2195 YANG_ADDELEM($1.node.ptr_leaflist->dflt, 2196 $1.node.ptr_leaflist->dflt_size, "defaults"); 2197 (*(const char **)actual) = lydict_insert_zc(param->module->ctx, s); 2198 s = NULL; 2199 actual = $1.node.ptr_leaflist; 2200 } 2201 | leaf_list_opt_stmt units_stmt { if (yang_read_units(trg, $1.node.ptr_leaflist, s, LEAF_LIST_KEYWORD)) { 2202 YYABORT; 2203 } 2204 s = NULL; 2205 } 2206 | leaf_list_opt_stmt must_stmt stmtsep 2207 | leaf_list_opt_stmt config_stmt { if ($1.node.ptr_leaflist->flags & LYS_CONFIG_MASK) { 2208 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_leaflist, "config", "leaf-list"); 2209 YYABORT; 2210 } 2211 $1.node.ptr_leaflist->flags |= $2; 2212 } 2213 | leaf_list_opt_stmt min_elements_stmt { if ($1.node.flag & LYS_MIN_ELEMENTS) { 2214 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_leaflist, "min-elements", "leaf-list"); 2215 YYABORT; 2216 } 2217 $1.node.ptr_leaflist->min = $2; 2218 $1.node.flag |= LYS_MIN_ELEMENTS; 2219 $$ = $1; 2220 if ($1.node.ptr_leaflist->max && ($1.node.ptr_leaflist->min > $1.node.ptr_leaflist->max)) { 2221 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $1.node.ptr_leaflist, "Invalid value \"%d\" of \"%s\".", $2, "min-elements"); 2222 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $1.node.ptr_leaflist, "\"min-elements\" is bigger than \"max-elements\"."); 2223 YYABORT; 2224 } 2225 } 2226 | leaf_list_opt_stmt max_elements_stmt { if ($1.node.flag & LYS_MAX_ELEMENTS) { 2227 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_leaflist, "max-elements", "leaf-list"); 2228 YYABORT; 2229 } 2230 $1.node.ptr_leaflist->max = $2; 2231 $1.node.flag |= LYS_MAX_ELEMENTS; 2232 $$ = $1; 2233 if ($1.node.ptr_leaflist->max && ($1.node.ptr_leaflist->min > $1.node.ptr_leaflist->max)) { 2234 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $1.node.ptr_leaflist, "Invalid value \"%d\" of \"%s\".", $2, "max-elements"); 2235 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $1.node.ptr_leaflist, "\"max-elements\" is smaller than \"min-elements\"."); 2236 YYABORT; 2237 } 2238 } 2239 | leaf_list_opt_stmt ordered_by_stmt { if ($1.node.flag & LYS_ORDERED_MASK) { 2240 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_leaflist, "ordered by", "leaf-list"); 2241 YYABORT; 2242 } 2243 if ($2 & LYS_USERORDERED) { 2244 $1.node.ptr_leaflist->flags |= LYS_USERORDERED; 2245 } 2246 $1.node.flag |= $2; 2247 $$ = $1; 2248 } 2249 | leaf_list_opt_stmt status_stmt { if ($1.node.ptr_leaflist->flags & LYS_STATUS_MASK) { 2250 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_leaflist, "status", "leaf-list"); 2251 YYABORT; 2252 } 2253 $1.node.ptr_leaflist->flags |= $2; 2254 } 2255 | leaf_list_opt_stmt description_stmt { if (yang_read_description(trg, $1.node.ptr_leaflist, s, "leaf-list", NODE_PRINT)) { 2256 YYABORT; 2257 } 2258 s = NULL; 2259 } 2260 | leaf_list_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.node.ptr_leaflist, s, "leaf-list", NODE_PRINT)) { 2261 YYABORT; 2262 } 2263 s = NULL; 2264 } 2265 2266list_arg_str: identifier_arg_str { $$.token = actual_type; 2267 $$.actual = actual; 2268 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_LIST, sizeof(struct lys_node_list)))) { 2269 YYABORT; 2270 } 2271 data_node = actual; 2272 s = NULL; 2273 actual_type = LIST_KEYWORD; 2274 } 2275 2276list_stmt: LIST_KEYWORD sep list_arg_str 2277 '{' stmtsep 2278 list_opt_stmt 2279 '}' { void *tmp; 2280 2281 if ($6.node.ptr_list->iffeature_size) { 2282 tmp = realloc($6.node.ptr_list->iffeature, $6.node.ptr_list->iffeature_size * sizeof *$6.node.ptr_list->iffeature); 2283 if (!tmp) { 2284 LOGMEM(trg->ctx); 2285 YYABORT; 2286 } 2287 $6.node.ptr_list->iffeature = tmp; 2288 } 2289 2290 if ($6.node.ptr_list->must_size) { 2291 tmp = realloc($6.node.ptr_list->must, $6.node.ptr_list->must_size * sizeof *$6.node.ptr_list->must); 2292 if (!tmp) { 2293 LOGMEM(trg->ctx); 2294 YYABORT; 2295 } 2296 $6.node.ptr_list->must = tmp; 2297 } 2298 2299 if ($6.node.ptr_list->tpdf_size) { 2300 tmp = realloc($6.node.ptr_list->tpdf, $6.node.ptr_list->tpdf_size * sizeof *$6.node.ptr_list->tpdf); 2301 if (!tmp) { 2302 LOGMEM(trg->ctx); 2303 YYABORT; 2304 } 2305 $6.node.ptr_list->tpdf = tmp; 2306 } 2307 2308 if ($6.node.ptr_list->unique_size) { 2309 tmp = realloc($6.node.ptr_list->unique, $6.node.ptr_list->unique_size * sizeof *$6.node.ptr_list->unique); 2310 if (!tmp) { 2311 LOGMEM(trg->ctx); 2312 YYABORT; 2313 } 2314 $6.node.ptr_list->unique = tmp; 2315 } 2316 2317 LOGDBG(LY_LDGYANG, "finished parsing list statement \"%s\"", data_node->name); 2318 actual_type = $3.token; 2319 actual = $3.actual; 2320 data_node = $3.actual; 2321 } 2322 2323list_opt_stmt: @EMPTYDIR@ { $$.node.ptr_list = actual; 2324 $$.node.flag = 0; 2325 } 2326 | list_opt_stmt when_stmt stmtsep 2327 | list_opt_stmt if_feature_stmt stmtsep 2328 | list_opt_stmt must_stmt stmtsep 2329 | list_opt_stmt key_stmt { if ($1.node.ptr_list->keys) { 2330 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_list, "key", "list"); 2331 free(s); 2332 YYABORT; 2333 } 2334 $1.node.ptr_list->keys = (struct lys_node_leaf **)s; 2335 $$ = $1; 2336 s = NULL; 2337 } 2338 | list_opt_stmt unique_stmt { YANG_ADDELEM($1.node.ptr_list->unique, $1.node.ptr_list->unique_size, "uniques"); 2339 ((struct lys_unique *)actual)->expr = (const char **)s; 2340 $$ = $1; 2341 s = NULL; 2342 actual = $1.node.ptr_list; 2343 } 2344 | list_opt_stmt config_stmt { if ($1.node.ptr_list->flags & LYS_CONFIG_MASK) { 2345 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_list, "config", "list"); 2346 YYABORT; 2347 } 2348 $1.node.ptr_list->flags |= $2; 2349 } 2350 | list_opt_stmt min_elements_stmt { if ($1.node.flag & LYS_MIN_ELEMENTS) { 2351 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_list, "min-elements", "list"); 2352 YYABORT; 2353 } 2354 $1.node.ptr_list->min = $2; 2355 $1.node.flag |= LYS_MIN_ELEMENTS; 2356 $$ = $1; 2357 if ($1.node.ptr_list->max && ($1.node.ptr_list->min > $1.node.ptr_list->max)) { 2358 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $1.node.ptr_list, "Invalid value \"%d\" of \"%s\".", $2, "min-elements"); 2359 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $1.node.ptr_list, "\"min-elements\" is bigger than \"max-elements\"."); 2360 YYABORT; 2361 } 2362 } 2363 | list_opt_stmt max_elements_stmt { if ($1.node.flag & LYS_MAX_ELEMENTS) { 2364 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_list, "max-elements", "list"); 2365 YYABORT; 2366 } 2367 $1.node.ptr_list->max = $2; 2368 $1.node.flag |= LYS_MAX_ELEMENTS; 2369 $$ = $1; 2370 if ($1.node.ptr_list->max && ($1.node.ptr_list->min > $1.node.ptr_list->max)) { 2371 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $1.node.ptr_list, "Invalid value \"%d\" of \"%s\".", $2, "min-elements"); 2372 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $1.node.ptr_list, "\"max-elements\" is smaller than \"min-elements\"."); 2373 YYABORT; 2374 } 2375 } 2376 | list_opt_stmt ordered_by_stmt { if ($1.node.flag & LYS_ORDERED_MASK) { 2377 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_list, "ordered by", "list"); 2378 YYABORT; 2379 } 2380 if ($2 & LYS_USERORDERED) { 2381 $1.node.ptr_list->flags |= LYS_USERORDERED; 2382 } 2383 $1.node.flag |= $2; 2384 $$ = $1; 2385 } 2386 | list_opt_stmt status_stmt { if ($1.node.ptr_list->flags & LYS_STATUS_MASK) { 2387 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_list, "status", "list"); 2388 YYABORT; 2389 } 2390 $1.node.ptr_list->flags |= $2; 2391 } 2392 | list_opt_stmt description_stmt { if (yang_read_description(trg, $1.node.ptr_list, s, "list", NODE_PRINT)) { 2393 YYABORT; 2394 } 2395 s = NULL; 2396 } 2397 | list_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.node.ptr_list, s, "list", NODE_PRINT)) { 2398 YYABORT; 2399 } 2400 s = NULL; 2401 } 2402 | list_opt_stmt typedef_stmt stmtsep 2403 | list_opt_stmt grouping_stmt stmtsep 2404 | list_opt_stmt action_stmt stmtsep 2405 | list_opt_stmt notification_stmt stmtsep { if (trg->version < 2) { 2406 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_LYS, $1.node.ptr_list, "notification"); 2407 YYABORT; 2408 } 2409 } 2410 | list_opt_stmt data_def_stmt stmtsep 2411 2412choice_arg_str: identifier_arg_str { $$.token = actual_type; 2413 $$.actual = actual; 2414 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_CHOICE, sizeof(struct lys_node_choice)))) { 2415 YYABORT; 2416 } 2417 data_node = actual; 2418 s = NULL; 2419 actual_type = CHOICE_KEYWORD; 2420 } 2421 2422choice_stmt: CHOICE_KEYWORD sep choice_arg_str choice_end 2423 { LOGDBG(LY_LDGYANG, "finished parsing choice statement \"%s\"", data_node->name); 2424 actual_type = $3.token; 2425 actual = $3.actual; 2426 data_node = $3.actual; 2427 } 2428 2429choice_end: ';' 2430 | '{' stmtsep 2431 choice_opt_stmt 2432 '}' { struct lys_iffeature *tmp; 2433 2434 if (($3.node.ptr_choice->flags & LYS_MAND_TRUE) && $3.node.ptr_choice->dflt) { 2435 LOGVAL(trg->ctx, LYE_INCHILDSTMT, LY_VLOG_LYS, $3.node.ptr_choice, "default", "choice"); 2436 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_LYS, $3.node.ptr_choice, "The \"default\" statement is forbidden on choices with \"mandatory\"."); 2437 YYABORT; 2438 } 2439 2440 if ($3.node.ptr_choice->iffeature_size) { 2441 tmp = realloc($3.node.ptr_choice->iffeature, $3.node.ptr_choice->iffeature_size * sizeof *tmp); 2442 if (!tmp) { 2443 LOGMEM(trg->ctx); 2444 YYABORT; 2445 } 2446 $3.node.ptr_choice->iffeature = tmp; 2447 } 2448 } 2449 2450choice_opt_stmt: @EMPTYDIR@ { $$.node.ptr_choice = actual; 2451 $$.node.flag = 0; 2452 } 2453 | choice_opt_stmt when_stmt stmtsep 2454 | choice_opt_stmt if_feature_stmt stmtsep 2455 | choice_opt_stmt default_stmt { if ($1.node.flag & LYS_CHOICE_DEFAULT) { 2456 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_choice, "default", "choice"); 2457 free(s); 2458 YYABORT; 2459 } 2460 $1.node.ptr_choice->dflt = (struct lys_node *) s; 2461 s = NULL; 2462 $$ = $1; 2463 $$.node.flag |= LYS_CHOICE_DEFAULT; 2464 } 2465 | choice_opt_stmt config_stmt { if ($1.node.ptr_choice->flags & LYS_CONFIG_MASK) { 2466 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_choice, "config", "choice"); 2467 YYABORT; 2468 } 2469 $1.node.ptr_choice->flags |= $2; 2470 $$ = $1; 2471 } 2472| choice_opt_stmt mandatory_stmt { if ($1.node.ptr_choice->flags & LYS_MAND_MASK) { 2473 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_choice, "mandatory", "choice"); 2474 YYABORT; 2475 } 2476 $1.node.ptr_choice->flags |= $2; 2477 $$ = $1; 2478 } 2479 | choice_opt_stmt status_stmt { if ($1.node.ptr_choice->flags & LYS_STATUS_MASK) { 2480 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_choice, "status", "choice"); 2481 YYABORT; 2482 } 2483 $1.node.ptr_choice->flags |= $2; 2484 $$ = $1; 2485 } 2486 | choice_opt_stmt description_stmt { if (yang_read_description(trg, $1.node.ptr_choice, s, "choice", NODE_PRINT)) { 2487 YYABORT; 2488 } 2489 s = NULL; 2490 $$ = $1; 2491 } 2492 | choice_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.node.ptr_choice, s, "choice", NODE_PRINT)) { 2493 YYABORT; 2494 } 2495 s = NULL; 2496 $$ = $1; 2497 } 2498 | choice_opt_stmt short_case_case_stmt stmtsep 2499 2500short_case_case_stmt: short_case_stmt 2501 | case_stmt 2502 2503short_case_stmt: container_stmt 2504 | leaf_stmt 2505 | leaf_list_stmt 2506 | list_stmt 2507 | anyxml_stmt 2508 | anydata_stmt 2509 | choice_stmt { if (trg->version < 2 ) { 2510 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_LYS, actual, "choice"); 2511 YYABORT; 2512 } 2513 } 2514 2515case_arg_str: identifier_arg_str { $$.token = actual_type; 2516 $$.actual = actual; 2517 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_CASE, sizeof(struct lys_node_case)))) { 2518 YYABORT; 2519 } 2520 data_node = actual; 2521 s = NULL; 2522 actual_type = CASE_KEYWORD; 2523 } 2524 2525case_stmt: CASE_KEYWORD sep case_arg_str case_end 2526 { LOGDBG(LY_LDGYANG, "finished parsing case statement \"%s\"", data_node->name); 2527 actual_type = $3.token; 2528 actual = $3.actual; 2529 data_node = $3.actual; 2530 } 2531 2532case_end: ';' 2533 | '{' stmtsep 2534 case_opt_stmt 2535 '}' { struct lys_iffeature *tmp; 2536 2537 if ($3.cs->iffeature_size) { 2538 tmp = realloc($3.cs->iffeature, $3.cs->iffeature_size * sizeof *tmp); 2539 if (!tmp) { 2540 LOGMEM(trg->ctx); 2541 YYABORT; 2542 } 2543 $3.cs->iffeature = tmp; 2544 } 2545 } 2546 2547case_opt_stmt: @EMPTYDIR@ { $$.cs = actual; } 2548 | case_opt_stmt when_stmt stmtsep 2549 | case_opt_stmt if_feature_stmt stmtsep 2550 | case_opt_stmt status_stmt { if ($1.cs->flags & LYS_STATUS_MASK) { 2551 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.cs, "status", "case"); 2552 YYABORT; 2553 } 2554 $1.cs->flags |= $2; 2555 } 2556 | case_opt_stmt description_stmt { if (yang_read_description(trg, $1.cs, s, "case", NODE_PRINT)) { 2557 YYABORT; 2558 } 2559 s = NULL; 2560 } 2561 | case_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.cs, s, "case", NODE_PRINT)) { 2562 YYABORT; 2563 } 2564 s = NULL; 2565 } 2566 | case_opt_stmt data_def_stmt stmtsep 2567 2568 2569anyxml_arg_str: identifier_arg_str { $$.token = actual_type; 2570 $$.actual = actual; 2571 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_ANYXML, sizeof(struct lys_node_anydata)))) { 2572 YYABORT; 2573 } 2574 data_node = actual; 2575 s = NULL; 2576 actual_type = ANYXML_KEYWORD; 2577 } 2578 2579anyxml_stmt: ANYXML_KEYWORD sep anyxml_arg_str anyxml_end 2580 { LOGDBG(LY_LDGYANG, "finished parsing anyxml statement \"%s\"", data_node->name); 2581 actual_type = $3.token; 2582 actual = $3.actual; 2583 data_node = $3.actual; 2584 } 2585 2586anydata_arg_str: identifier_arg_str { $$.token = actual_type; 2587 $$.actual = actual; 2588 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_ANYDATA, sizeof(struct lys_node_anydata)))) { 2589 YYABORT; 2590 } 2591 data_node = actual; 2592 s = NULL; 2593 actual_type = ANYDATA_KEYWORD; 2594 } 2595 2596anydata_stmt: ANYDATA_KEYWORD sep anydata_arg_str anyxml_end 2597 { LOGDBG(LY_LDGYANG, "finished parsing anydata statement \"%s\"", data_node->name); 2598 actual_type = $3.token; 2599 actual = $3.actual; 2600 data_node = $3.actual; 2601 } 2602 2603anyxml_end: ';' 2604 | '{' stmtsep 2605 anyxml_opt_stmt 2606 '}' { void *tmp; 2607 2608 if ($3.node.ptr_anydata->iffeature_size) { 2609 tmp = realloc($3.node.ptr_anydata->iffeature, $3.node.ptr_anydata->iffeature_size * sizeof *$3.node.ptr_anydata->iffeature); 2610 if (!tmp) { 2611 LOGMEM(trg->ctx); 2612 YYABORT; 2613 } 2614 $3.node.ptr_anydata->iffeature = tmp; 2615 } 2616 2617 if ($3.node.ptr_anydata->must_size) { 2618 tmp = realloc($3.node.ptr_anydata->must, $3.node.ptr_anydata->must_size * sizeof *$3.node.ptr_anydata->must); 2619 if (!tmp) { 2620 LOGMEM(trg->ctx); 2621 YYABORT; 2622 } 2623 $3.node.ptr_anydata->must = tmp; 2624 } 2625 } 2626 2627anyxml_opt_stmt: @EMPTYDIR@ { $$.node.ptr_anydata = actual; 2628 $$.node.flag = actual_type; 2629 } 2630 | anyxml_opt_stmt when_stmt stmtsep 2631 | anyxml_opt_stmt if_feature_stmt stmtsep 2632 | anyxml_opt_stmt must_stmt stmtsep 2633 | anyxml_opt_stmt config_stmt { if ($1.node.ptr_anydata->flags & LYS_CONFIG_MASK) { 2634 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_anydata, "config", 2635 ($1.node.flag == ANYXML_KEYWORD) ? "anyxml" : "anydata"); 2636 YYABORT; 2637 } 2638 $1.node.ptr_anydata->flags |= $2; 2639 } 2640 | anyxml_opt_stmt mandatory_stmt { if ($1.node.ptr_anydata->flags & LYS_MAND_MASK) { 2641 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_anydata, "mandatory", 2642 ($1.node.flag == ANYXML_KEYWORD) ? "anyxml" : "anydata"); 2643 YYABORT; 2644 } 2645 $1.node.ptr_anydata->flags |= $2; 2646 } 2647 | anyxml_opt_stmt status_stmt { if ($1.node.ptr_anydata->flags & LYS_STATUS_MASK) { 2648 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_anydata, "status", 2649 ($1.node.flag == ANYXML_KEYWORD) ? "anyxml" : "anydata"); 2650 YYABORT; 2651 } 2652 $1.node.ptr_anydata->flags |= $2; 2653 } 2654 | anyxml_opt_stmt description_stmt { if (yang_read_description(trg, $1.node.ptr_anydata, s, ($1.node.flag == ANYXML_KEYWORD) ? "anyxml" : "anydata", NODE_PRINT)) { 2655 YYABORT; 2656 } 2657 s = NULL; 2658 } 2659 | anyxml_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.node.ptr_anydata, s, ($1.node.flag == ANYXML_KEYWORD) ? "anyxml" : "anydata", NODE_PRINT)) { 2660 YYABORT; 2661 } 2662 s = NULL; 2663 } 2664 2665uses_arg_str: identifier_ref_arg_str { $$.token = actual_type; 2666 $$.actual = actual; 2667 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_USES, sizeof(struct lys_node_uses)))) { 2668 YYABORT; 2669 } 2670 data_node = actual; 2671 s = NULL; 2672 actual_type = USES_KEYWORD; 2673 } 2674 2675uses_stmt: USES_KEYWORD sep uses_arg_str uses_end 2676 { LOGDBG(LY_LDGYANG, "finished parsing uses statement \"%s\"", data_node->name); 2677 actual_type = $3.token; 2678 actual = $3.actual; 2679 data_node = $3.actual; 2680 } 2681 2682uses_end: ';' 2683 | '{' stmtsep 2684 uses_opt_stmt 2685 '}' { void *tmp; 2686 2687 if ($3.uses->iffeature_size) { 2688 tmp = realloc($3.uses->iffeature, $3.uses->iffeature_size * sizeof *$3.uses->iffeature); 2689 if (!tmp) { 2690 LOGMEM(trg->ctx); 2691 YYABORT; 2692 } 2693 $3.uses->iffeature = tmp; 2694 } 2695 2696 if ($3.uses->refine_size) { 2697 tmp = realloc($3.uses->refine, $3.uses->refine_size * sizeof *$3.uses->refine); 2698 if (!tmp) { 2699 LOGMEM(trg->ctx); 2700 YYABORT; 2701 } 2702 $3.uses->refine = tmp; 2703 } 2704 2705 if ($3.uses->augment_size) { 2706 tmp = realloc($3.uses->augment, $3.uses->augment_size * sizeof *$3.uses->augment); 2707 if (!tmp) { 2708 LOGMEM(trg->ctx); 2709 YYABORT; 2710 } 2711 $3.uses->augment = tmp; 2712 } 2713 } 2714 2715uses_opt_stmt: @EMPTYDIR@ { $$.uses = actual; } 2716 | uses_opt_stmt when_stmt stmtsep 2717 | uses_opt_stmt if_feature_stmt stmtsep 2718 | uses_opt_stmt status_stmt { if ($1.uses->flags & LYS_STATUS_MASK) { 2719 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.uses, "status", "uses"); 2720 YYABORT; 2721 } 2722 $1.uses->flags |= $2; 2723 } 2724 | uses_opt_stmt description_stmt { if (yang_read_description(trg, $1.uses, s, "uses", NODE_PRINT)) { 2725 YYABORT; 2726 } 2727 s = NULL; 2728 } 2729 | uses_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.uses, s, "uses", NODE_PRINT)) { 2730 YYABORT; 2731 } 2732 s = NULL; 2733 } 2734 | uses_opt_stmt refine_stmt stmtsep 2735 | uses_opt_stmt uses_augment_stmt stmtsep 2736 2737refine_args_str: descendant_schema_nodeid optsep 2738 | string_1 2739 2740refine_arg_str: refine_args_str { $$.token = actual_type; 2741 $$.actual = actual; 2742 YANG_ADDELEM(((struct lys_node_uses *)actual)->refine, 2743 ((struct lys_node_uses *)actual)->refine_size, "refines"); 2744 ((struct lys_refine *)actual)->target_name = transform_schema2json(trg, s); 2745 free(s); 2746 s = NULL; 2747 if (!((struct lys_refine *)actual)->target_name) { 2748 YYABORT; 2749 } 2750 actual_type = REFINE_KEYWORD; 2751 } 2752 2753refine_stmt: REFINE_KEYWORD sep refine_arg_str refine_end 2754 { actual_type = $3.token; 2755 actual = $3.actual; 2756 } 2757 2758refine_end: ';' 2759 | '{' stmtsep 2760 refine_body_opt_stmts 2761 '}' { void *tmp; 2762 2763 if ($3.refine->iffeature_size) { 2764 tmp = realloc($3.refine->iffeature, $3.refine->iffeature_size * sizeof *$3.refine->iffeature); 2765 if (!tmp) { 2766 LOGMEM(trg->ctx); 2767 YYABORT; 2768 } 2769 $3.refine->iffeature = tmp; 2770 } 2771 2772 if ($3.refine->must_size) { 2773 tmp = realloc($3.refine->must, $3.refine->must_size * sizeof *$3.refine->must); 2774 if (!tmp) { 2775 LOGMEM(trg->ctx); 2776 YYABORT; 2777 } 2778 $3.refine->must = tmp; 2779 } 2780 2781 if ($3.refine->dflt_size) { 2782 tmp = realloc($3.refine->dflt, $3.refine->dflt_size * sizeof *$3.refine->dflt); 2783 if (!tmp) { 2784 LOGMEM(trg->ctx); 2785 YYABORT; 2786 } 2787 $3.refine->dflt = tmp; 2788 } 2789 } 2790 2791refine_body_opt_stmts: @EMPTYDIR@ { $$.refine = actual; 2792 actual_type = REFINE_KEYWORD; 2793 } 2794 | refine_body_opt_stmts must_stmt stmtsep { actual = $1.refine; 2795 actual_type = REFINE_KEYWORD; 2796 if ($1.refine->target_type) { 2797 if ($1.refine->target_type & (LYS_LEAF | LYS_LIST | LYS_LEAFLIST | LYS_CONTAINER | LYS_ANYDATA)) { 2798 $1.refine->target_type &= (LYS_LEAF | LYS_LIST | LYS_LEAFLIST | LYS_CONTAINER | LYS_ANYDATA); 2799 } else { 2800 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "must", "refine"); 2801 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid refine target nodetype for the substatements."); 2802 YYABORT; 2803 } 2804 } else { 2805 $1.refine->target_type = LYS_LEAF | LYS_LIST | LYS_LEAFLIST | LYS_CONTAINER | LYS_ANYDATA; 2806 } 2807 } 2808 | refine_body_opt_stmts if_feature_stmt 2809 stmtsep { /* leaf, leaf-list, list, container, choice, case, anydata or anyxml */ 2810 /* check possibility of statements combination */ 2811 if ($1.refine->target_type) { 2812 if ($1.refine->target_type & (LYS_LEAF | LYS_LIST | LYS_LEAFLIST | LYS_CONTAINER | LYS_CHOICE | LYS_CASE | LYS_ANYDATA)) { 2813 $1.refine->target_type &= (LYS_LEAF | LYS_LIST | LYS_LEAFLIST | LYS_CONTAINER | LYS_CHOICE | LYS_CASE | LYS_ANYDATA); 2814 } else { 2815 free(s); 2816 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "if-feature", "refine"); 2817 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid refine target nodetype for the substatements."); 2818 YYABORT; 2819 } 2820 } else { 2821 $1.refine->target_type = LYS_LEAF | LYS_LIST | LYS_LEAFLIST | LYS_CONTAINER | LYS_CHOICE | LYS_CASE | LYS_ANYDATA; 2822 } 2823 } 2824 | refine_body_opt_stmts presence_stmt { if ($1.refine->target_type) { 2825 if ($1.refine->target_type & LYS_CONTAINER) { 2826 if ($1.refine->mod.presence) { 2827 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "presence", "refine"); 2828 free(s); 2829 YYABORT; 2830 } 2831 $1.refine->target_type = LYS_CONTAINER; 2832 $1.refine->mod.presence = lydict_insert_zc(trg->ctx, s); 2833 } else { 2834 free(s); 2835 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "presence", "refine"); 2836 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid refine target nodetype for the substatements."); 2837 YYABORT; 2838 } 2839 } else { 2840 $1.refine->target_type = LYS_CONTAINER; 2841 $1.refine->mod.presence = lydict_insert_zc(trg->ctx, s); 2842 } 2843 s = NULL; 2844 $$ = $1; 2845 } 2846 | refine_body_opt_stmts default_stmt { int i; 2847 2848 if ($1.refine->dflt_size) { 2849 if (trg->version < 2) { 2850 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "default", "refine"); 2851 YYABORT; 2852 } 2853 if ($1.refine->target_type & LYS_LEAFLIST) { 2854 $1.refine->target_type = LYS_LEAFLIST; 2855 } else { 2856 free(s); 2857 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "default", "refine"); 2858 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid refine target nodetype for the substatements."); 2859 YYABORT; 2860 } 2861 } else { 2862 if ($1.refine->target_type) { 2863 if (trg->version < 2 && ($1.refine->target_type & (LYS_LEAF | LYS_CHOICE))) { 2864 $1.refine->target_type &= (LYS_LEAF | LYS_CHOICE); 2865 } if (trg->version > 1 && ($1.refine->target_type & (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE))) { 2866 /* YANG 1.1 */ 2867 $1.refine->target_type &= (LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE); 2868 } else { 2869 free(s); 2870 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "default", "refine"); 2871 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid refine target nodetype for the substatements."); 2872 YYABORT; 2873 } 2874 } else { 2875 if (trg->version < 2) { 2876 $1.refine->target_type = LYS_LEAF | LYS_CHOICE; 2877 } else { 2878 /* YANG 1.1 */ 2879 $1.refine->target_type = LYS_LEAF | LYS_LEAFLIST | LYS_CHOICE; 2880 } 2881 } 2882 } 2883 /* check for duplicity */ 2884 for (i = 0; i < $1.refine->dflt_size; ++i) { 2885 if (ly_strequal($1.refine->dflt[i], s, 0)) { 2886 LOGVAL(trg->ctx, LYE_INARG, LY_VLOG_NONE, NULL, s, "default"); 2887 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Duplicated default value \"%s\".", s); 2888 YYABORT; 2889 } 2890 } 2891 YANG_ADDELEM($1.refine->dflt, $1.refine->dflt_size, "defaults"); 2892 *((const char **)actual) = lydict_insert_zc(trg->ctx, s); 2893 actual = $1.refine; 2894 s = NULL; 2895 $$ = $1; 2896 } 2897 | refine_body_opt_stmts config_stmt { if ($1.refine->target_type) { 2898 if ($1.refine->target_type & (LYS_LEAF | LYS_CHOICE | LYS_LIST | LYS_CONTAINER | LYS_LEAFLIST)) { 2899 $1.refine->target_type &= (LYS_LEAF | LYS_CHOICE | LYS_LIST | LYS_CONTAINER | LYS_LEAFLIST); 2900 if ($1.refine->flags & LYS_CONFIG_MASK) { 2901 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "config", "refine"); 2902 YYABORT; 2903 } 2904 $1.refine->flags |= $2; 2905 } else { 2906 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "config", "refine"); 2907 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid refine target nodetype for the substatements."); 2908 YYABORT; 2909 } 2910 } else { 2911 $1.refine->target_type = LYS_LEAF | LYS_CHOICE | LYS_LIST | LYS_CONTAINER | LYS_LEAFLIST; 2912 $1.refine->flags |= $2; 2913 } 2914 $$ = $1; 2915 } 2916 | refine_body_opt_stmts mandatory_stmt { if ($1.refine->target_type) { 2917 if ($1.refine->target_type & (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA)) { 2918 $1.refine->target_type &= (LYS_LEAF | LYS_CHOICE | LYS_ANYDATA); 2919 if ($1.refine->flags & LYS_MAND_MASK) { 2920 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "mandatory", "refine"); 2921 YYABORT; 2922 } 2923 $1.refine->flags |= $2; 2924 } else { 2925 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "mandatory", "refine"); 2926 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid refine target nodetype for the substatements."); 2927 YYABORT; 2928 } 2929 } else { 2930 $1.refine->target_type = LYS_LEAF | LYS_CHOICE | LYS_ANYDATA; 2931 $1.refine->flags |= $2; 2932 } 2933 $$ = $1; 2934 } 2935 | refine_body_opt_stmts min_elements_stmt { if ($1.refine->target_type) { 2936 if ($1.refine->target_type & (LYS_LIST | LYS_LEAFLIST)) { 2937 $1.refine->target_type &= (LYS_LIST | LYS_LEAFLIST); 2938 if ($1.refine->flags & LYS_RFN_MINSET) { 2939 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "min-elements", "refine"); 2940 YYABORT; 2941 } 2942 $1.refine->flags |= LYS_RFN_MINSET; 2943 $1.refine->mod.list.min = $2; 2944 } else { 2945 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "min-elements", "refine"); 2946 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid refine target nodetype for the substatements."); 2947 YYABORT; 2948 } 2949 } else { 2950 $1.refine->target_type = LYS_LIST | LYS_LEAFLIST; 2951 $1.refine->flags |= LYS_RFN_MINSET; 2952 $1.refine->mod.list.min = $2; 2953 } 2954 $$ = $1; 2955 } 2956 | refine_body_opt_stmts max_elements_stmt { if ($1.refine->target_type) { 2957 if ($1.refine->target_type & (LYS_LIST | LYS_LEAFLIST)) { 2958 $1.refine->target_type &= (LYS_LIST | LYS_LEAFLIST); 2959 if ($1.refine->flags & LYS_RFN_MAXSET) { 2960 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "max-elements", "refine"); 2961 YYABORT; 2962 } 2963 $1.refine->flags |= LYS_RFN_MAXSET; 2964 $1.refine->mod.list.max = $2; 2965 } else { 2966 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "max-elements", "refine"); 2967 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid refine target nodetype for the substatements."); 2968 YYABORT; 2969 } 2970 } else { 2971 $1.refine->target_type = LYS_LIST | LYS_LEAFLIST; 2972 $1.refine->flags |= LYS_RFN_MAXSET; 2973 $1.refine->mod.list.max = $2; 2974 } 2975 $$ = $1; 2976 } 2977 | refine_body_opt_stmts description_stmt { if (yang_read_description(trg, $1.refine, s, "refine", NODE)) { 2978 YYABORT; 2979 } 2980 s = NULL; 2981 } 2982 | refine_body_opt_stmts reference_stmt { if (yang_read_reference(trg, $1.refine, s, "refine", NODE)) { 2983 YYABORT; 2984 } 2985 s = NULL; 2986 } 2987 2988uses_augment_arg_str: descendant_schema_nodeid optsep 2989 | string_1 2990 ; 2991 2992uses_augment_arg: uses_augment_arg_str { void *parent; 2993 2994 $$.token = actual_type; 2995 $$.actual = actual; 2996 parent = actual; 2997 YANG_ADDELEM(((struct lys_node_uses *)actual)->augment, 2998 ((struct lys_node_uses *)actual)->augment_size, "augments"); 2999 if (yang_read_augment(trg, parent, actual, s)) { 3000 YYABORT; 3001 } 3002 data_node = actual; 3003 s = NULL; 3004 actual_type = AUGMENT_KEYWORD; 3005 } 3006 3007uses_augment_stmt: AUGMENT_KEYWORD sep uses_augment_arg 3008 '{' stmtsep 3009 augment_opt_stmt 3010 '}' { LOGDBG(LY_LDGYANG, "finished parsing augment statement \"%s\"", data_node->name); 3011 actual_type = $3.token; 3012 actual = $3.actual; 3013 data_node = $3.actual; 3014 } 3015 3016augment_arg_str: absolute_schema_nodeids optsep 3017 | string_1 3018 3019augment_arg: augment_arg_str { $$.token = actual_type; 3020 $$.actual = actual; 3021 YANG_ADDELEM(trg->augment, trg->augment_size, "augments"); 3022 if (yang_read_augment(trg, NULL, actual, s)) { 3023 YYABORT; 3024 } 3025 data_node = actual; 3026 s = NULL; 3027 actual_type = AUGMENT_KEYWORD; 3028 } 3029 3030augment_stmt: AUGMENT_KEYWORD sep augment_arg 3031 '{' stmtsep 3032 augment_opt_stmt 3033 '}' { LOGDBG(LY_LDGYANG, "finished parsing augment statement \"%s\"", data_node->name); 3034 actual_type = $3.token; 3035 actual = $3.actual; 3036 data_node = $3.actual; 3037 } 3038 3039augment_opt_stmt: @EMPTYDIR@ { $$.augment = actual; } 3040 | augment_opt_stmt when_stmt stmtsep 3041 | augment_opt_stmt if_feature_stmt stmtsep 3042 | augment_opt_stmt status_stmt { if ($1.augment->flags & LYS_STATUS_MASK) { 3043 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.augment, "status", "augment"); 3044 YYABORT; 3045 } 3046 $1.augment->flags |= $2; 3047 } 3048 | augment_opt_stmt description_stmt { if (yang_read_description(trg, $1.augment, s, "augment", NODE_PRINT)) { 3049 YYABORT; 3050 } 3051 s = NULL; 3052 } 3053 | augment_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.augment, s, "augment", NODE_PRINT)) { 3054 YYABORT; 3055 } 3056 s = NULL; 3057 } 3058 | augment_opt_stmt data_def_stmt stmtsep 3059 | augment_opt_stmt action_stmt stmtsep 3060 | augment_opt_stmt notification_stmt stmtsep { if (trg->version < 2) { 3061 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_LYS, $1.augment, "notification"); 3062 YYABORT; 3063 } 3064 } 3065 | augment_opt_stmt case_stmt stmtsep 3066 3067action_arg_str: identifier_arg_str { if (param->module->version != 2) { 3068 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_LYS, actual, "action"); 3069 free(s); 3070 YYABORT; 3071 } 3072 $$.token = actual_type; 3073 $$.actual = actual; 3074 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_ACTION, sizeof(struct lys_node_rpc_action)))) { 3075 YYABORT; 3076 } 3077 data_node = actual; 3078 s = NULL; 3079 actual_type = ACTION_KEYWORD; 3080 } 3081 3082action_stmt: ACTION_KEYWORD sep action_arg_str rpc_end 3083 { LOGDBG(LY_LDGYANG, "finished parsing action statement \"%s\"", data_node->name); 3084 actual_type = $3.token; 3085 actual = $3.actual; 3086 data_node = $3.actual; 3087 } 3088 3089rpc_arg_str: identifier_arg_str { $$.token = actual_type; 3090 $$.actual = actual; 3091 if (!(actual = yang_read_node(trg, NULL, param->node, s, LYS_RPC, sizeof(struct lys_node_rpc_action)))) { 3092 YYABORT; 3093 } 3094 data_node = actual; 3095 s = NULL; 3096 actual_type = RPC_KEYWORD; 3097 } 3098 3099rpc_stmt: RPC_KEYWORD sep rpc_arg_str rpc_end 3100 { LOGDBG(LY_LDGYANG, "finished parsing rpc statement \"%s\"", data_node->name); 3101 actual_type = $3.token; 3102 actual = $3.actual; 3103 data_node = $3.actual; 3104 } 3105 3106rpc_end: ';' 3107 | '{' stmtsep 3108 rpc_opt_stmt 3109 '}' { void *tmp; 3110 3111 if ($3.node.ptr_rpc->iffeature_size) { 3112 tmp = realloc($3.node.ptr_rpc->iffeature, $3.node.ptr_rpc->iffeature_size * sizeof *$3.node.ptr_rpc->iffeature); 3113 if (!tmp) { 3114 LOGMEM(trg->ctx); 3115 YYABORT; 3116 } 3117 $3.node.ptr_rpc->iffeature = tmp; 3118 } 3119 3120 if ($3.node.ptr_rpc->tpdf_size) { 3121 tmp = realloc($3.node.ptr_rpc->tpdf, $3.node.ptr_rpc->tpdf_size * sizeof *$3.node.ptr_rpc->tpdf); 3122 if (!tmp) { 3123 LOGMEM(trg->ctx); 3124 YYABORT; 3125 } 3126 $3.node.ptr_rpc->tpdf = tmp; 3127 } 3128 } 3129 3130 3131rpc_opt_stmt: @EMPTYDIR@ { $$.node.ptr_rpc = actual; 3132 $$.node.flag = 0; 3133 } 3134 | rpc_opt_stmt if_feature_stmt stmtsep 3135 | rpc_opt_stmt status_stmt { if ($1.node.ptr_rpc->flags & LYS_STATUS_MASK) { 3136 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_rpc, "status", "rpc"); 3137 YYABORT; 3138 } 3139 $1.node.ptr_rpc->flags |= $2; 3140 } 3141 | rpc_opt_stmt description_stmt { if (yang_read_description(trg, $1.node.ptr_rpc, s, "rpc", NODE_PRINT)) { 3142 YYABORT; 3143 } 3144 s = NULL; 3145 } 3146 | rpc_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.node.ptr_rpc, s, "rpc", NODE_PRINT)) { 3147 YYABORT; 3148 } 3149 s = NULL; 3150 } 3151 | rpc_opt_stmt typedef_stmt stmtsep 3152 | rpc_opt_stmt grouping_stmt stmtsep 3153 | rpc_opt_stmt input_stmt stmtsep { if ($1.node.flag & LYS_RPC_INPUT) { 3154 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_rpc, "input", "rpc"); 3155 YYABORT; 3156 } 3157 $1.node.flag |= LYS_RPC_INPUT; 3158 $$ = $1; 3159 } 3160 | rpc_opt_stmt output_stmt stmtsep { if ($1.node.flag & LYS_RPC_OUTPUT) { 3161 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.node.ptr_rpc, "output", "rpc"); 3162 YYABORT; 3163 } 3164 $1.node.flag |= LYS_RPC_OUTPUT; 3165 $$ = $1; 3166 } 3167 3168input_arg: INPUT_KEYWORD optsep { $$.token = actual_type; 3169 $$.actual = actual; 3170 s = strdup("input"); 3171 if (!s) { 3172 LOGMEM(trg->ctx); 3173 YYABORT; 3174 } 3175 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_INPUT, sizeof(struct lys_node_inout)))) { 3176 YYABORT; 3177 } 3178 data_node = actual; 3179 s = NULL; 3180 actual_type = INPUT_KEYWORD; 3181 } 3182 3183input_stmt: input_arg 3184 '{' stmtsep 3185 input_output_opt_stmt 3186 '}' { void *tmp; 3187 struct lys_node_inout *input = actual; 3188 3189 if (input->must_size) { 3190 tmp = realloc(input->must, input->must_size * sizeof *input->must); 3191 if (!tmp) { 3192 LOGMEM(trg->ctx); 3193 YYABORT; 3194 } 3195 input->must = tmp; 3196 } 3197 3198 if (input->tpdf_size) { 3199 tmp = realloc(input->tpdf, input->tpdf_size * sizeof *input->tpdf); 3200 if (!tmp) { 3201 LOGMEM(trg->ctx); 3202 YYABORT; 3203 } 3204 input->tpdf = tmp; 3205 } 3206 3207 LOGDBG(LY_LDGYANG, "finished parsing input statement \"%s\"", data_node->name); 3208 actual_type = $1.token; 3209 actual = $1.actual; 3210 data_node = $1.actual; 3211 } 3212 3213input_output_opt_stmt: @EMPTYDIR@ 3214 | input_output_opt_stmt must_stmt stmtsep 3215 | input_output_opt_stmt typedef_stmt stmtsep 3216 | input_output_opt_stmt grouping_stmt stmtsep 3217 | input_output_opt_stmt data_def_stmt stmtsep 3218 3219output_arg: OUTPUT_KEYWORD optsep { $$.token = actual_type; 3220 $$.actual = actual; 3221 s = strdup("output"); 3222 if (!s) { 3223 LOGMEM(trg->ctx); 3224 YYABORT; 3225 } 3226 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_OUTPUT, sizeof(struct lys_node_inout)))) { 3227 YYABORT; 3228 } 3229 data_node = actual; 3230 s = NULL; 3231 actual_type = OUTPUT_KEYWORD; 3232 } 3233 3234output_stmt: output_arg 3235 '{' stmtsep 3236 input_output_opt_stmt 3237 '}' { void *tmp; 3238 struct lys_node_inout *output = actual; 3239 3240 if (output->must_size) { 3241 tmp = realloc(output->must, output->must_size * sizeof *output->must); 3242 if (!tmp) { 3243 LOGMEM(trg->ctx); 3244 YYABORT; 3245 } 3246 output->must = tmp; 3247 } 3248 3249 if (output->tpdf_size) { 3250 tmp = realloc(output->tpdf, output->tpdf_size * sizeof *output->tpdf); 3251 if (!tmp) { 3252 LOGMEM(trg->ctx); 3253 YYABORT; 3254 } 3255 output->tpdf = tmp; 3256 } 3257 3258 LOGDBG(LY_LDGYANG, "finished parsing output statement \"%s\"", data_node->name); 3259 actual_type = $1.token; 3260 actual = $1.actual; 3261 data_node = $1.actual; 3262 } 3263 3264notification_arg_str: identifier_arg_str { $$.token = actual_type; 3265 $$.actual = actual; 3266 if (!(actual = yang_read_node(trg, actual, param->node, s, LYS_NOTIF, sizeof(struct lys_node_notif)))) { 3267 YYABORT; 3268 } 3269 data_node = actual; 3270 s = NULL; 3271 actual_type = NOTIFICATION_KEYWORD; 3272 } 3273 3274notification_stmt: NOTIFICATION_KEYWORD sep notification_arg_str notification_end 3275 { LOGDBG(LY_LDGYANG, "finished parsing notification statement \"%s\"", data_node->name); 3276 actual_type = $3.token; 3277 actual = $3.actual; 3278 data_node = $3.actual; 3279 } 3280 3281notification_end: ';' 3282 | '{' stmtsep 3283 notification_opt_stmt 3284 '}' { void *tmp; 3285 3286 if ($3.notif->must_size) { 3287 tmp = realloc($3.notif->must, $3.notif->must_size * sizeof *$3.notif->must); 3288 if (!tmp) { 3289 LOGMEM(trg->ctx); 3290 YYABORT; 3291 } 3292 $3.notif->must = tmp; 3293 } 3294 3295 if ($3.notif->iffeature_size) { 3296 tmp = realloc($3.notif->iffeature, $3.notif->iffeature_size * sizeof *$3.notif->iffeature); 3297 if (!tmp) { 3298 LOGMEM(trg->ctx); 3299 YYABORT; 3300 } 3301 $3.notif->iffeature = tmp; 3302 } 3303 3304 if ($3.notif->tpdf_size) { 3305 tmp = realloc($3.notif->tpdf, $3.notif->tpdf_size * sizeof *$3.notif->tpdf); 3306 if (!tmp) { 3307 LOGMEM(trg->ctx); 3308 YYABORT; 3309 } 3310 $3.notif->tpdf = tmp; 3311 } 3312 } 3313 3314notification_opt_stmt: @EMPTYDIR@ { $$.notif = actual; } 3315 | notification_opt_stmt must_stmt stmtsep 3316 | notification_opt_stmt if_feature_stmt stmtsep 3317 | notification_opt_stmt status_stmt { if ($1.notif->flags & LYS_STATUS_MASK) { 3318 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_LYS, $1.notif, "status", "notification"); 3319 YYABORT; 3320 } 3321 $1.notif->flags |= $2; 3322 } 3323 | notification_opt_stmt description_stmt { if (yang_read_description(trg, $1.notif, s, "notification", NODE_PRINT)) { 3324 YYABORT; 3325 } 3326 s = NULL; 3327 } 3328 | notification_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.notif, s, "notification", NODE_PRINT)) { 3329 YYABORT; 3330 } 3331 s = NULL; 3332 } 3333 | notification_opt_stmt typedef_stmt stmtsep 3334 | notification_opt_stmt grouping_stmt stmtsep 3335 | notification_opt_stmt data_def_stmt stmtsep 3336 3337deviation_arg: deviation_arg_str { $$.token = actual_type; 3338 $$.actual = actual; 3339 YANG_ADDELEM(trg->deviation, trg->deviation_size, "deviations"); 3340 ((struct lys_deviation *)actual)->target_name = transform_schema2json(trg, s); 3341 free(s); 3342 if (!((struct lys_deviation *)actual)->target_name) { 3343 YYABORT; 3344 } 3345 s = NULL; 3346 actual_type = DEVIATION_KEYWORD; 3347 } 3348 3349deviation_stmt: DEVIATION_KEYWORD sep deviation_arg 3350 '{' stmtsep 3351 deviation_opt_stmt 3352 '}' { void *tmp; 3353 3354 if ($6->deviate_size) { 3355 tmp = realloc($6->deviate, $6->deviate_size * sizeof *$6->deviate); 3356 if (!tmp) { 3357 LOGINT(trg->ctx); 3358 YYABORT; 3359 } 3360 $6->deviate = tmp; 3361 } else { 3362 LOGVAL(trg->ctx, LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "deviate", "deviation"); 3363 YYABORT; 3364 } 3365 actual_type = $3.token; 3366 actual = $3.actual; 3367 } 3368 3369deviation_opt_stmt: @EMPTYDIR@ { $$ = actual; } 3370 | deviation_opt_stmt description_stmt { if (yang_read_description(trg, $1, s, "deviation", NODE)) { 3371 YYABORT; 3372 } 3373 s = NULL; 3374 $$ = $1; 3375 } 3376 | deviation_opt_stmt reference_stmt { if (yang_read_reference(trg, $1, s, "deviation", NODE)) { 3377 YYABORT; 3378 } 3379 s = NULL; 3380 $$ = $1; 3381 } 3382 | deviation_opt_stmt DEVIATE_KEYWORD sep deviate_body_stmt stmtsep 3383 3384deviation_arg_str: absolute_schema_nodeids optsep 3385 | string_1 3386 3387deviate_body_stmt: deviate_not_supported_stmt 3388 | deviate_stmts 3389 3390 3391deviate_not_supported: NOT_SUPPORTED_KEYWORD { $$.token = actual_type; 3392 $$.actual = actual; 3393 if (!(actual = yang_read_deviate_unsupported(trg->ctx, actual))) { 3394 YYABORT; 3395 } 3396 actual_type = NOT_SUPPORTED_KEYWORD; 3397 } 3398 3399deviate_not_supported_stmt: deviate_not_supported optsep deviate_not_supported_end 3400 { actual_type = $1.token; 3401 actual = $1.actual; 3402 } 3403 3404deviate_not_supported_end: ';' 3405 | '{' stmtsep '}' 3406 3407deviate_stmts: deviate_add_stmt 3408 | deviate_replace_stmt 3409 | deviate_delete_stmt 3410 3411deviate_add: ADD_KEYWORD { $$.token = actual_type; 3412 $$.actual = actual; 3413 if (!(actual = yang_read_deviate(trg->ctx, actual, LY_DEVIATE_ADD))) { 3414 YYABORT; 3415 } 3416 actual_type = ADD_KEYWORD; 3417 } 3418 3419deviate_add_stmt: deviate_add optsep deviate_add_end 3420 { actual_type = $1.token; 3421 actual = $1.actual; 3422 } 3423 3424deviate_add_end: ';' 3425 | '{' stmtsep 3426 deviate_add_opt_stmt 3427 '}' { void *tmp; 3428 3429 if ($3->must_size) { 3430 tmp = realloc($3->must, $3->must_size * sizeof *$3->must); 3431 if (!tmp) { 3432 LOGMEM(trg->ctx); 3433 YYABORT; 3434 } 3435 $3->must = tmp; 3436 } 3437 3438 if ($3->unique_size) { 3439 tmp = realloc($3->unique, $3->unique_size * sizeof *$3->unique); 3440 if (!tmp) { 3441 LOGMEM(trg->ctx); 3442 YYABORT; 3443 } 3444 $3->unique = tmp; 3445 } 3446 3447 if ($3->dflt_size) { 3448 tmp = realloc($3->dflt, $3->dflt_size * sizeof *$3->dflt); 3449 if (!tmp) { 3450 LOGMEM(trg->ctx); 3451 YYABORT; 3452 } 3453 $3->dflt = tmp; 3454 } 3455 } 3456 3457deviate_add_opt_stmt: @EMPTYDIR@ { $$ = actual; } 3458 | deviate_add_opt_stmt units_stmt { if (yang_read_units(trg, actual, s, ADD_KEYWORD)) { 3459 YYABORT; 3460 } 3461 s = NULL; 3462 $$ = $1; 3463 } 3464 | deviate_add_opt_stmt must_stmt stmtsep 3465 | deviate_add_opt_stmt unique_stmt { YANG_ADDELEM($1->unique, $1->unique_size, "uniques"); 3466 ((struct lys_unique *)actual)->expr = (const char **)s; 3467 s = NULL; 3468 actual = $1; 3469 $$= $1; 3470 } 3471 | deviate_add_opt_stmt default_stmt { YANG_ADDELEM($1->dflt, $1->dflt_size, "defaults"); 3472 *((const char **)actual) = lydict_insert_zc(trg->ctx, s); 3473 s = NULL; 3474 actual = $1; 3475 $$ = $1; 3476 } 3477 | deviate_add_opt_stmt config_stmt { if ($1->flags & LYS_CONFIG_MASK) { 3478 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "config", "deviate"); 3479 YYABORT; 3480 } 3481 $1->flags = $2; 3482 $$ = $1; 3483 } 3484 | deviate_add_opt_stmt mandatory_stmt { if ($1->flags & LYS_MAND_MASK) { 3485 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "mandatory", "deviate"); 3486 YYABORT; 3487 } 3488 $1->flags = $2; 3489 $$ = $1; 3490 } 3491 | deviate_add_opt_stmt min_elements_stmt { if ($1->min_set) { 3492 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "min-elements", "deviation"); 3493 YYABORT; 3494 } 3495 $1->min = $2; 3496 $1->min_set = 1; 3497 $$ = $1; 3498 } 3499 | deviate_add_opt_stmt max_elements_stmt { if ($1->max_set) { 3500 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "max-elements", "deviation"); 3501 YYABORT; 3502 } 3503 $1->max = $2; 3504 $1->max_set = 1; 3505 $$ = $1; 3506 } 3507 3508deviate_delete: DELETE_KEYWORD { $$.token = actual_type; 3509 $$.actual = actual; 3510 if (!(actual = yang_read_deviate(trg->ctx, actual, LY_DEVIATE_DEL))) { 3511 YYABORT; 3512 } 3513 actual_type = DELETE_KEYWORD; 3514 } 3515 3516deviate_delete_stmt: deviate_delete optsep deviate_delete_end 3517 { actual_type = $1.token; 3518 actual = $1.actual; 3519 } 3520 3521deviate_delete_end: ';' 3522 | '{' stmtsep 3523 deviate_delete_opt_stmt 3524 '}' { void *tmp; 3525 3526 if ($3->must_size) { 3527 tmp = realloc($3->must, $3->must_size * sizeof *$3->must); 3528 if (!tmp) { 3529 LOGMEM(trg->ctx); 3530 YYABORT; 3531 } 3532 $3->must = tmp; 3533 } 3534 3535 if ($3->unique_size) { 3536 tmp = realloc($3->unique, $3->unique_size * sizeof *$3->unique); 3537 if (!tmp) { 3538 LOGMEM(trg->ctx); 3539 YYABORT; 3540 } 3541 $3->unique = tmp; 3542 } 3543 3544 if ($3->dflt_size) { 3545 tmp = realloc($3->dflt, $3->dflt_size * sizeof *$3->dflt); 3546 if (!tmp) { 3547 LOGMEM(trg->ctx); 3548 YYABORT; 3549 } 3550 $3->dflt = tmp; 3551 } 3552 } 3553 3554deviate_delete_opt_stmt: @EMPTYDIR@ { $$ = actual; } 3555 | deviate_delete_opt_stmt units_stmt { if (yang_read_units(trg, actual, s, DELETE_KEYWORD)) { 3556 YYABORT; 3557 } 3558 s = NULL; 3559 $$ = $1; 3560 } 3561 | deviate_delete_opt_stmt must_stmt stmtsep 3562 | deviate_delete_opt_stmt unique_stmt { YANG_ADDELEM($1->unique, $1->unique_size, "uniques"); 3563 ((struct lys_unique *)actual)->expr = (const char **)s; 3564 s = NULL; 3565 actual = $1; 3566 $$ = $1; 3567 } 3568 | deviate_delete_opt_stmt default_stmt { YANG_ADDELEM($1->dflt, $1->dflt_size, "defaults"); 3569 *((const char **)actual) = lydict_insert_zc(trg->ctx, s); 3570 s = NULL; 3571 actual = $1; 3572 $$ = $1; 3573 } 3574 3575deviate_replace: REPLACE_KEYWORD { $$.token = actual_type; 3576 $$.actual = actual; 3577 if (!(actual = yang_read_deviate(trg->ctx, actual, LY_DEVIATE_RPL))) { 3578 YYABORT; 3579 } 3580 actual_type = REPLACE_KEYWORD; 3581 } 3582 3583deviate_replace_stmt: deviate_replace optsep deviate_replace_end 3584 { actual_type = $1.token; 3585 actual = $1.actual; 3586 } 3587 3588deviate_replace_end: ';' 3589 | '{' stmtsep 3590 deviate_replace_opt_stmt 3591 '}' { void *tmp; 3592 3593 if ($3->dflt_size) { 3594 tmp = realloc($3->dflt, $3->dflt_size * sizeof *$3->dflt); 3595 if (!tmp) { 3596 LOGMEM(trg->ctx); 3597 YYABORT; 3598 } 3599 $3->dflt = tmp; 3600 } 3601 } 3602 3603deviate_replace_opt_stmt: @EMPTYDIR@ { $$ = actual; } 3604 | deviate_replace_opt_stmt type_stmt stmtsep 3605 | deviate_replace_opt_stmt units_stmt { if (yang_read_units(trg, actual, s, DELETE_KEYWORD)) { 3606 YYABORT; 3607 } 3608 s = NULL; 3609 $$ = $1; 3610 } 3611 | deviate_replace_opt_stmt default_stmt { YANG_ADDELEM($1->dflt, $1->dflt_size, "defaults"); 3612 *((const char **)actual) = lydict_insert_zc(trg->ctx, s); 3613 s = NULL; 3614 actual = $1; 3615 $$ = $1; 3616 } 3617 | deviate_replace_opt_stmt config_stmt { if ($1->flags & LYS_CONFIG_MASK) { 3618 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "config", "deviate"); 3619 YYABORT; 3620 } 3621 $1->flags = $2; 3622 $$ = $1; 3623 } 3624 | deviate_replace_opt_stmt mandatory_stmt { if ($1->flags & LYS_MAND_MASK) { 3625 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "mandatory", "deviate"); 3626 YYABORT; 3627 } 3628 $1->flags = $2; 3629 $$ = $1; 3630 } 3631 | deviate_replace_opt_stmt min_elements_stmt { if ($1->min_set) { 3632 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "min-elements", "deviation"); 3633 YYABORT; 3634 } 3635 $1->min = $2; 3636 $1->min_set = 1; 3637 $$ = $1; 3638 } 3639 | deviate_replace_opt_stmt max_elements_stmt { if ($1->max_set) { 3640 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "max-elements", "deviation"); 3641 YYABORT; 3642 } 3643 $1->max = $2; 3644 $1->max_set = 1; 3645 $$ = $1; 3646 } 3647 3648when_arg_str: string { $$.token = actual_type; 3649 $$.actual = actual; 3650 if (!(actual = yang_read_when(trg, actual, actual_type, s))) { 3651 YYABORT; 3652 } 3653 s = NULL; 3654 actual_type = WHEN_KEYWORD; 3655 } 3656 3657when_stmt: WHEN_KEYWORD sep when_arg_str when_end 3658 { actual_type = $3.token; 3659 actual = $3.actual; 3660 } 3661 3662when_end: ';' 3663 | '{' stmtsep 3664 when_opt_stmt 3665 '}' 3666 3667when_opt_stmt: @EMPTYDIR@ 3668 | when_opt_stmt description_stmt { if (yang_read_description(trg, actual, s, "when", NODE)) { 3669 YYABORT; 3670 } 3671 s = NULL; 3672 } 3673 | when_opt_stmt reference_stmt { if (yang_read_reference(trg, actual, s, "when", NODE)) { 3674 YYABORT; 3675 } 3676 s = NULL; 3677 } 3678 3679config_arg: config_arg_str { $$ = $1; 3680 backup_type = actual_type; 3681 actual_type = CONFIG_KEYWORD; 3682 } 3683 3684config_stmt: CONFIG_KEYWORD sep config_arg stmtend { $$ = $3; } 3685 3686config_arg_str: TRUE_KEYWORD optsep { $$ = LYS_CONFIG_W | LYS_CONFIG_SET; } 3687 | FALSE_KEYWORD optsep { $$ = LYS_CONFIG_R | LYS_CONFIG_SET; } 3688 | string_1 { if (!strcmp(s, "true")) { 3689 $$ = LYS_CONFIG_W | LYS_CONFIG_SET; 3690 } else if (!strcmp(s, "false")) { 3691 $$ = LYS_CONFIG_R | LYS_CONFIG_SET; 3692 } else { 3693 LOGVAL(trg->ctx, LYE_INARG, LY_VLOG_NONE, NULL, s, "config"); 3694 free(s); 3695 YYABORT; 3696 } 3697 free(s); 3698 s = NULL; 3699 } 3700 3701mandatory_arg: mandatory_arg_str { $$ = $1; 3702 backup_type = actual_type; 3703 actual_type = MANDATORY_KEYWORD; 3704 } 3705 3706mandatory_stmt: MANDATORY_KEYWORD sep mandatory_arg stmtend { $$ = $3; } 3707 3708mandatory_arg_str: TRUE_KEYWORD optsep { $$ = LYS_MAND_TRUE; } 3709 | FALSE_KEYWORD optsep { $$ = LYS_MAND_FALSE; } 3710 | string_1 { if (!strcmp(s, "true")) { 3711 $$ = LYS_MAND_TRUE; 3712 } else if (!strcmp(s, "false")) { 3713 $$ = LYS_MAND_FALSE; 3714 } else { 3715 LOGVAL(trg->ctx, LYE_INARG, LY_VLOG_NONE, NULL, s, "mandatory"); 3716 free(s); 3717 YYABORT; 3718 } 3719 free(s); 3720 s = NULL; 3721 } 3722 3723presence_arg: string { backup_type = actual_type; 3724 actual_type = PRESENCE_KEYWORD; 3725 } 3726 3727presence_stmt: PRESENCE_KEYWORD sep presence_arg stmtend 3728 3729min_value_arg: min_value_arg_str { $$ = $1; 3730 backup_type = actual_type; 3731 actual_type = MIN_ELEMENTS_KEYWORD; 3732 } 3733 3734min_elements_stmt: MIN_ELEMENTS_KEYWORD sep min_value_arg stmtend { $$ = $3; } 3735 3736min_value_arg_str: non_negative_integer_value optsep { $$ = $1; } 3737 | string_1 { if (strlen(s) == 1 && s[0] == '0') { 3738 $$ = 0; 3739 } else { 3740 /* convert it to uint32_t */ 3741 uint64_t val; 3742 char *endptr = NULL; 3743 errno = 0; 3744 3745 val = strtoul(s, &endptr, 10); 3746 if (*endptr || s[0] == '-' || errno || val > UINT32_MAX) { 3747 LOGVAL(trg->ctx, LYE_INARG, LY_VLOG_NONE, NULL, s, "min-elements"); 3748 free(s); 3749 YYABORT; 3750 } 3751 $$ = (uint32_t) val; 3752 } 3753 free(s); 3754 s = NULL; 3755 } 3756 3757max_value_arg: max_value_arg_str { $$ = $1; 3758 backup_type = actual_type; 3759 actual_type = MAX_ELEMENTS_KEYWORD; 3760 } 3761 3762max_elements_stmt: MAX_ELEMENTS_KEYWORD sep max_value_arg stmtend { $$ = $3; } 3763 3764max_value_arg_str: UNBOUNDED_KEYWORD optsep { $$ = 0; } 3765 | positive_integer_value optsep { $$ = $1; } 3766 | string_1 { if (!strcmp(s, "unbounded")) { 3767 $$ = 0; 3768 } else { 3769 /* convert it to uint32_t */ 3770 uint64_t val; 3771 char *endptr = NULL; 3772 errno = 0; 3773 3774 val = strtoul(s, &endptr, 10); 3775 if (*endptr || s[0] == '-' || errno || val == 0 || val > UINT32_MAX) { 3776 LOGVAL(trg->ctx, LYE_INARG, LY_VLOG_NONE, NULL, s, "max-elements"); 3777 free(s); 3778 YYABORT; 3779 } 3780 $$ = (uint32_t) val; 3781 } 3782 free(s); 3783 s = NULL; 3784 } 3785 3786ordered_by_arg: ordered_by_arg_str { $$ = $1; 3787 backup_type = actual_type; 3788 actual_type = ORDERED_BY_KEYWORD; 3789 } 3790 3791ordered_by_stmt: ORDERED_BY_KEYWORD sep ordered_by_arg stmtend { $$ = $3; } 3792 3793ordered_by_arg_str: USER_KEYWORD optsep { $$ = LYS_USERORDERED; } 3794 | SYSTEM_KEYWORD optsep { $$ = LYS_SYSTEMORDERED; } 3795 | string_1 { if (!strcmp(s, "user")) { 3796 $$ = LYS_USERORDERED; 3797 } else if (!strcmp(s, "system")) { 3798 $$ = LYS_SYSTEMORDERED; 3799 } else { 3800 free(s); 3801 YYABORT; 3802 } 3803 free(s); 3804 s=NULL; 3805 } 3806 3807must_agr_str: string { $$.token = actual_type; 3808 $$.actual = actual; 3809 switch (actual_type) { 3810 case CONTAINER_KEYWORD: 3811 YANG_ADDELEM(((struct lys_node_container *)actual)->must, 3812 ((struct lys_node_container *)actual)->must_size, "musts"); 3813 break; 3814 case ANYDATA_KEYWORD: 3815 case ANYXML_KEYWORD: 3816 YANG_ADDELEM(((struct lys_node_anydata *)actual)->must, 3817 ((struct lys_node_anydata *)actual)->must_size, "musts"); 3818 break; 3819 case LEAF_KEYWORD: 3820 YANG_ADDELEM(((struct lys_node_leaf *)actual)->must, 3821 ((struct lys_node_leaf *)actual)->must_size, "musts"); 3822 break; 3823 case LEAF_LIST_KEYWORD: 3824 YANG_ADDELEM(((struct lys_node_leaflist *)actual)->must, 3825 ((struct lys_node_leaflist *)actual)->must_size, "musts"); 3826 break; 3827 case LIST_KEYWORD: 3828 YANG_ADDELEM(((struct lys_node_list *)actual)->must, 3829 ((struct lys_node_list *)actual)->must_size, "musts"); 3830 break; 3831 case REFINE_KEYWORD: 3832 YANG_ADDELEM(((struct lys_refine *)actual)->must, 3833 ((struct lys_refine *)actual)->must_size, "musts"); 3834 break; 3835 case ADD_KEYWORD: 3836 case DELETE_KEYWORD: 3837 YANG_ADDELEM(((struct lys_deviate *)actual)->must, 3838 ((struct lys_deviate *)actual)->must_size, "musts"); 3839 break; 3840 case NOTIFICATION_KEYWORD: 3841 if (trg->version < 2) { 3842 free(s); 3843 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_LYS, actual, "must"); 3844 YYABORT; 3845 } 3846 YANG_ADDELEM(((struct lys_node_notif *)actual)->must, 3847 ((struct lys_node_notif *)actual)->must_size, "musts"); 3848 break; 3849 case INPUT_KEYWORD: 3850 case OUTPUT_KEYWORD: 3851 if (trg->version < 2) { 3852 free(s); 3853 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_LYS, actual, "must"); 3854 YYABORT; 3855 } 3856 YANG_ADDELEM(((struct lys_node_inout *)actual)->must, 3857 ((struct lys_node_inout *)actual)->must_size, "musts"); 3858 break; 3859 case EXTENSION_INSTANCE: 3860 /* must is already allocated */ 3861 break; 3862 default: 3863 free(s); 3864 LOGINT(trg->ctx); 3865 YYABORT; 3866 } 3867 ((struct lys_restr *)actual)->expr = transform_schema2json(trg, s); 3868 free(s); 3869 if (!((struct lys_restr *)actual)->expr) { 3870 YYABORT; 3871 } 3872 s = NULL; 3873 actual_type = MUST_KEYWORD; 3874 } 3875 3876must_stmt: MUST_KEYWORD sep must_agr_str must_end 3877 { actual_type = $3.token; 3878 actual = $3.actual; 3879 } 3880 3881must_end: ';' 3882 | '{' stmtsep 3883 message_opt_stmt 3884 '}' 3885 3886unique_arg: unique_arg_str { backup_type = actual_type; 3887 actual_type = UNIQUE_KEYWORD; 3888 } 3889 3890unique_stmt: UNIQUE_KEYWORD sep unique_arg stmtend 3891 3892unique_arg_str: descendant_schema_nodeid optsep 3893 | string_1 3894 3895key_arg: key_arg_str { backup_type = actual_type; 3896 actual_type = KEY_KEYWORD; 3897 } 3898 3899key_stmt: KEY_KEYWORD sep key_arg stmtend; 3900 3901key_arg_str: node_identifier { s = strdup(yyget_text(scanner)); 3902 if (!s) { 3903 LOGMEM(trg->ctx); 3904 YYABORT; 3905 } 3906 } 3907 optsep 3908 | string_1 3909 ; 3910 3911range_arg_str: string { $$.token = actual_type; 3912 $$.actual = actual; 3913 if (!(actual = yang_read_range(trg->ctx, actual, s, is_ext_instance))) { 3914 YYABORT; 3915 } 3916 actual_type = RANGE_KEYWORD; 3917 s = NULL; 3918 } 3919 3920absolute_schema_nodeid: '/' node_identifier { if (s) { 3921 s = ly_realloc(s,strlen(s) + yyget_leng(scanner) + 2); 3922 if (!s) { 3923 LOGMEM(trg->ctx); 3924 YYABORT; 3925 } 3926 strcat(s,"/"); 3927 strcat(s, yyget_text(scanner)); 3928 } else { 3929 s = malloc(yyget_leng(scanner) + 2); 3930 if (!s) { 3931 LOGMEM(trg->ctx); 3932 YYABORT; 3933 } 3934 s[0]='/'; 3935 memcpy(s + 1, yyget_text(scanner), yyget_leng(scanner) + 1); 3936 } 3937 } 3938 3939absolute_schema_nodeids: absolute_schema_nodeid absolute_schema_nodeid_opt; 3940 3941absolute_schema_nodeid_opt: @EMPTYDIR@ 3942 | absolute_schema_nodeid_opt absolute_schema_nodeid 3943 ; 3944 3945descendant_schema_nodeid: node_identifier { if (s) { 3946 s = ly_realloc(s,strlen(s) + yyget_leng(scanner) + 1); 3947 if (!s) { 3948 LOGMEM(trg->ctx); 3949 YYABORT; 3950 } 3951 strcat(s, yyget_text(scanner)); 3952 } else { 3953 s = strdup(yyget_text(scanner)); 3954 if (!s) { 3955 LOGMEM(trg->ctx); 3956 YYABORT; 3957 } 3958 } 3959 } 3960 absolute_schema_nodeid_opt; 3961 3962path_arg_str: { tmp_s = yyget_text(scanner); } absolute_paths { s = strdup(tmp_s); 3963 if (!s) { 3964 LOGMEM(trg->ctx); 3965 YYABORT; 3966 } 3967 s[strlen(s) - 1] = '\0'; 3968 } 3969 | { tmp_s = yyget_text(scanner); } relative_path { s = strdup(tmp_s); 3970 if (!s) { 3971 LOGMEM(trg->ctx); 3972 YYABORT; 3973 } 3974 s[strlen(s) - 1] = '\0'; 3975 } 3976 | string_1 3977 ; 3978 3979absolute_path: '/' node_identifier path_predicate 3980 3981absolute_paths: absolute_path absolute_path_opt 3982 3983absolute_path_opt: @EMPTYDIR@ 3984 | absolute_path_opt absolute_path; 3985 3986relative_path: relative_path_part1 relative_path_part1_opt descendant_path 3987 3988relative_path_part1: DOUBLEDOT '/'; 3989 3990relative_path_part1_opt: @EMPTYDIR@ 3991 | relative_path_part1_opt relative_path_part1; 3992 3993descendant_path: node_identifier descendant_path_opt 3994 3995descendant_path_opt: @EMPTYDIR@ 3996 | path_predicate absolute_paths; 3997 3998path_predicate: @EMPTYDIR@ 3999 | path_predicate '[' whitespace_opt path_equality_expr ']' 4000 4001path_equality_expr: node_identifier whitespace_opt '=' whitespace_opt path_key_expr 4002 4003path_key_expr: current_function_invocation whitespace_opt '/' whitespace_opt 4004 rel_path_keyexpr 4005 4006rel_path_keyexpr: rel_path_keyexpr_part1 rel_path_keyexpr_part1_opt 4007 node_identifier rel_path_keyexpr_part2 4008 4009rel_path_keyexpr_part1: DOUBLEDOT whitespace_opt '/' whitespace_opt; 4010 4011rel_path_keyexpr_part1_opt: @EMPTYDIR@ 4012 | rel_path_keyexpr_part1_opt rel_path_keyexpr_part1; 4013 4014rel_path_keyexpr_part2: @EMPTYDIR@ 4015 | rel_path_keyexpr_part2 whitespace_opt '/' whitespace_opt node_identifier; 4016 4017current_function_invocation: CURRENT_KEYWORD whitespace_opt '(' whitespace_opt ')' 4018 4019positive_integer_value: NON_NEGATIVE_INTEGER { /* convert it to uint32_t */ 4020 unsigned long val; 4021 4022 val = strtoul(yyget_text(scanner), NULL, 10); 4023 if (val > UINT32_MAX) { 4024 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Converted number is very long."); 4025 YYABORT; 4026 } 4027 $$ = (uint32_t) val; 4028 } 4029 4030non_negative_integer_value: ZERO { $$ = 0; } 4031 | positive_integer_value { $$ = $1; } 4032 ; 4033 4034integer_value: ZERO { $$ = 0; } 4035 | integer_value_convert { /* convert it to int32_t */ 4036 int64_t val; 4037 4038 val = strtoll(yyget_text(scanner), NULL, 10); 4039 if (val < INT32_MIN || val > INT32_MAX) { 4040 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, 4041 "The number is not in the correct range (INT32_MIN..INT32_MAX): \"%d\"",val); 4042 YYABORT; 4043 } 4044 $$ = (int32_t) val; 4045 } 4046 4047integer_value_convert: INTEGER 4048 | NON_NEGATIVE_INTEGER 4049 4050prefix_arg_str: string_1 4051 | identifiers optsep; 4052 4053identifier_arg_str: identifiers optsep 4054 | string_1 { if (lyp_check_identifier(trg->ctx, s, LY_IDENT_SIMPLE, trg, NULL)) { 4055 free(s); 4056 YYABORT; 4057 } 4058 } 4059 4060node_identifier: identifier 4061 | IDENTIFIERPREFIX 4062 ; 4063 4064identifier_ref_arg_str: identifiers optsep 4065 | identifiers_ref optsep 4066 | string_1 { char *tmp; 4067 4068 if ((tmp = strchr(s, ':'))) { 4069 *tmp = '\0'; 4070 /* check prefix */ 4071 if (lyp_check_identifier(trg->ctx, s, LY_IDENT_SIMPLE, trg, NULL)) { 4072 free(s); 4073 YYABORT; 4074 } 4075 /* check identifier */ 4076 if (lyp_check_identifier(trg->ctx, tmp + 1, LY_IDENT_SIMPLE, trg, NULL)) { 4077 free(s); 4078 YYABORT; 4079 } 4080 *tmp = ':'; 4081 } else { 4082 /* check identifier */ 4083 if (lyp_check_identifier(trg->ctx, s, LY_IDENT_SIMPLE, trg, NULL)) { 4084 free(s); 4085 YYABORT; 4086 } 4087 } 4088 } 4089 4090stmtend: semicolom stmtsep { s = $1; } 4091 | curly_bracket_open stmtsep curly_bracket_close stmtsep { s = $1; } 4092 4093 4094semicolom: ';' { actual_type = backup_type; 4095 backup_type = NODE; 4096 $$ = s; 4097 s = NULL; 4098 } 4099 4100curly_bracket_close: '}' { actual_type = backup_type; 4101 backup_type = NODE; 4102 } 4103 4104curly_bracket_open: '{' { $$ = s; 4105 s = NULL; 4106 } 4107 4108 4109stmtsep: @EMPTYDIR@ 4110 | stmtsep sep_stmt 4111 | stmtsep unknown_statement 4112 ; 4113 4114unknown_statement: identifiers_ref string_opt unknown_statement_end 4115 { actual_type = $2.token; 4116 actual = $2.actual; 4117 } 4118 4119string_opt: string_opt_part1 string_opt_part2 { $$.token = actual_type; 4120 $$.actual = actual; 4121 if (!(actual = yang_read_ext(trg, (actual) ? actual : trg, $1, s, 4122 actual_type, backup_type, is_ext_instance))) { 4123 YYABORT; 4124 } 4125 s = NULL; 4126 actual_type = EXTENSION_INSTANCE; 4127 } 4128 4129string_opt_part1: optsep { $$ = s; s = NULL; } 4130 4131string_opt_part2: @EMPTYDIR@ 4132 | string 4133 4134unknown_string: @EMPTYDIR@ 4135 | sep unknown_string_part1 4136 4137unknown_string_part1: @EMPTYDIR@ 4138 | strings optsep 4139 | STRING optsep unknown_string_part2 4140 4141unknown_string_part2: @EMPTYDIR@ 4142 | unknown_string_part2 '+' optsep STRING optsep 4143 4144unknown_statement_end: ';' 4145 | '{' optsep unknown_statement2_opt '}' 4146 4147unknown_statement2_opt: @EMPTYDIR@ 4148 | unknown_statement2_opt unknown_statement2 optsep 4149 4150/* unknown_statement2 read yang statement or extension; yang statement is parsed later */ 4151 4152unknown_statement2: unknown_statement 4153 | unknown_statement2_yang_stmt unknown_string unknown_statement2_end 4154 { struct yang_ext_substmt *substmt = ((struct lys_ext_instance *)actual)->parent; 4155 int32_t length = 0, old_length = 0; 4156 char *tmp_value; 4157 4158 if (!substmt) { 4159 substmt = calloc(1, sizeof *substmt); 4160 if (!substmt) { 4161 LOGMEM(trg->ctx); 4162 YYABORT; 4163 } 4164 ((struct lys_ext_instance *)actual)->parent = substmt; 4165 } 4166 length = strlen($1); 4167 old_length = (substmt->ext_substmt) ? strlen(substmt->ext_substmt) + 2 : 2; 4168 tmp_value = realloc(substmt->ext_substmt, old_length + length + 1); 4169 if (!tmp_value) { 4170 LOGMEM(trg->ctx); 4171 YYABORT; 4172 } 4173 substmt->ext_substmt = tmp_value; 4174 tmp_value += old_length - 2; 4175 memcpy(tmp_value, $1, length); 4176 tmp_value[length] = ' '; 4177 tmp_value[length + 1] = '\0'; 4178 tmp_value[length + 2] = '\0'; 4179 } 4180 | unknown_statement2_module_stmt unknown_string unknown_statement2_end 4181 { struct yang_ext_substmt *substmt = ((struct lys_ext_instance *)actual)->parent; 4182 int32_t length; 4183 char *tmp_value, **array; 4184 int i = 0; 4185 4186 if (!substmt) { 4187 substmt = calloc(1, sizeof *substmt); 4188 if (!substmt) { 4189 LOGMEM(trg->ctx); 4190 YYABORT; 4191 } 4192 ((struct lys_ext_instance *)actual)->parent = substmt; 4193 } 4194 length = strlen($1); 4195 if (!substmt->ext_modules) { 4196 array = malloc(2 * sizeof *substmt->ext_modules); 4197 } else { 4198 for (i = 0; substmt->ext_modules[i]; ++i); 4199 array = realloc(substmt->ext_modules, (i + 2) * sizeof *substmt->ext_modules); 4200 } 4201 if (!array) { 4202 LOGMEM(trg->ctx); 4203 YYABORT; 4204 } 4205 substmt->ext_modules = array; 4206 array[i + 1] = NULL; 4207 tmp_value = malloc(length + 2); 4208 if (!tmp_value) { 4209 LOGMEM(trg->ctx); 4210 YYABORT; 4211 } 4212 array[i] = tmp_value; 4213 memcpy(tmp_value, $1, length); 4214 tmp_value[length] = '\0'; 4215 tmp_value[length + 1] = '\0'; 4216 } 4217 4218unknown_statement2_end: ';' 4219 | '{' optsep unknown_statement3_opt '}' 4220 4221unknown_statement2_yang_stmt: yang_stmt { $$ = yyget_text(scanner); } 4222 4223unknown_statement2_module_stmt: MODULE_KEYWORD { $$ = yyget_text(scanner); } 4224 4225unknown_statement3_opt: @EMPTYDIR@ 4226 | unknown_statement3_opt node_identifier unknown_string unknown_statement3_opt_end; 4227 4228unknown_statement3_opt_end: ';' optsep 4229 | '{' optsep unknown_statement3_opt '}' optsep 4230 4231sep_stmt: WHITESPACE 4232 | EOL 4233 ; 4234 4235optsep: @EMPTYDIR@ 4236 | optsep sep_stmt 4237 ; 4238 4239sep: sep_stmt optsep; 4240 4241whitespace_opt: @EMPTYDIR@ 4242 | WHITESPACE 4243 ; 4244 4245string: strings { s = strdup(yyget_text(scanner)); 4246 if (!s) { 4247 LOGMEM(trg->ctx); 4248 YYABORT; 4249 } 4250 } 4251 optsep 4252 | string_1 4253 4254strings: STRINGS 4255 | REVISION_DATE 4256 | identifier 4257 | IDENTIFIERPREFIX 4258 | ZERO 4259 | INTEGER 4260 | NON_NEGATIVE_INTEGER 4261 4262identifier: MODULE_KEYWORD 4263 | identifier1 4264 | yang_stmt 4265 4266identifier1: IDENTIFIER 4267 | CURRENT_KEYWORD 4268 | DEPRECATED_KEYWORD 4269 | FALSE_KEYWORD 4270 | NOT_SUPPORTED_KEYWORD 4271 | OBSOLETE_KEYWORD 4272 | SYSTEM_KEYWORD 4273 | TRUE_KEYWORD 4274 | UNBOUNDED_KEYWORD 4275 | USER_KEYWORD 4276 4277 4278yang_stmt: ANYXML_KEYWORD 4279 | ARGUMENT_KEYWORD 4280 | AUGMENT_KEYWORD 4281 | BASE_KEYWORD 4282 | BELONGS_TO_KEYWORD 4283 | BIT_KEYWORD 4284 | CASE_KEYWORD 4285 | CHOICE_KEYWORD 4286 | CONFIG_KEYWORD 4287 | CONTACT_KEYWORD 4288 | CONTAINER_KEYWORD 4289 | DEFAULT_KEYWORD 4290 | DESCRIPTION_KEYWORD 4291 | ENUM_KEYWORD 4292 | ERROR_APP_TAG_KEYWORD 4293 | ERROR_MESSAGE_KEYWORD 4294 | EXTENSION_KEYWORD 4295 | DEVIATION_KEYWORD 4296 | DEVIATE_KEYWORD 4297 | FEATURE_KEYWORD 4298 | FRACTION_DIGITS_KEYWORD 4299 | GROUPING_KEYWORD 4300 | IDENTITY_KEYWORD 4301 | IF_FEATURE_KEYWORD 4302 | IMPORT_KEYWORD 4303 | INCLUDE_KEYWORD 4304 | INPUT_KEYWORD 4305 | KEY_KEYWORD 4306 | LEAF_KEYWORD 4307 | LEAF_LIST_KEYWORD 4308 | LENGTH_KEYWORD 4309 | LIST_KEYWORD 4310 | MANDATORY_KEYWORD 4311 | MAX_ELEMENTS_KEYWORD 4312 | MIN_ELEMENTS_KEYWORD 4313 | MUST_KEYWORD 4314 | NAMESPACE_KEYWORD 4315 | NOTIFICATION_KEYWORD 4316 | ORDERED_BY_KEYWORD 4317 | ORGANIZATION_KEYWORD 4318 | OUTPUT_KEYWORD 4319 | PATH_KEYWORD 4320 | PATTERN_KEYWORD 4321 | POSITION_KEYWORD 4322 | PREFIX_KEYWORD 4323 | PRESENCE_KEYWORD 4324 | RANGE_KEYWORD 4325 | REFERENCE_KEYWORD 4326 | REFINE_KEYWORD 4327 | REQUIRE_INSTANCE_KEYWORD 4328 | REVISION_KEYWORD 4329 | REVISION_DATE_KEYWORD 4330 | RPC_KEYWORD 4331 | STATUS_KEYWORD 4332 | SUBMODULE_KEYWORD 4333 | TYPE_KEYWORD 4334 | TYPEDEF_KEYWORD 4335 | UNIQUE_KEYWORD 4336 | UNITS_KEYWORD 4337 | USES_KEYWORD 4338 | VALUE_KEYWORD 4339 | WHEN_KEYWORD 4340 | YANG_VERSION_KEYWORD 4341 | YIN_ELEMENT_KEYWORD 4342 | ADD_KEYWORD 4343 | DELETE_KEYWORD 4344 | REPLACE_KEYWORD 4345 | ACTION_KEYWORD 4346 | MODIFIER_KEYWORD 4347 | ANYDATA_KEYWORD 4348 4349identifiers: identifier { s = strdup(yyget_text(scanner)); 4350 if (!s) { 4351 LOGMEM(trg->ctx); 4352 YYABORT; 4353 } 4354 } 4355 4356identifiers_ref: IDENTIFIERPREFIX { s = strdup(yyget_text(scanner)); 4357 if (!s) { 4358 LOGMEM(trg->ctx); 4359 YYABORT; 4360 } 4361 } 4362 4363type_ext_alloc: @EMPTYDIR@ { struct lys_type **type; 4364 4365 type = (struct lys_type **)yang_getplace_for_extcomplex_struct(ext_instance, NULL, ext_name, 4366 "type", LY_STMT_TYPE); 4367 if (!type) { 4368 YYABORT; 4369 } 4370 /* allocate type structure */ 4371 (*type) = calloc(1, sizeof **type); 4372 if (!*type) { 4373 LOGMEM(trg->ctx); 4374 YYABORT; 4375 } 4376 4377 /* HACK for unres */ 4378 (*type)->parent = (struct lys_tpdf *)ext_instance; 4379 $$ = actual = *type; 4380 is_ext_instance = 0; 4381 } 4382 4383typedef_ext_alloc: @EMPTYDIR@ { struct lys_tpdf **tpdf; 4384 4385 tpdf = (struct lys_tpdf **)yang_getplace_for_extcomplex_struct(ext_instance, NULL, ext_name, 4386 "typedef", LY_STMT_TYPEDEF); 4387 if (!tpdf) { 4388 YYABORT; 4389 } 4390 /* allocate typedef structure */ 4391 (*tpdf) = calloc(1, sizeof **tpdf); 4392 if (!*tpdf) { 4393 LOGMEM(trg->ctx); 4394 YYABORT; 4395 } 4396 4397 $$ = actual = *tpdf; 4398 is_ext_instance = 0; 4399 } 4400 4401iffeature_ext_alloc: @EMPTYDIR@ { struct lys_iffeature **iffeature; 4402 4403 iffeature = (struct lys_iffeature **)yang_getplace_for_extcomplex_struct(ext_instance, NULL, ext_name, 4404 "if-feature", LY_STMT_IFFEATURE); 4405 if (!iffeature) { 4406 YYABORT; 4407 } 4408 /* allocate typedef structure */ 4409 (*iffeature) = calloc(1, sizeof **iffeature); 4410 if (!*iffeature) { 4411 LOGMEM(trg->ctx); 4412 YYABORT; 4413 } 4414 $$ = actual = *iffeature; 4415 } 4416 4417restriction_ext_alloc: @EMPTYDIR@ { struct lys_restr **restr; 4418 LY_STMT stmt; 4419 4420 s = yyget_text(scanner); 4421 if (!strcmp(s, "must")) { 4422 stmt = LY_STMT_MUST; 4423 } else if (!strcmp(s, "pattern")) { 4424 stmt = LY_STMT_PATTERN; 4425 } else if (!strcmp(s, "range")) { 4426 stmt = LY_STMT_RANGE; 4427 } else { 4428 stmt = LY_STMT_LENGTH; 4429 } 4430 restr = (struct lys_restr **)yang_getplace_for_extcomplex_struct(ext_instance, NULL, ext_name, s, stmt); 4431 if (!restr) { 4432 YYABORT; 4433 } 4434 /* allocate structure for must */ 4435 (*restr) = calloc(1, sizeof(struct lys_restr)); 4436 if (!*restr) { 4437 LOGMEM(trg->ctx); 4438 YYABORT; 4439 } 4440 $$ = actual = *restr; 4441 s = NULL; 4442 } 4443 4444when_ext_alloc: @EMPTYDIR@ { actual = yang_getplace_for_extcomplex_struct(ext_instance, NULL, ext_name, "when", LY_STMT_WHEN); 4445 if (!actual) { 4446 YYABORT; 4447 } 4448 $$ = actual; 4449 } 4450 4451revision_ext_alloc: @EMPTYDIR@ { struct lys_revision **rev; 4452 int i; 4453 4454 rev = (struct lys_revision **)yang_getplace_for_extcomplex_struct(ext_instance, &i, ext_name, 4455 "revision", LY_STMT_REVISION); 4456 if (!rev) { 4457 YYABORT; 4458 } 4459 rev[i] = calloc(1, sizeof **rev); 4460 if (!rev[i]) { 4461 LOGMEM(trg->ctx); 4462 YYABORT; 4463 } 4464 actual = rev[i]; 4465 $$.revision = rev; 4466 $$.index = i; 4467 } 4468 4469datadef_ext_check: @EMPTYDIR@ { LY_STMT stmt; 4470 4471 s = yyget_text(scanner); 4472 if (!strcmp(s, "action")) { 4473 stmt = LY_STMT_ACTION; 4474 } else if (!strcmp(s, "anydata")) { 4475 stmt = LY_STMT_ANYDATA; 4476 } else if (!strcmp(s, "anyxml")) { 4477 stmt = LY_STMT_ANYXML; 4478 } else if (!strcmp(s, "case")) { 4479 stmt = LY_STMT_CASE; 4480 } else if (!strcmp(s, "choice")) { 4481 stmt = LY_STMT_CHOICE; 4482 } else if (!strcmp(s, "container")) { 4483 stmt = LY_STMT_CONTAINER; 4484 } else if (!strcmp(s, "grouping")) { 4485 stmt = LY_STMT_GROUPING; 4486 } else if (!strcmp(s, "input")) { 4487 stmt = LY_STMT_INPUT; 4488 } else if (!strcmp(s, "leaf")) { 4489 stmt = LY_STMT_LEAF; 4490 } else if (!strcmp(s, "leaf-list")) { 4491 stmt = LY_STMT_LEAFLIST; 4492 } else if (!strcmp(s, "list")) { 4493 stmt = LY_STMT_LIST; 4494 } else if (!strcmp(s, "notification")) { 4495 stmt = LY_STMT_NOTIFICATION; 4496 } else if (!strcmp(s, "output")) { 4497 stmt = LY_STMT_OUTPUT; 4498 } else { 4499 stmt = LY_STMT_USES; 4500 } 4501 if (yang_extcomplex_node(ext_instance, ext_name, s, *param->node, stmt)) { 4502 YYABORT; 4503 } 4504 actual = NULL; 4505 s = NULL; 4506 is_ext_instance = 0; 4507 } 4508 4509not_supported_ext_check: not_supported_ext { LOGERR(trg->ctx, ly_errno, "Extension's substatement \"%s\" not supported.", yyget_text(scanner)); } 4510 4511not_supported_ext: YANG_VERSION_KEYWORD 4512 | YIN_ELEMENT_KEYWORD 4513 | BIT_KEYWORD 4514 | ENUM_KEYWORD 4515 | AUGMENT_KEYWORD 4516 | DEVIATION_KEYWORD 4517 | DEVIATE_KEYWORD 4518 | EXTENSION_KEYWORD 4519 | FEATURE_KEYWORD 4520 | IDENTITY_KEYWORD 4521 | IMPORT_KEYWORD 4522 | INCLUDE_KEYWORD 4523 | SUBMODULE_EXT_KEYWORD 4524 4525datadef_ext_stmt: action_stmt 4526 | anydata_stmt 4527 | anyxml_stmt 4528 | case_stmt 4529 | choice_stmt 4530 | container_stmt 4531 | grouping_stmt 4532 | input_stmt 4533 | leaf_stmt 4534 | leaf_list_stmt 4535 | list_stmt 4536 | notification_stmt 4537 | output_stmt 4538 | uses_stmt 4539 4540restriction_ext_stmt: must_stmt 4541 | pattern_stmt 4542 | range_stmt 4543 | length_stmt 4544 4545ext_substatements: @EMPTYDIR@ { actual_type = EXTENSION_INSTANCE; 4546 actual = ext_instance; 4547 if (!is_ext_instance) { 4548 LOGVAL(trg->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, yyget_text(scanner)); 4549 YYABORT; 4550 } 4551 $$ = 0; 4552 } 4553 | ext_substatements belongs_to_stmt stmtsep 4554 | ext_substatements prefix_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "prefix", ext_name, &s, 4555 0, LY_STMT_PREFIX)) { 4556 YYABORT; 4557 } 4558 } 4559 | ext_substatements description_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "description", ext_name, &s, 4560 0, LY_STMT_DESCRIPTION)) { 4561 YYABORT; 4562 } 4563 } 4564 | ext_substatements reference_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "reference", ext_name, &s, 4565 0, LY_STMT_REFERENCE)) { 4566 YYABORT; 4567 } 4568 } 4569 | ext_substatements units_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "units", ext_name, &s, 4570 0, LY_STMT_UNITS)) { 4571 YYABORT; 4572 } 4573 } 4574 | ext_substatements base_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "base", ext_name, &s, 4575 0, LY_STMT_BASE)) { 4576 YYABORT; 4577 } 4578 } 4579 | ext_substatements contact_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "contact", ext_name, &s, 4580 0, LY_STMT_CONTACT)) { 4581 YYABORT; 4582 } 4583 } 4584 | ext_substatements default_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "default", ext_name, &s, 4585 0, LY_STMT_DEFAULT)) { 4586 YYABORT; 4587 } 4588 } 4589 | ext_substatements error_message_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "error-message", ext_name, &s, 4590 0, LY_STMT_ERRMSG)) { 4591 YYABORT; 4592 } 4593 } 4594 | ext_substatements error_app_tag_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "error-app-tag", ext_name, &s, 4595 0, LY_STMT_ERRTAG)) { 4596 YYABORT; 4597 } 4598 } 4599 | ext_substatements key_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "key", ext_name, &s, 4600 0, LY_STMT_KEY)) { 4601 YYABORT; 4602 } 4603 } 4604 | ext_substatements namespace_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "namespace", ext_name, &s, 4605 0, LY_STMT_NAMESPACE)) { 4606 YYABORT; 4607 } 4608 } 4609 | ext_substatements organization_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "organization", ext_name, &s, 4610 0, LY_STMT_ORGANIZATION)) { 4611 YYABORT; 4612 } 4613 } 4614 | ext_substatements path_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "path", ext_name, &s, 4615 0, LY_STMT_PATH)) { 4616 YYABORT; 4617 } 4618 } 4619 | ext_substatements presence_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "presence", ext_name, &s, 4620 0, LY_STMT_PRESENCE)) { 4621 YYABORT; 4622 } 4623 } 4624 | ext_substatements revision_date_stmt { if (yang_read_extcomplex_str(trg, ext_instance, "revision-date", ext_name, &s, 4625 0, LY_STMT_REVISIONDATE)) { 4626 YYABORT; 4627 } 4628 } 4629 | ext_substatements type_ext_alloc type_stmt stmtsep 4630 { struct lys_type *type = $2; 4631 4632 if (yang_fill_type(trg, type, (struct yang_type *)type->der, ext_instance, param->unres)) { 4633 yang_type_free(trg->ctx, type); 4634 YYABORT; 4635 } 4636 if (unres_schema_add_node(trg, param->unres, type, UNRES_TYPE_DER_EXT, NULL) == -1) { 4637 yang_type_free(trg->ctx, type); 4638 YYABORT; 4639 } 4640 actual = ext_instance; 4641 is_ext_instance = 1; 4642 } 4643 | ext_substatements typedef_ext_alloc typedef_stmt stmtsep 4644 { struct lys_tpdf *tpdf = $2; 4645 4646 if (yang_fill_type(trg, &tpdf->type, (struct yang_type *)tpdf->type.der, tpdf, param->unres)) { 4647 yang_type_free(trg->ctx, &tpdf->type); 4648 } 4649 if (yang_check_ext_instance(trg, &tpdf->ext, &tpdf->ext_size, tpdf, param->unres)) { 4650 YYABORT; 4651 } 4652 if (unres_schema_add_node(trg, param->unres, &tpdf->type, UNRES_TYPE_DER_TPDF, (struct lys_node *)ext_instance) == -1) { 4653 yang_type_free(trg->ctx, &tpdf->type); 4654 YYABORT; 4655 } 4656 /* check default value*/ 4657 if (unres_schema_add_node(trg, param->unres, &tpdf->type, UNRES_TYPE_DFLT, (struct lys_node *)(&tpdf->dflt)) == -1) { 4658 YYABORT; 4659 } 4660 actual = ext_instance; 4661 is_ext_instance = 1; 4662 } 4663 | ext_substatements status_stmt { if (yang_fill_extcomplex_flags(ext_instance, ext_name, "status", LY_STMT_STATUS, 4664 $2, LYS_STATUS_MASK)) { 4665 YYABORT; 4666 } 4667 } 4668 | ext_substatements config_stmt { if (yang_fill_extcomplex_flags(ext_instance, ext_name, "config", LY_STMT_CONFIG, 4669 $2, LYS_CONFIG_MASK)) { 4670 YYABORT; 4671 } 4672 } 4673 | ext_substatements mandatory_stmt { if (yang_fill_extcomplex_flags(ext_instance, ext_name, "mandatory", LY_STMT_MANDATORY, 4674 $2, LYS_MAND_MASK)) { 4675 YYABORT; 4676 } 4677 } 4678 | ext_substatements ordered_by_stmt { if ($1 & LYS_ORDERED_MASK) { 4679 LOGVAL(trg->ctx, LYE_TOOMANY, LY_VLOG_NONE, NULL, "ordered by", ext_name); 4680 YYABORT; 4681 } 4682 if ($2 & LYS_USERORDERED) { 4683 if (yang_fill_extcomplex_flags(ext_instance, ext_name, "ordered-by", LY_STMT_ORDEREDBY, 4684 $2, LYS_USERORDERED)) { 4685 YYABORT; 4686 } 4687 } 4688 $1 |= $2; 4689 $$ = $1; 4690 } 4691 | ext_substatements require_instance_stmt { if (yang_fill_extcomplex_uint8(ext_instance, ext_name, "require-instance", 4692 LY_STMT_REQINSTANCE, $2)) { 4693 YYABORT; 4694 } 4695 } 4696 | ext_substatements modifier_stmt { if (yang_fill_extcomplex_uint8(ext_instance, ext_name, "modifier", LY_STMT_MODIFIER, 0)) { 4697 YYABORT; 4698 } 4699 } 4700 | ext_substatements fraction_digits_stmt 4701 { /* range check */ 4702 if ($2 < 1 || $2 > 18) { 4703 LOGVAL(trg->ctx, LYE_SPEC, LY_VLOG_NONE, NULL, "Invalid value \"%d\" of \"%s\".", $2, "fraction-digits"); 4704 YYABORT; 4705 } 4706 if (yang_fill_extcomplex_uint8(ext_instance, ext_name, "fraction-digits", LY_STMT_DIGITS, $2)) { 4707 YYABORT; 4708 } 4709 } 4710 | ext_substatements min_elements_stmt { uint32_t **val; 4711 4712 val = (uint32_t **)yang_getplace_for_extcomplex_struct(ext_instance, NULL, ext_name, 4713 "min-elements", LY_STMT_MIN); 4714 if (!val) { 4715 YYABORT; 4716 } 4717 /* store the value */ 4718 *val = malloc(sizeof(uint32_t)); 4719 if (!*val) { 4720 LOGMEM(trg->ctx); 4721 YYABORT; 4722 } 4723 **val = $2; 4724 } 4725 | ext_substatements max_elements_stmt { uint32_t **val; 4726 4727 val = (uint32_t **)yang_getplace_for_extcomplex_struct(ext_instance, NULL, ext_name, 4728 "max-elements", LY_STMT_MAX); 4729 if (!val) { 4730 YYABORT; 4731 } 4732 /* store the value */ 4733 *val = malloc(sizeof(uint32_t)); 4734 if (!*val) { 4735 LOGMEM(trg->ctx); 4736 YYABORT; 4737 } 4738 **val = $2; 4739 } 4740 | ext_substatements position_stmt { uint32_t **val; 4741 4742 val = (uint32_t **)yang_getplace_for_extcomplex_struct(ext_instance, NULL, ext_name, 4743 "position", LY_STMT_POSITION); 4744 if (!val) { 4745 YYABORT; 4746 } 4747 /* store the value */ 4748 *val = malloc(sizeof(uint32_t)); 4749 if (!*val) { 4750 LOGMEM(trg->ctx); 4751 YYABORT; 4752 } 4753 **val = $2; 4754 } 4755 | ext_substatements value_stmt { int32_t **val; 4756 4757 val = (int32_t **)yang_getplace_for_extcomplex_struct(ext_instance, NULL, ext_name, 4758 "value", LY_STMT_VALUE); 4759 if (!val) { 4760 YYABORT; 4761 } 4762 /* store the value */ 4763 *val = malloc(sizeof(int32_t)); 4764 if (!*val) { 4765 LOGMEM(trg->ctx); 4766 YYABORT; 4767 } 4768 **val = $2; 4769 } 4770 | ext_substatements unique_stmt { struct lys_unique **unique; 4771 int rc; 4772 4773 unique = (struct lys_unique **)yang_getplace_for_extcomplex_struct(ext_instance, NULL, ext_name, 4774 "unique", LY_STMT_UNIQUE); 4775 if (!unique) { 4776 YYABORT; 4777 } 4778 *unique = calloc(1, sizeof(struct lys_unique)); 4779 if (!*unique) { 4780 LOGMEM(trg->ctx); 4781 YYABORT; 4782 } 4783 rc = yang_fill_unique(trg, (struct lys_node_list *)ext_instance, *unique, s, param->unres); 4784 free(s); 4785 s = NULL; 4786 if (rc) { 4787 YYABORT; 4788 } 4789 } 4790 | ext_substatements iffeature_ext_alloc if_feature_stmt stmtsep 4791 { struct lys_iffeature *iffeature; 4792 4793 iffeature = $2; 4794 s = (char *)iffeature->features; 4795 iffeature->features = NULL; 4796 if (yang_fill_iffeature(trg, iffeature, ext_instance, s, param->unres, 0)) { 4797 YYABORT; 4798 } 4799 if (yang_check_ext_instance(trg, &iffeature->ext, &iffeature->ext_size, iffeature, param->unres)) { 4800 YYABORT; 4801 } 4802 s = NULL; 4803 actual = ext_instance; 4804 } 4805 | ext_substatements argument_stmt stmtsep 4806 | ext_substatements restriction_ext_alloc restriction_ext_stmt stmtsep 4807 { if (yang_check_ext_instance(trg, &((struct lys_restr *)$2)->ext, &((struct lys_restr *)$2)->ext_size, $2, param->unres)) { 4808 YYABORT; 4809 } 4810 actual = ext_instance; 4811 } 4812 | ext_substatements when_ext_alloc when_stmt stmtsep 4813 { if (yang_check_ext_instance(trg, &(*(struct lys_when **)$2)->ext, &(*(struct lys_when **)$2)->ext_size, 4814 *(struct lys_when **)$2, param->unres)) { 4815 YYABORT; 4816 } 4817 actual = ext_instance; 4818 } 4819 | ext_substatements revision_ext_alloc revision_stmt stmtsep 4820 { int i; 4821 4822 for (i = 0; i < $2.index; ++i) { 4823 if (!strcmp($2.revision[i]->date, $2.revision[$2.index]->date)) { 4824 LOGWRN(trg->ctx, "Module's revisions are not unique (%s).", $2.revision[i]->date); 4825 break; 4826 } 4827 } 4828 if (yang_check_ext_instance(trg, &$2.revision[$2.index]->ext, &$2.revision[$2.index]->ext_size, 4829 &$2.revision[$2.index], param->unres)) { 4830 YYABORT; 4831 } 4832 actual = ext_instance; 4833 } 4834 | ext_substatements datadef_ext_check datadef_ext_stmt stmtsep { actual = ext_instance; 4835 is_ext_instance = 1; 4836 } 4837 | ext_substatements not_supported_ext_check unknown_string unknown_statement3_opt_end 4838 4839%% 4840 4841void 4842yyerror(YYLTYPE *yylloc, void *scanner, struct yang_parameter *param, ...) 4843{ 4844 free(*param->value); 4845 *param->value = NULL; 4846 if (yylloc->first_line != -1) { 4847 if (*param->data_node && (*param->data_node) == (*param->actual_node)) { 4848 LOGVAL(param->module->ctx, LYE_INSTMT, LY_VLOG_LYS, *param->data_node, yyget_text(scanner)); 4849 } else { 4850 LOGVAL(param->module->ctx, LYE_INSTMT, LY_VLOG_NONE, NULL, yyget_text(scanner)); 4851 } 4852 } 4853} 4854