1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME: 80** 81** acf.y 82** 83** FACILITY: 84** 85** Interface Definition Language (IDL) Compiler 86** 87** ABSTRACT: 88** 89** ACF Parser Grammar and parser helper functions 90** 91** VERSION: DCE 1.0 92** 93*/ 94 95/******************************* 96 * parser declarations section * 97 *******************************/ 98 99%{ 100 101 /* Tank Trap to stop older yacc parsers */ 102 /* Bison defines the macro YYBISON */ 103 104#ifndef YYBISON 105This grammar file needs to be built with GNU Bison V1.25 or later. 106 GNU Bison can be be obtained from ftp://prep.ai.mit.edu:/pub/gnu 107#endif 108 109/* Declarations in this section are copied from yacc source to y_tab.c. */ 110#include <stdarg.h> 111 112#include <nidl.h> /* IDL compiler-wide defs */ 113 114#include <ast.h> /* Abstract Syntax Tree defs */ 115#include <astp.h> /* Import AST processing routine defs */ 116#include <command.h> /* Command line defs */ 117#include <message.h> /* Error message defs */ 118#include <nidlmsg.h> /* Error message IDs */ 119#include <files.h> 120#include <propagat.h> 121#include <checker.h> 122 123#define YYDEBUG 1 124 125extern AST_interface_n_t *the_interface; /* Ptr to AST interface node */ 126extern boolean ASTP_parsing_main_idl; /* True when parsing main IDL */ 127 128typedef union /* Attributes bitmask */ 129{ 130 struct 131 { 132 unsigned auto_handle : 1; 133 unsigned binding_callout: 1; 134 unsigned code : 1; 135 unsigned comm_status : 1; 136 unsigned cs_char : 1; 137 unsigned cs_drtag : 1; 138 unsigned cs_rtag : 1; 139 unsigned cs_stag : 1; 140 unsigned cs_tag_rtn : 1; 141 unsigned decode : 1; 142 unsigned enable_allocate: 1; 143 unsigned encode : 1; 144 unsigned explicit_handle: 1; 145 unsigned extern_exceps : 1; 146 unsigned fault_status : 1; 147 unsigned heap : 1; 148 unsigned implicit_handle: 1; 149 unsigned in_line : 1; 150 unsigned nocode : 1; 151 unsigned out_of_line : 1; 152 unsigned represent_as : 1; 153 unsigned nocancel : 1; 154 } bit; 155 long mask; 156} acf_attrib_t; 157 158typedef struct acf_param_t /* ACF parameter info structure */ 159{ 160 struct acf_param_t *next; /* Forward link */ 161 acf_attrib_t parameter_attr; /* Parameter attributes */ 162 NAMETABLE_id_t param_id; /* Parameter name */ 163} acf_param_t; 164 165/* An opaque pointer. */ 166#ifndef YY_TYPEDEF_YY_SCANNER_T 167#define YY_TYPEDEF_YY_SCANNER_T 168typedef void* yyscan_t; 169#endif 170 171typedef struct acf_parser_state_t 172{ 173 yyscan_t acf_yyscanner; 174 unsigned acf_yynerrs; 175 parser_location_t acf_location; 176 177 boolean acf_dumpers; 178 179 acf_attrib_t acf_interface_attr; /* Interface attributes */ 180 acf_attrib_t acf_type_attr; /* Type attributes */ 181 acf_attrib_t acf_operation_attr; /* Operation attributes */ 182 acf_attrib_t acf_parameter_attr; /* Parameter attributes */ 183 184 const char * acf_interface_name; /* Interface name */ 185 const char * acf_impl_name; /* Implicit handle name */ 186 const char * acf_type_name; /* Current type name */ 187 const char * acf_repr_type_name; /* Current represent_as type */ 188 const char * acf_cs_char_type_name; /* Current cs_char type */ 189 const char * acf_operation_name; /* Current operation name */ 190 const char * acf_cs_tag_rtn_name; /* Current cs_tag_rtn name */ 191 const char * acf_binding_callout_name; /* Current binding_callout name */ 192 boolean acf_named_type; /* True if parsed type is named type */ 193 194 AST_include_n_t * acf_include_list; /* List of AST include nodes */ 195 AST_include_n_t * acf_include_p; /* Ptr to a created include node */ 196 197 acf_param_t * acf_parameter_list; /* Param list for curr. operation */ 198 acf_param_t * acf_parameter_free_list; /* True if param attrs specified */ 199 boolean acf_parameter_attr_list; /* True if param attrs specified */ 200} acf_parser_state_t; 201 202/* 203 * Forward declarations to shut up the compiler 204 */ 205 206static boolean lookup_exception(acf_parser_state_t *, NAMETABLE_id_t, 207 boolean, AST_exception_n_t **); 208static boolean lookup_type(acf_parser_state_t *, char const *, boolean, 209 NAMETABLE_id_t *, AST_type_n_t **); 210static boolean lookup_operation(acf_parser_state_t *, char const *, 211 boolean, NAMETABLE_id_t *, AST_operation_n_t **); 212static boolean lookup_parameter(acf_parser_state_t *, AST_operation_n_t *, 213 char const *, boolean, NAMETABLE_id_t *, AST_parameter_n_t **); 214static boolean lookup_rep_as_name(AST_type_p_n_t *, NAMETABLE_id_t, AST_type_n_t **, char const **); 215static boolean lookup_cs_char_name(AST_type_p_n_t *, NAMETABLE_id_t, AST_type_n_t **, char const * *); 216static acf_param_t * alloc_param(acf_parser_state_t *); 217static void free_param(acf_parser_state_t *, acf_param_t *); 218static void free_param_list(acf_parser_state_t *, acf_param_t **); 219void add_param_to_list(acf_param_t *, acf_param_t **); 220static void append_parameter(acf_parser_state_t *, AST_operation_n_t *, 221 char const *, acf_attrib_t *); 222static void process_rep_as_type(acf_parser_state_t *, AST_interface_n_t *, 223 AST_type_n_t *, char const *); 224static void process_cs_char_type(acf_parser_state_t *, AST_interface_n_t *, 225 AST_type_n_t *, char const *); 226static void dump_attributes(acf_parser_state_t *, const char *, const char *, acf_attrib_t *); 227 228/* 229 * Warning and Error stuff 230 */ 231 232static void acf_yyerror ( YYLTYPE *, acf_parser_p, char const *); 233 234/* 235** a c f _ e r r o r 236** 237** Issues an error message, and bumps the error count. 238** 239*/ 240static void acf_error 241( 242 acf_parser_state_t * acf, 243 long msgid, 244 ... 245) 246{ 247 va_list ap; 248 249 va_start(ap, msgid); 250 vlog_error(acf_yylineno(acf), msgid, ap); 251 va_end(ap); 252 253 acf->acf_yynerrs++; 254} 255 256/* 257** a c f _ w a r n i n g 258** 259** Issues a warning message. 260** 261*/ 262static void acf_warning 263( 264 acf_parser_state_t * acf, 265 long msgid, 266 ... 267) 268{ 269 va_list ap; 270 271 va_start(ap, msgid); 272 273 vlog_warning(acf_yylineno(acf), msgid, ap); 274 275 va_end(ap); 276} 277 278%} 279 280%locations 281%defines 282%error-verbose 283%pure-parser 284%name-prefix="acf_yy" 285 286/* Tell Bison that the Flexer takes a yyscan_t parameter. */ 287%lex-param { void * lexxer } 288/* Tell Bison that we will pass the yyscan_t scanner into yyparse. */ 289%parse-param { acf_parser_state_t * acf } 290 291/* Tell Bison how to get the lexxer argument from the parser state. */ 292%{ 293#define lexxer acf->acf_yyscanner 294%} 295 296/*------------------------------------* 297 * yylval and yyval type definition * 298 *------------------------------------*/ 299 300/* 301 * Union declaration defines the possible datatypes of the external variables 302 * yylval and yyval. 303 */ 304 305%union 306{ 307 NAMETABLE_id_t y_id; /* Identifier */ 308 STRTAB_str_t y_string; /* Text string */ 309} 310 311%{ 312#include <acf_l.h> 313%} 314 315/*-----------------------------* 316 * Tokens used by the parser * 317 *-----------------------------*/ 318 319/* Keywords */ 320 321%token AUTO_HANDLE_KW 322%token BINDING_CALLOUT_KW 323%token CODE_KW 324%token COMM_STATUS_KW 325%token CS_CHAR_KW 326%token CS_TAG_RTN_KW 327%token ENABLE_ALLOCATE_KW 328%token EXPLICIT_HANDLE_KW 329%token EXTERN_EXCEPS_KW 330%token FAULT_STATUS_KW 331%token HANDLE_T_KW 332%token HEAP_KW 333%token IMPLICIT_HANDLE_KW 334%token INCLUDE_KW 335%token INTERFACE_KW 336%token IN_LINE_KW 337%token NOCODE_KW 338%token NOCANCEL_KW 339%token OUT_OF_LINE_KW 340%token REPRESENT_AS_KW 341%token TYPEDEF_KW 342 343/* Punctuation */ 344 345%token COMMA 346%token LBRACE 347%token LBRACKET 348%token LPAREN 349%token RBRACE 350%token RBRACKET 351%token RPAREN 352%token SEMI 353%token TILDE 354%token UNKNOWN /* Unrecognized by LEX */ 355 356/* Tokens setting yylval */ 357 358%token <y_id> IDENTIFIER 359%token <y_string> STRING 360 361/*-----------------------------* 362 * Starting state for parser * 363 *-----------------------------*/ 364 365%start acf_interface 366 367%% 368 369/**************************** 370 * parser grammar section * 371 ****************************/ 372 373acf_interface: 374 acf_interface_header acf_interface_body 375 ; 376 377acf_interface_header: 378 acf_interface_attr_list INTERFACE_KW acf_interface_name 379 { 380 char const *ast_int_name; /* Interface name in AST node */ 381 NAMETABLE_id_t impl_name_id; /* Nametable id of impl_handle var */ 382 383 if (acf->acf_dumpers) 384 { 385 dump_attributes(acf, "ACF interface", acf->acf_interface_name, 386 &acf->acf_interface_attr); 387 } 388 389 /* Store source information. */ 390 if (the_interface->fe_info != NULL) 391 { 392 the_interface->fe_info->acf_file = acf->acf_location.fileid; 393 the_interface->fe_info->acf_source_line = acf_yylineno(acf); 394 } 395 396 /* 397 * Interface attributes are saved for main and imported interfaces. 398 * the_interface = pointer to main or imported interface node 399 * 400 * Make sure that the interface name in the ACF agrees with the 401 * interface name in the main IDL file. Then set the parsed 402 * attributes in the interface node. 403 * 404 * interface_attr = bitmask of interface attributes parsed. 405 * interface_name = ACF interface name parsed. 406 */ 407 408 NAMETABLE_id_to_string(the_interface->name, &ast_int_name); 409 410 if (strcmp(acf->acf_interface_name, ast_int_name) != 0) 411 { 412 char const *acf_int_name; /* Ptr to permanent copy */ 413 NAMETABLE_id_t name_id; /* Handle on permanent copy */ 414 char const *file_name; /* Related file name */ 415 416 name_id = NAMETABLE_add_id(acf->acf_interface_name); 417 NAMETABLE_id_to_string(name_id, &acf_int_name); 418 419 STRTAB_str_to_string(the_interface->fe_info->file, &file_name); 420 421 acf_error(acf, NIDL_INTNAMDIF, acf_int_name, ast_int_name); 422 acf_error(acf, NIDL_NAMEDECLAT, ast_int_name, file_name, 423 the_interface->fe_info->source_line); 424 } 425 else 426 { 427 if (acf->acf_interface_attr.bit.code) 428 AST_SET_CODE(the_interface); 429 if (acf->acf_interface_attr.bit.nocode) 430 AST_SET_NO_CODE(the_interface); 431 if (acf->acf_interface_attr.bit.decode) 432 AST_SET_DECODE(the_interface); 433 if (acf->acf_interface_attr.bit.encode) 434 AST_SET_ENCODE(the_interface); 435 if (acf->acf_interface_attr.bit.explicit_handle) 436 AST_SET_EXPLICIT_HANDLE(the_interface); 437 if (acf->acf_interface_attr.bit.in_line) 438 AST_SET_IN_LINE(the_interface); 439 if (acf->acf_interface_attr.bit.out_of_line) 440 AST_SET_OUT_OF_LINE(the_interface); 441 if (acf->acf_interface_attr.bit.auto_handle) 442 AST_SET_AUTO_HANDLE(the_interface); 443 if (acf->acf_interface_attr.bit.nocancel) 444 AST_SET_NO_CANCEL(the_interface); 445 446 if (acf->acf_interface_attr.bit.cs_tag_rtn) 447 the_interface->cs_tag_rtn_name = NAMETABLE_add_id(acf->acf_cs_tag_rtn_name); 448 if (acf->acf_interface_attr.bit.binding_callout) 449 { 450 the_interface->binding_callout_name = 451 NAMETABLE_add_id(acf->acf_binding_callout_name); 452 } 453 454 if (acf->acf_interface_attr.bit.implicit_handle) 455 { 456 /* Store the [implicit_handle] variable name in nametbl. */ 457 impl_name_id = NAMETABLE_add_id(acf->acf_impl_name); 458 459 ASTP_set_implicit_handle(the_interface, 460 acf->acf_named_type ? NAMETABLE_add_id(acf->acf_type_name) 461 : NAMETABLE_NIL_ID, 462 impl_name_id); 463 464 } 465 } 466 467 acf->acf_interface_name = NULL; 468 acf->acf_type_name = NULL; 469 acf->acf_impl_name = NULL; 470 acf->acf_binding_callout_name = NULL; 471 acf->acf_cs_tag_rtn_name = NULL; 472 acf->acf_interface_attr.mask = 0; /* Reset attribute mask */ 473 } 474 ; 475 476acf_interface_attr_list: 477 LBRACKET acf_interface_attrs RBRACKET 478 | /* Nothing */ 479 ; 480 481acf_interface_attrs: 482 acf_interface_attr 483 | acf_interface_attrs COMMA acf_interface_attr 484 ; 485 486acf_interface_attr: 487 acf_code_attr 488 { 489 if (acf->acf_interface_attr.bit.code) 490 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 491 acf->acf_interface_attr.bit.code = TRUE; 492 } 493 | acf_nocode_attr 494 { 495 if (acf->acf_interface_attr.bit.nocode) 496 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 497 acf->acf_interface_attr.bit.nocode = TRUE; 498 } 499 | acf_binding_callout_attr 500 { 501 if (acf->acf_interface_attr.bit.binding_callout) 502 log_error(acf_yylineno(acf), NIDL_ATTRUSEMULT, NULL); 503 acf->acf_interface_attr.bit.binding_callout = TRUE; 504 } 505 | acf_cs_tag_rtn_attr 506 { 507 if (acf->acf_interface_attr.bit.cs_tag_rtn) 508 log_error(acf_yylineno(acf), NIDL_ATTRUSEMULT, NULL); 509 acf->acf_interface_attr.bit.cs_tag_rtn = TRUE; 510 } 511 | acf_explicit_handle_attr 512 { 513 if (acf->acf_interface_attr.bit.explicit_handle) 514 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 515 acf->acf_interface_attr.bit.explicit_handle = TRUE; 516 } 517 | acf_nocancel_attr 518 { 519 if (acf->acf_interface_attr.bit.nocancel) 520 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 521 acf->acf_interface_attr.bit.nocancel = TRUE; 522 } 523 | acf_inline_attr 524 { 525 if (acf->acf_interface_attr.bit.in_line) 526 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 527 acf->acf_interface_attr.bit.in_line = TRUE; 528 } 529 | acf_outofline_attr 530 { 531 if (acf->acf_interface_attr.bit.out_of_line) 532 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 533 acf->acf_interface_attr.bit.out_of_line = TRUE; 534 } 535 | acf_implicit_handle_attr 536 { 537 if (acf->acf_interface_attr.bit.implicit_handle) 538 log_error(acf_yylineno(acf), NIDL_ATTRUSEMULT, NULL); 539 acf->acf_interface_attr.bit.implicit_handle = TRUE; 540 } 541 | acf_auto_handle_attr 542 { 543 if (acf->acf_interface_attr.bit.auto_handle) 544 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 545 acf->acf_interface_attr.bit.auto_handle = TRUE; 546 } 547 | acf_extern_exceps_attr 548 { 549 if (acf->acf_interface_attr.bit.extern_exceps) 550 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 551 acf->acf_interface_attr.bit.extern_exceps = TRUE; 552 } 553 | IDENTIFIER 554 { 555 if (NAMETABLE_add_id("decode") == $<y_id>1) 556 { 557 if (acf->acf_interface_attr.bit.decode) 558 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 559 acf->acf_interface_attr.bit.decode = TRUE; 560 } 561 else if (NAMETABLE_add_id("encode") == $<y_id>1) 562 { 563 if (acf->acf_interface_attr.bit.encode) 564 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 565 acf->acf_interface_attr.bit.encode = TRUE; 566 } 567 else 568 log_error(acf_yylineno(acf), NIDL_ERRINATTR, NULL); 569 } 570 ; 571 572acf_implicit_handle_attr: 573 IMPLICIT_HANDLE_KW LPAREN acf_implicit_handle RPAREN 574 ; 575 576acf_implicit_handle: 577 acf_impl_type acf_impl_name 578 ; 579 580acf_impl_type: 581 acf_handle_type 582 { 583 acf->acf_named_type = FALSE; 584 } 585 | IDENTIFIER 586 { 587 NAMETABLE_id_to_string($<y_id>1, &acf->acf_type_name); 588 acf->acf_named_type = TRUE; 589 } 590 ; 591 592acf_handle_type: 593 HANDLE_T_KW 594 ; 595 596acf_impl_name: 597 IDENTIFIER 598 { 599 NAMETABLE_id_to_string($<y_id>1, &acf->acf_impl_name); 600 } 601 ; 602 603acf_extern_exceps_attr: 604 EXTERN_EXCEPS_KW LPAREN acf_ext_excep_list RPAREN 605 | EXTERN_EXCEPS_KW 606 { 607 if (ASTP_parsing_main_idl) 608 { 609 AST_exception_n_t *excep_p; 610 for (excep_p = the_interface->exceptions; 611 excep_p != NULL; 612 excep_p = excep_p->next) 613 { 614 AST_SET_EXTERN(excep_p); 615 } 616 } 617 } 618 ; 619 620acf_ext_excep_list: 621 acf_ext_excep 622 | acf_ext_excep_list COMMA acf_ext_excep 623 ; 624 625acf_ext_excep: 626 IDENTIFIER 627 { 628 AST_exception_n_t *excep_p; 629 if (ASTP_parsing_main_idl) 630 if (lookup_exception(acf, $<y_id>1, TRUE, &excep_p)) 631 AST_SET_EXTERN(excep_p); 632 } 633 ; 634 635acf_interface_name: 636 IDENTIFIER 637 { 638 NAMETABLE_id_to_string($<y_id>1, &acf->acf_interface_name); 639 } 640 ; 641 642acf_interface_body: 643 LBRACE acf_body_elements RBRACE 644 | LBRACE RBRACE 645 | error 646 { log_error(acf_yylineno(acf), NIDL_SYNTAXERR, NULL); } 647 | error RBRACE 648 { log_error(acf_yylineno(acf), NIDL_SYNTAXERR, NULL); } 649 ; 650 651acf_body_elements: 652 acf_body_element 653 | acf_body_elements acf_body_element 654 ; 655 656acf_body_element: 657 acf_include SEMI 658 | acf_type_declaration SEMI 659 | acf_operation_declaration SEMI 660 | error SEMI 661 { 662 log_error(acf_yylineno(acf), NIDL_SYNTAXERR, NULL); 663 /* Re-initialize attr masks to avoid sticky attributes */ 664 acf->acf_interface_attr.mask = 0; 665 acf->acf_type_attr.mask = 0; 666 acf->acf_operation_attr.mask = 0; 667 acf->acf_parameter_attr.mask = 0; 668 } 669 ; 670 671acf_include: 672 INCLUDE_KW acf_include_list 673 { 674 if (ASTP_parsing_main_idl) 675 { 676 the_interface->includes = (AST_include_n_t *) 677 AST_concat_element((ASTP_node_t *)the_interface->includes, 678 (ASTP_node_t *)acf->acf_include_list); 679 } 680 acf->acf_include_list = NULL; 681 } 682 | INCLUDE_KW error 683 { log_error(acf_yylineno(acf), NIDL_SYNTAXERR, NULL); } 684 ; 685 686acf_include_list: 687 acf_include_name 688 | acf_include_list COMMA acf_include_name 689 ; 690 691acf_include_name: 692 STRING 693 { 694 if (ASTP_parsing_main_idl) 695 { 696 char const *parsed_include_file; 697 char include_type[PATH_MAX]; 698 char include_file[PATH_MAX]; 699 STRTAB_str_t include_file_id; 700 701 STRTAB_str_to_string($<y_string>1, &parsed_include_file); 702 703 /* 704 * Log warning if include name contains a file extension. 705 * Tack on the correct extension based on the -lang option. 706 */ 707 FILE_parse(parsed_include_file, (char *)NULL, 0, (char *)NULL, 0, 708 include_type, sizeof (include_type)); 709 if (include_type[0] != '\0') 710 acf_warning(acf, NIDL_INCLUDEXT); 711 712 FILE_form_filespec(parsed_include_file, (char *)NULL, 713 ".h", 714 (char *)NULL, include_file, sizeof(include_file)); 715 716 /* Create an include node. */ 717 include_file_id = STRTAB_add_string(include_file); 718 acf->acf_include_p = AST_include_node(acf_location(acf), 719 include_file_id, $<y_string>1); 720 721 /* Store source information. */ 722 if (acf->acf_include_p->fe_info != NULL) 723 { 724 acf->acf_include_p->fe_info->acf_file = acf->acf_location.fileid; 725 acf->acf_include_p->fe_info->acf_source_line = acf_yylineno(acf); 726 } 727 728 acf->acf_include_list = (AST_include_n_t *) 729 AST_concat_element((ASTP_node_t *)acf->acf_include_list, 730 (ASTP_node_t *)acf->acf_include_p); 731 } 732 } 733 ; 734 735acf_type_declaration: 736 TYPEDEF_KW error 737 { log_error(acf_yylineno(acf), NIDL_SYNTAXERR, NULL); } 738 | TYPEDEF_KW acf_type_attr_list acf_named_type_list 739 { 740 acf->acf_type_attr.mask = 0; /* Reset attribute mask */ 741 acf->acf_repr_type_name = NULL; /* Reset represent_as type name */ 742 acf->acf_cs_char_type_name = NULL; /* Reset cs_char type name */ 743 } 744 ; 745 746acf_named_type_list: 747 acf_named_type 748 { 749 acf->acf_type_name = NULL; /* Reset type name */ 750 } 751 | acf_named_type_list COMMA acf_named_type 752 { 753 acf->acf_type_name = NULL; /* Reset type name */ 754 } 755 ; 756 757acf_named_type: 758 IDENTIFIER 759 { 760 NAMETABLE_id_t type_id; /* Nametable id of type name */ 761 AST_type_n_t *type_p; /* Ptr to AST type node */ 762 763 NAMETABLE_id_to_string($<y_id>1, &acf->acf_type_name); 764 765 if (acf->acf_dumpers) 766 { 767 dump_attributes(acf, "ACF type", 768 acf->acf_type_name, &acf->acf_type_attr); 769 } 770 771 /* 772 * Lookup the type_name parsed and verify that it is a valid type 773 * node. Then set the parsed attributes in the type node. 774 * 775 * type_attr = bitmask of type attributes parsed. 776 * type_name = name of type_t node to look up. 777 * [repr_type_name] = name of represent_as type. 778 * [cs_char_type_name] = name of cs_char type. 779 */ 780 781 if (lookup_type(acf, acf->acf_type_name, TRUE, &type_id, &type_p)) 782 { 783 /* Store source information. */ 784 if (type_p->fe_info != NULL) 785 { 786 type_p->fe_info->acf_file = acf->acf_location.fileid; 787 type_p->fe_info->acf_source_line = acf_yylineno(acf); 788 } 789 790 if (acf->acf_type_attr.bit.heap 791 && type_p->kind != AST_pipe_k 792 && !AST_CONTEXT_RD_SET(type_p)) 793 PROP_set_type_attr(type_p,AST_HEAP); 794 if (acf->acf_type_attr.bit.in_line) 795 PROP_set_type_attr(type_p,AST_IN_LINE); 796 if ((acf->acf_type_attr.bit.out_of_line) && 797 (type_p->kind != AST_pointer_k) && 798 (type_p->xmit_as_type == NULL)) 799 PROP_set_type_attr(type_p,AST_OUT_OF_LINE); 800 if (acf->acf_type_attr.bit.represent_as) 801 process_rep_as_type(acf, the_interface, type_p, acf->acf_repr_type_name); 802 if (acf->acf_type_attr.bit.cs_char) 803 process_cs_char_type(acf, the_interface, type_p, acf->acf_cs_char_type_name); 804 } 805 } 806 ; 807 808acf_type_attr_list: 809 LBRACKET acf_rest_of_attr_list 810 | /* Nothing */ 811 ; 812 813acf_rest_of_attr_list: 814 acf_type_attrs RBRACKET 815 | error SEMI 816 { 817 log_error(acf_yylineno(acf), NIDL_MISSONATTR, NULL); 818 } 819 | error RBRACKET 820 { 821 log_error(acf_yylineno(acf), NIDL_ERRINATTR, NULL); 822 } 823 ; 824 825acf_type_attrs: 826 acf_type_attr 827 | acf_type_attrs COMMA acf_type_attr 828 ; 829 830acf_type_attr: 831 acf_represent_attr 832 { 833 if (acf->acf_type_attr.bit.represent_as) 834 log_error(acf_yylineno(acf), NIDL_ATTRUSEMULT, NULL); 835 acf->acf_type_attr.bit.represent_as = TRUE; 836 } 837 | acf_cs_char_attr 838 { 839 if (acf->acf_type_attr.bit.cs_char) 840 log_error(acf_yylineno(acf), NIDL_ATTRUSEMULT, NULL); 841 acf->acf_type_attr.bit.cs_char = TRUE; 842 } 843 | acf_heap_attr 844 { 845 if (acf->acf_type_attr.bit.heap) 846 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 847 acf->acf_type_attr.bit.heap = TRUE; 848 } 849 | acf_inline_attr 850 { 851 if (acf->acf_type_attr.bit.in_line) 852 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 853 acf->acf_type_attr.bit.in_line = TRUE; 854 } 855 | acf_outofline_attr 856 { 857 if (acf->acf_type_attr.bit.out_of_line) 858 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 859 acf->acf_type_attr.bit.out_of_line = TRUE; 860 } 861 ; 862 863acf_represent_attr: 864 REPRESENT_AS_KW LPAREN acf_repr_type RPAREN 865 ; 866 867acf_repr_type: 868 IDENTIFIER 869 { 870 NAMETABLE_id_to_string($<y_id>1, &acf->acf_repr_type_name); 871 } 872 ; 873 874acf_cs_char_attr: 875 CS_CHAR_KW LPAREN acf_cs_char_type RPAREN 876 ; 877 878acf_cs_char_type: 879 IDENTIFIER 880 { 881 NAMETABLE_id_to_string($<y_id>1, &acf->acf_cs_char_type_name); 882 } 883 ; 884 885acf_operation_declaration: 886 acf_op_attr_list acf_operations 887 { 888 acf->acf_operation_attr.mask = 0; /* Reset attribute mask */ 889 acf->acf_cs_tag_rtn_name = NULL; /* Reset cs_tag_rtn name */ 890 } 891 ; 892 893acf_operations: 894 acf_operation 895 | acf_operations COMMA acf_operation 896 ; 897 898acf_operation: 899 IDENTIFIER LPAREN acf_parameter_list RPAREN 900 { 901 acf_param_t *p; /* Ptr to local parameter structure */ 902 NAMETABLE_id_t op_id; /* Nametable id of operation name */ 903 NAMETABLE_id_t param_id; /* Nametable id of parameter name */ 904 AST_operation_n_t *op_p; /* Ptr to AST operation node */ 905 AST_parameter_n_t *param_p; /* Ptr to AST parameter node */ 906 boolean log_error; /* TRUE => error if name not found */ 907 char const *param_name;/* character string of param id */ 908 909 NAMETABLE_id_to_string($<y_id>1, &acf->acf_operation_name); 910 911 if (acf->acf_dumpers) 912 { 913 dump_attributes(acf, "ACF operation", 914 acf->acf_operation_name, &acf->acf_operation_attr); 915 } 916 917 /* 918 * Operation and parameter attributes are ignored for imported 919 * interfaces. Operations and parameters within imported interfaces 920 * are not put in the AST. 921 */ 922 if (ASTP_parsing_main_idl) 923 { 924 /* 925 * Lookup the operation_name parsed and verify that it is a valid 926 * operation node. Then set the parsed attributes in the operation 927 * node. For each parameter_name that was parsed for this 928 * operation, chase the parameter list off the AST operation node 929 * to verify that it is a valid parameter for that operation. 930 * Then set the parsed attributes for that parameter into the 931 * relevant parameter node. 932 * 933 * operation_attr = bitmask of operation attributes parsed. 934 * operation_name = name of routine_t node to look up. 935 * [cs_tag_rtn_name] = cs_tag_rtn name. 936 * parameter_list = linked list of parameter information. 937 */ 938 939 if (lookup_operation(acf, acf->acf_operation_name, TRUE, &op_id, &op_p)) 940 { 941 /* Store source information. */ 942 if (op_p->fe_info != NULL) 943 { 944 op_p->fe_info->acf_file = acf->acf_location.fileid; 945 op_p->fe_info->acf_source_line = acf_yylineno(acf); 946 } 947 948 if (acf->acf_operation_attr.bit.comm_status) 949 { 950 /* 951 * Assume the AST Builder always builds a result param, 952 * even for void operations. 953 */ 954 AST_SET_COMM_STATUS(op_p->result); 955 } 956 if (acf->acf_operation_attr.bit.fault_status) 957 AST_SET_FAULT_STATUS(op_p->result); 958 959 if (acf->acf_operation_attr.bit.code) 960 AST_SET_CODE(op_p); 961 if (acf->acf_operation_attr.bit.nocode) 962 AST_SET_NO_CODE(op_p); 963 if (acf->acf_operation_attr.bit.decode) 964 AST_SET_DECODE(op_p); 965 if (acf->acf_operation_attr.bit.encode) 966 AST_SET_ENCODE(op_p); 967 if (acf->acf_operation_attr.bit.enable_allocate) 968 AST_SET_ENABLE_ALLOCATE(op_p); 969 if (acf->acf_operation_attr.bit.explicit_handle) 970 AST_SET_EXPLICIT_HANDLE(op_p); 971 if (acf->acf_operation_attr.bit.nocancel) 972 AST_SET_NO_CANCEL(op_p); 973 if (acf->acf_operation_attr.bit.cs_tag_rtn) 974 op_p->cs_tag_rtn_name = NAMETABLE_add_id(acf->acf_cs_tag_rtn_name); 975 976 for (p = acf->acf_parameter_list ; p != NULL ; p = p->next) 977 { 978 /* 979 * Most parameter attributes, if present, require that the 980 * referenced parameter be defined in the IDL. If only 981 * [comm_status] and/or [fault_status] is present, the 982 * parameter needn't be IDL-defined. 983 */ 984 if (!p->parameter_attr.bit.heap 985 && !p->parameter_attr.bit.in_line 986 && !p->parameter_attr.bit.out_of_line 987 && !p->parameter_attr.bit.cs_stag 988 && !p->parameter_attr.bit.cs_drtag 989 && !p->parameter_attr.bit.cs_rtag 990 && (p->parameter_attr.bit.comm_status 991 || p->parameter_attr.bit.fault_status)) 992 log_error = FALSE; 993 else 994 log_error = TRUE; 995 996 NAMETABLE_id_to_string(p->param_id, ¶m_name); 997 if (lookup_parameter(acf, op_p, param_name, log_error, 998 ¶m_id, ¶m_p)) 999 { 1000 /* Store source information. */ 1001 if (param_p->fe_info != NULL) 1002 { 1003 param_p->fe_info->acf_file = acf->acf_location.fileid; 1004 param_p->fe_info->acf_source_line = acf_yylineno(acf); 1005 } 1006 1007 if (p->parameter_attr.bit.comm_status) 1008 AST_SET_COMM_STATUS(param_p); 1009 if (p->parameter_attr.bit.fault_status) 1010 AST_SET_FAULT_STATUS(param_p); 1011 if (p->parameter_attr.bit.heap) 1012 { 1013 AST_type_n_t *ref_type_p; 1014 ref_type_p = param_follow_ref_ptr(param_p, 1015 CHK_follow_ref); 1016 if (ref_type_p->kind != AST_pipe_k 1017 && !AST_CONTEXT_SET(param_p) 1018 && !AST_CONTEXT_RD_SET(ref_type_p) 1019 && !type_is_scalar(ref_type_p)) 1020 AST_SET_HEAP(param_p); 1021 } 1022 if (p->parameter_attr.bit.in_line) 1023 AST_SET_IN_LINE(param_p); 1024 /* 1025 * We parse the [out_of_line] parameter attribute, 1026 * but disallow it. 1027 */ 1028 if (p->parameter_attr.bit.out_of_line) 1029 acf_error(acf, NIDL_INVOOLPRM); 1030 if (p->parameter_attr.bit.cs_stag) 1031 AST_SET_CS_STAG(param_p); 1032 if (p->parameter_attr.bit.cs_drtag) 1033 AST_SET_CS_DRTAG(param_p); 1034 if (p->parameter_attr.bit.cs_rtag) 1035 AST_SET_CS_RTAG(param_p); 1036 } 1037 else if (log_error == FALSE) 1038 { 1039 /* 1040 * Lookup failed, but OK since the parameter only has 1041 * attribute(s) that specify an additional parameter. 1042 * Append a parameter to the operation parameter list. 1043 */ 1044 NAMETABLE_id_to_string(p->param_id, ¶m_name); 1045 append_parameter(acf, op_p, param_name, &p->parameter_attr); 1046 } 1047 } 1048 } 1049 } 1050 1051 free_param_list(acf, &acf->acf_parameter_list); /* Free parameter list */ 1052 1053 acf->acf_operation_name = NULL; 1054 } 1055 ; 1056 1057acf_op_attr_list: 1058 LBRACKET acf_op_attrs RBRACKET 1059 | /* Nothing */ 1060 ; 1061 1062acf_op_attrs: 1063 acf_op_attr 1064 | acf_op_attrs COMMA acf_op_attr 1065 ; 1066 1067acf_op_attr: 1068 acf_commstat_attr 1069 { 1070 if (acf->acf_operation_attr.bit.comm_status) 1071 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1072 acf->acf_operation_attr.bit.comm_status = TRUE; 1073 } 1074 | acf_code_attr 1075 { 1076 if (acf->acf_operation_attr.bit.code) 1077 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1078 acf->acf_operation_attr.bit.code = TRUE; 1079 } 1080 | acf_nocode_attr 1081 { 1082 if (acf->acf_operation_attr.bit.nocode) 1083 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1084 acf->acf_operation_attr.bit.nocode = TRUE; 1085 } 1086 | acf_cs_tag_rtn_attr 1087 { 1088 if (acf->acf_operation_attr.bit.cs_tag_rtn) 1089 log_error(acf_yylineno(acf), NIDL_ATTRUSEMULT, NULL); 1090 acf->acf_operation_attr.bit.cs_tag_rtn = TRUE; 1091 } 1092 | acf_enable_allocate_attr 1093 { 1094 if (acf->acf_operation_attr.bit.enable_allocate) 1095 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1096 acf->acf_operation_attr.bit.enable_allocate = TRUE; 1097 } 1098 | acf_explicit_handle_attr 1099 { 1100 if (acf->acf_operation_attr.bit.explicit_handle) 1101 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1102 acf->acf_operation_attr.bit.explicit_handle = TRUE; 1103 } 1104 | acf_nocancel_attr 1105 { 1106 if (acf->acf_operation_attr.bit.nocancel) 1107 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1108 acf->acf_operation_attr.bit.nocancel = TRUE; 1109 } 1110 | acf_faultstat_attr 1111 { 1112 if (acf->acf_operation_attr.bit.fault_status) 1113 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1114 acf->acf_operation_attr.bit.fault_status = TRUE; 1115 } 1116 | IDENTIFIER 1117 { 1118 if (NAMETABLE_add_id("decode") == $<y_id>1) 1119 { 1120 if (acf->acf_operation_attr.bit.decode) 1121 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1122 acf->acf_operation_attr.bit.decode = TRUE; 1123 } 1124 else if (NAMETABLE_add_id("encode") == $<y_id>1) 1125 { 1126 if (acf->acf_operation_attr.bit.encode) 1127 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1128 acf->acf_operation_attr.bit.encode = TRUE; 1129 } 1130 else 1131 log_error(acf_yylineno(acf), NIDL_ERRINATTR, NULL); 1132 } 1133 ; 1134 1135acf_binding_callout_attr: 1136 BINDING_CALLOUT_KW LPAREN acf_binding_callout_name RPAREN 1137 ; 1138 1139acf_binding_callout_name: 1140 IDENTIFIER 1141 { 1142 NAMETABLE_id_to_string($<y_id>1, &acf->acf_binding_callout_name); 1143 } 1144 ; 1145 1146acf_cs_tag_rtn_attr: 1147 CS_TAG_RTN_KW LPAREN acf_cs_tag_rtn_name RPAREN 1148 ; 1149 1150acf_cs_tag_rtn_name: 1151 IDENTIFIER 1152 { 1153 NAMETABLE_id_to_string($<y_id>1, &acf->acf_cs_tag_rtn_name); 1154 } 1155 ; 1156 1157acf_parameter_list: 1158 acf_parameters 1159 | /* Nothing */ 1160 ; 1161 1162acf_parameters: 1163 acf_parameter 1164 | acf_parameters COMMA acf_parameter 1165 ; 1166 1167acf_parameter: 1168 acf_param_attr_list IDENTIFIER 1169 { 1170 if (acf->acf_dumpers) 1171 { 1172 char const *param_name; 1173 NAMETABLE_id_to_string($<y_id>2, ¶m_name); 1174 dump_attributes(acf, "ACF parameter", 1175 param_name, &acf->acf_parameter_attr); 1176 } 1177 1178 if (acf->acf_parameter_attr_list) /* If there were param attributes: */ 1179 { 1180 acf_param_t *p; /* Pointer to parameter record */ 1181 1182 /* 1183 * Allocate and initialize a parameter record. 1184 */ 1185 p = alloc_param(acf); 1186 p->parameter_attr = acf->acf_parameter_attr; 1187 p->param_id = $<y_id>2; 1188 1189 /* 1190 * Add to end of parameter list. 1191 */ 1192 add_param_to_list(p, &acf->acf_parameter_list); 1193 1194 acf->acf_parameter_attr.mask = 0; 1195 } 1196 } 1197 ; 1198 1199acf_param_attr_list: 1200 LBRACKET acf_param_attrs RBRACKET 1201 { 1202 acf->acf_parameter_attr_list = TRUE; /* Flag that we have param attributes */ 1203 } 1204 | /* Nothing */ 1205 { 1206 acf->acf_parameter_attr_list = FALSE; 1207 } 1208 ; 1209 1210acf_param_attrs: 1211 acf_param_attr 1212 | acf_param_attrs COMMA acf_param_attr 1213 ; 1214 1215acf_param_attr: 1216 acf_commstat_attr 1217 { 1218 if (acf->acf_parameter_attr.bit.comm_status) 1219 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1220 acf->acf_parameter_attr.bit.comm_status = TRUE; 1221 } 1222 | acf_faultstat_attr 1223 { 1224 if (acf->acf_parameter_attr.bit.fault_status) 1225 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1226 acf->acf_parameter_attr.bit.fault_status = TRUE; 1227 } 1228 | acf_heap_attr 1229 { 1230 if (acf->acf_parameter_attr.bit.heap) 1231 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1232 acf->acf_parameter_attr.bit.heap = TRUE; 1233 } 1234 | acf_inline_attr 1235 { 1236 if (acf->acf_parameter_attr.bit.in_line) 1237 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1238 acf->acf_parameter_attr.bit.in_line = TRUE; 1239 } 1240 | acf_outofline_attr 1241 { 1242 if (acf->acf_parameter_attr.bit.out_of_line) 1243 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1244 acf->acf_parameter_attr.bit.out_of_line = TRUE; 1245 } 1246 | IDENTIFIER 1247 { 1248 if (NAMETABLE_add_id("cs_stag") == $<y_id>1) 1249 { 1250 if (acf->acf_parameter_attr.bit.cs_stag) 1251 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1252 acf->acf_parameter_attr.bit.cs_stag = TRUE; 1253 } 1254 else if (NAMETABLE_add_id("cs_drtag") == $<y_id>1) 1255 { 1256 if (acf->acf_parameter_attr.bit.cs_drtag) 1257 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1258 acf->acf_parameter_attr.bit.cs_drtag = TRUE; 1259 } 1260 else if (NAMETABLE_add_id("cs_rtag") == $<y_id>1) 1261 { 1262 if (acf->acf_parameter_attr.bit.cs_rtag) 1263 log_warning(acf_yylineno(acf), NIDL_MULATTRDEF, NULL); 1264 acf->acf_parameter_attr.bit.cs_rtag = TRUE; 1265 } 1266 else 1267 log_error(acf_yylineno(acf), NIDL_ERRINATTR, NULL); 1268 } 1269 ; 1270 1271acf_auto_handle_attr: AUTO_HANDLE_KW; 1272acf_code_attr: CODE_KW; 1273acf_nocode_attr: NOCODE_KW; 1274acf_enable_allocate_attr: ENABLE_ALLOCATE_KW; 1275acf_explicit_handle_attr: EXPLICIT_HANDLE_KW; 1276acf_nocancel_attr: NOCANCEL_KW; 1277acf_heap_attr: HEAP_KW; 1278acf_inline_attr: IN_LINE_KW; 1279acf_outofline_attr: OUT_OF_LINE_KW; 1280acf_commstat_attr: COMM_STATUS_KW; 1281acf_faultstat_attr: FAULT_STATUS_KW; 1282 1283%% 1284 1285/*************************** 1286 * yacc programs section * 1287 ***************************/ 1288 1289/* 1290 * a c f _ p a r s e r _ a l l o c 1291 * 1292 * Function: Called to create an new ACF parser object 1293 * 1294 */ 1295 1296acf_parser_p acf_parser_alloc 1297( 1298 boolean *cmd_opt_arr, /* [in] Array of command option flags */ 1299 void **cmd_val_arr, /* [in] Array of command option values */ 1300 char *acf_file /* [in] ACF file name */ 1301) 1302{ 1303 acf_parser_state_t * acf; 1304 1305 acf = NEW(acf_parser_state_t); 1306 1307 acf->acf_dumpers = FALSE; 1308 1309#ifdef DUMPERS 1310 if (cmd_opt_arr[opt_dump_acf]) 1311 acf->acf_dumpers = TRUE; 1312#else 1313 (void)cmd_opt_arr; 1314#endif 1315 1316 /* Set global (STRTAB_str_t error_file_name_id) for error processing. */ 1317 set_name_for_errors(acf_file); 1318 acf->acf_location.fileid = STRTAB_add_string(acf_file); 1319 1320 // XXX save file name ID in parser state 1321 1322 acf->acf_interface_attr.mask = 0; 1323 acf->acf_type_attr.mask = 0; 1324 acf->acf_operation_attr.mask = 0; 1325 acf->acf_parameter_attr.mask = 0; 1326 1327 acf->acf_interface_name = NULL; 1328 acf->acf_type_name = NULL; 1329 acf->acf_repr_type_name = NULL; 1330 acf->acf_cs_char_type_name = NULL; 1331 acf->acf_operation_name = NULL; 1332 acf->acf_binding_callout_name= NULL; 1333 acf->acf_cs_tag_rtn_name = NULL; 1334 1335 acf->acf_include_list = NULL; 1336 1337 acf->acf_parameter_list = NULL; 1338 acf->acf_parameter_free_list = NULL; 1339 1340 return acf; 1341} 1342 1343/* 1344 * a c f _ p a r s e r _ d e s t r o y 1345 * 1346 * Function: Called after ACF parsing to free allocated memory. 1347 * 1348 */ 1349 1350void acf_parser_destroy 1351( 1352 acf_parser_p acf 1353) 1354{ 1355 acf_param_t *p, *q; /* Ptrs to parameter record */ 1356 1357 p = acf->acf_parameter_free_list; 1358 1359 while (p != NULL) 1360 { 1361 q = p; 1362 p = p->next; 1363 FREE(q); 1364 } 1365 1366 if (acf->acf_yyscanner) 1367 { 1368 acf_yylex_destroy(acf->acf_yyscanner); 1369 } 1370 1371 FREE(acf); 1372 yyin_p = NULL; 1373 yylineno_p = NULL; 1374} 1375 1376void acf_parser_input 1377( 1378 acf_parser_p acf, 1379 FILE * in 1380) 1381{ 1382 1383 assert(acf->acf_yyscanner == NULL); 1384 1385 acf_yylex_init(&acf->acf_yyscanner); 1386 acf_yyset_in(in, acf->acf_yyscanner); 1387 1388 yyin_p = in; 1389 yylineno_p = &acf->acf_location.lineno; 1390} 1391 1392unsigned acf_yylineno 1393( 1394 acf_parser_p acf 1395) 1396{ 1397 return acf_yyget_lineno(acf->acf_yyscanner); 1398} 1399 1400const parser_location_t * acf_location 1401( 1402 acf_parser_p acf 1403) 1404{ 1405 /* Update the current location before handing it back ... */ 1406 acf->acf_location.lineno = acf_yylineno(acf); 1407 acf->acf_location.location = *acf_yyget_lloc(acf->acf_yyscanner); 1408 acf->acf_location.text = acf_yyget_text(acf->acf_yyscanner); 1409 1410 return &acf->acf_location; 1411} 1412 1413unsigned acf_errcount 1414( 1415 acf_parser_p acf 1416) 1417{ 1418 return acf->acf_yynerrs; 1419} 1420 1421static void acf_yyerror 1422( 1423 YYLTYPE * yylloc ATTRIBUTE_UNUSED, 1424 acf_parser_p acf, 1425 char const * message 1426) 1427{ 1428 const struct parser_location_t * loc; 1429 loc = acf_location(acf); 1430 idl_yyerror(loc, message); 1431} 1432 1433/* 1434** l o o k u p _ e x c e p t i o n 1435** 1436** Looks up a name in the nametable, and if it is bound to a valid exception 1437** node, returns the address of the exception node. 1438** 1439** Returns: TRUE if lookup succeeds, FALSE otherwise. 1440*/ 1441 1442static boolean lookup_exception 1443( 1444 acf_parser_state_t *acf, 1445 NAMETABLE_id_t excep_id, /* [in] Nametable id of exception name */ 1446 boolean log_error, /* [in] TRUE => log error if name not found */ 1447 AST_exception_n_t **excep_ptr /*[out] Ptr to AST exception node */ 1448) 1449{ 1450 AST_exception_n_t *excep_p; /* Ptr to node bound to looked up name */ 1451 char const *perm_excep_name; /* Ptr to permanent copy */ 1452 NAMETABLE_id_t name_id ATTRIBUTE_UNUSED; /* Handle on permanent copy */ 1453 1454 if (excep_id != NAMETABLE_NIL_ID) 1455 { 1456 excep_p = (AST_exception_n_t *)NAMETABLE_lookup_binding(excep_id); 1457 1458 if (excep_p != NULL && excep_p->fe_info->node_kind == fe_exception_n_k) 1459 { 1460 *excep_ptr = excep_p; 1461 return TRUE; 1462 } 1463 } 1464 1465 if (log_error) 1466 { 1467 NAMETABLE_id_to_string(excep_id, &perm_excep_name); 1468 acf_error(acf, NIDL_EXCNOTDEF, perm_excep_name); 1469 } 1470 1471 *excep_ptr = NULL; 1472 return FALSE; 1473} 1474 1475/* 1476** l o o k u p _ t y p e 1477** 1478** Looks up a name in the nametable, and if it is bound to a valid type 1479** node, returns the address of the type node. 1480** 1481** Returns: TRUE if lookup succeeds, FALSE otherwise. 1482*/ 1483 1484static boolean lookup_type 1485( 1486 acf_parser_state_t *acf, 1487 char const *type_name, /* [in] Name to look up */ 1488 boolean log_error, /* [in] TRUE => log error if name not found */ 1489 NAMETABLE_id_t *type_id, /*[out] Nametable id of type name */ 1490 AST_type_n_t **type_ptr /*[out] Ptr to AST type node */ 1491) 1492{ 1493 AST_type_n_t *type_p; /* Ptr to node bound to looked up name */ 1494 char const *perm_type_name; /* Ptr to permanent copy */ 1495 NAMETABLE_id_t name_id; /* Handle on permanent copy */ 1496 1497 *type_id = NAMETABLE_lookup_id(type_name); 1498 1499 if (*type_id != NAMETABLE_NIL_ID) 1500 { 1501 type_p = (AST_type_n_t *)NAMETABLE_lookup_binding(*type_id); 1502 1503 if (type_p != NULL && type_p->fe_info->node_kind == fe_type_n_k) 1504 { 1505 *type_ptr = type_p; 1506 return TRUE; 1507 } 1508 } 1509 1510 if (log_error) 1511 { 1512 name_id = NAMETABLE_add_id(type_name); 1513 NAMETABLE_id_to_string(name_id, &perm_type_name); 1514 acf_error(acf, NIDL_TYPNOTDEF, perm_type_name); 1515 } 1516 1517 *type_ptr = NULL; 1518 return FALSE; 1519} 1520 1521/* 1522** l o o k u p _ o p e r a t i o n 1523** 1524** Looks up a name in the nametable, and if it is bound to a valid operation 1525** node, returns the address of the operation node. 1526** 1527** Returns: TRUE if lookup succeeds, FALSE otherwise. 1528*/ 1529 1530static boolean lookup_operation 1531( 1532 acf_parser_state_t *acf, 1533 char const *op_name, /* [in] Name to look up */ 1534 boolean log_error, /* [in] TRUE => log error if name not found */ 1535 NAMETABLE_id_t *op_id, /*[out] Nametable id of operation name */ 1536 AST_operation_n_t **op_ptr /*[out] Ptr to AST operation node */ 1537) 1538{ 1539 AST_operation_n_t *op_p; /* Ptr to node bound to looked up name */ 1540 char const *perm_op_name; /* Ptr to permanent copy */ 1541 NAMETABLE_id_t name_id; /* Handle on permanent copy */ 1542 1543 *op_id = NAMETABLE_lookup_id(op_name); 1544 1545 if (*op_id != NAMETABLE_NIL_ID) 1546 { 1547 op_p = (AST_operation_n_t *)NAMETABLE_lookup_binding(*op_id); 1548 1549 if (op_p != NULL && op_p->fe_info->node_kind == fe_operation_n_k) 1550 { 1551 *op_ptr = op_p; 1552 return TRUE; 1553 } 1554 } 1555 1556 if (log_error) 1557 { 1558 name_id = NAMETABLE_add_id(op_name); 1559 NAMETABLE_id_to_string(name_id, &perm_op_name); 1560 acf_error(acf, NIDL_OPNOTDEF, perm_op_name); 1561 } 1562 1563 *op_ptr = NULL; 1564 return FALSE; 1565} 1566 1567/* 1568** l o o k u p _ p a r a m e t e r 1569** 1570** Searches an operation node's parameter list for the parameter name passed. 1571** If found, returns the address of the parameter node. 1572** 1573** Returns: TRUE if lookup succeeds, FALSE otherwise. 1574*/ 1575 1576static boolean lookup_parameter 1577( 1578 acf_parser_state_t *acf, 1579 AST_operation_n_t *op_p, /* [in] Ptr to AST operation node */ 1580 char const *param_name, /* [in] Parameter name to look up */ 1581 boolean log_error, /* [in] TRUE=> log error if not found */ 1582 NAMETABLE_id_t *param_id, /*[out] Nametable id of param name */ 1583 AST_parameter_n_t **param_ptr /*[out] Ptr to AST parameter node */ 1584) 1585{ 1586 AST_parameter_n_t *param_p; /* Ptr to operation parameter node */ 1587 char const *op_param_name; /* Name of an operation parameter */ 1588 char const *op_name; /* Operation name */ 1589 char const *perm_param_name; /* Ptr to permanent copy */ 1590 NAMETABLE_id_t name_id; /* Handle on permanent copy */ 1591 1592 for (param_p = op_p->parameters ; param_p != NULL ; param_p = param_p->next) 1593 { 1594 NAMETABLE_id_to_string(param_p->name, &op_param_name); 1595 1596 if (strcmp(param_name, op_param_name) == 0) 1597 { 1598 *param_id = param_p->name; 1599 *param_ptr = param_p; 1600 return TRUE; 1601 } 1602 } 1603 1604 if (log_error) 1605 { 1606 char const *file_name; /* Related file name */ 1607 1608 NAMETABLE_id_to_string(op_p->name, &op_name); 1609 name_id = NAMETABLE_add_id(param_name); 1610 NAMETABLE_id_to_string(name_id, &perm_param_name); 1611 1612 STRTAB_str_to_string(op_p->fe_info->file, &file_name); 1613 1614 acf_error(acf, NIDL_PRMNOTDEF, perm_param_name, op_name); 1615 acf_error(acf, NIDL_NAMEDECLAT, op_name, file_name, 1616 op_p->fe_info->source_line); 1617 } 1618 1619 return FALSE; 1620} 1621 1622/* 1623** l o o k u p _ r e p _ a s _ n a m e 1624** 1625** Scans a list of type nodes that have represent_as types for a match with 1626** the type name given by the parameter repr_name_id. If so, returns the 1627** address of the found type node and a pointer to the associated 1628** represent_as type name. 1629** 1630** Returns: TRUE if lookup succeeds, FALSE otherwise. 1631*/ 1632 1633static boolean lookup_rep_as_name 1634( 1635 AST_type_p_n_t *typep_p, /* [in] Listhead of type ptr nodes */ 1636 NAMETABLE_id_t repr_name_id, /* [in] represent_as name to look up */ 1637 AST_type_n_t **ret_type_p, /*[out] Type node if found */ 1638 char const **ret_type_name /*[out] Type name if found */ 1639) 1640{ 1641 AST_type_n_t *type_p; /* Ptr to a type node */ 1642 1643 for ( ; typep_p != NULL ; typep_p = typep_p->next ) 1644 { 1645 type_p = typep_p->type; 1646 if (type_p->name == repr_name_id) 1647 { 1648 *ret_type_p = type_p; 1649 NAMETABLE_id_to_string(type_p->rep_as_type->type_name, 1650 ret_type_name); 1651 return TRUE; 1652 } 1653 } 1654 1655 return FALSE; 1656} 1657 1658/* 1659** l o o k u p _ c s _ c h a r _ n a m e 1660** 1661** Scans a list of type nodes that have cs_char types for a match with 1662** the type name given by the parameter cs_char_name_id. If so, returns the 1663** address of the found type node and a pointer to the associated 1664** cs_char type name. 1665** 1666** Returns: TRUE if lookup succeeds, FALSE otherwise. 1667*/ 1668 1669static boolean lookup_cs_char_name 1670( 1671 AST_type_p_n_t *typep_p, /* [in] Listhead of type ptr nodes */ 1672 NAMETABLE_id_t cs_char_name_id, /* [in] cs_char name to look up */ 1673 AST_type_n_t **ret_type_p, /*[out] Type node if found */ 1674 char const **ret_type_name /*[out] Type name if found */ 1675) 1676{ 1677 AST_type_n_t *type_p; /* Ptr to a type node */ 1678 1679 for ( ; typep_p != NULL ; typep_p = typep_p->next ) 1680 { 1681 type_p = typep_p->type; 1682 if (type_p->name == cs_char_name_id) 1683 { 1684 *ret_type_p = type_p; 1685 NAMETABLE_id_to_string(type_p->cs_char_type->type_name, 1686 ret_type_name); 1687 return TRUE; 1688 } 1689 } 1690 1691 return FALSE; 1692} 1693 1694/* 1695 * a c f _ a l l o c _ p a r a m 1696 * 1697 * Function: Allocates an acf_param_t, either from the free list or heap. 1698 * 1699 * Returns: Address of acf_param_t 1700 * 1701 * Globals: parameter_free_list - listhead for free list 1702 * 1703 * Side Effects: Exits program if unable to allocate memory. 1704 */ 1705 1706static acf_param_t *alloc_param 1707( 1708 acf_parser_state_t * acf 1709) 1710{ 1711 acf_param_t *p; /* Ptr to parameter record */ 1712 1713 if (acf->acf_parameter_free_list != NULL) 1714 { 1715 p = acf->acf_parameter_free_list; 1716 acf->acf_parameter_free_list = acf->acf_parameter_free_list->next; 1717 } 1718 else 1719 { 1720 p = NEW (acf_param_t); 1721 p->next = NULL; 1722 p->parameter_attr.mask = 0; 1723 p->param_id = NAMETABLE_NIL_ID; 1724 } 1725 1726 return p; 1727} 1728 1729/* 1730 * a c f _ f r e e _ p a r a m 1731 * 1732 * Function: Frees an acf_param_t by reinitilizing it and returning it to 1733 * the head of the free list. 1734 * 1735 * Input: p - Pointer to acf_param_t record 1736 * 1737 * Globals: parameter_free_list - listhead for free list 1738 */ 1739 1740static void free_param 1741( 1742 acf_parser_state_t * acf, 1743 acf_param_t *p /* [in] Pointer to acf_param_t record */ 1744) 1745{ 1746 p->parameter_attr.mask = 0; 1747 p->param_id = NAMETABLE_NIL_ID; 1748 1749 p->next = acf->acf_parameter_free_list; 1750 acf->acf_parameter_free_list = p; 1751} 1752 1753/* 1754 * a c f _ f r e e _ p a r a m _ l i s t 1755 * 1756 * Function: Frees a list of acf_param_t records. 1757 * 1758 * Input: list - Address of list pointer 1759 * 1760 * Output: list pointer = NULL 1761 */ 1762 1763static void free_param_list 1764( 1765 acf_parser_state_t * acf, 1766 acf_param_t **list /* [in] Address of list pointer */ 1767) 1768{ 1769 acf_param_t *p, *q; /* Ptrs to parameter record */ 1770 1771 p = *list; 1772 1773 while (p != NULL) 1774 { 1775 q = p; 1776 p = p->next; 1777 free_param(acf, q); 1778 } 1779 1780 *list = NULL; /* List now empty */ 1781} 1782 1783/* 1784 * a d d _ p a r a m _ t o _ l i s t 1785 * 1786 * Function: Add a acf_param_t record to the end of a list. 1787 * 1788 * Inputs: p - Pointer to parameter record 1789 * list - Address of list pointer 1790 * 1791 * Outputs: List is modified. 1792 */ 1793 1794void add_param_to_list 1795( 1796 acf_param_t *p, /* [in] Pointer to parameter record */ 1797 acf_param_t **list /* [in] Address of list pointer */ 1798) 1799{ 1800 acf_param_t *q; /* Ptr to parameter record */ 1801 1802 if (*list == NULL) /* If list empty */ 1803 *list = p; /* then list now points at param */ 1804 else 1805 { 1806 for (q = *list ; q->next != NULL ; q = q->next) 1807 ; 1808 q->next = p; /* else last record in list now points at param */ 1809 } 1810 1811 p->next = NULL; /* Param is now last in list */ 1812} 1813 1814/* 1815** a p p e n d _ p a r a m e t e r 1816** 1817** Appends a parameter to an operation's parameter list. 1818*/ 1819 1820static void append_parameter 1821( 1822 acf_parser_state_t *acf, 1823 AST_operation_n_t *op_p, /* [in] Ptr to AST operation node */ 1824 char const *param_name, /* [in] Parameter name */ 1825 acf_attrib_t *param_attr /* [in] Parameter attributes */ 1826) 1827{ 1828 NAMETABLE_id_t new_param_id; /* Nametable id of new parameter name */ 1829 AST_parameter_n_t *new_param_p; /* Ptr to new parameter node */ 1830 AST_type_n_t *new_type_p; /* Ptr to new parameter type node */ 1831 AST_pointer_n_t *new_ptr_p; /* Ptr to new pointer node */ 1832 NAMETABLE_id_t status_id; /* Nametable id of status_t */ 1833 AST_type_n_t *status_type_p; /* Type node bound to status_t name */ 1834 AST_parameter_n_t *param_p; /* Ptr to operation parameter node */ 1835 1836 /* Look up error_status_t type. */ 1837 status_id = NAMETABLE_add_id("error_status_t"); 1838 status_type_p = (AST_type_n_t *)NAMETABLE_lookup_binding(status_id); 1839 if (status_type_p == NULL) 1840 { 1841 acf_error(acf, NIDL_ERRSTATDEF, "error_status_t", "nbase.idl"); 1842 return; 1843 } 1844 1845 /* 1846 * Have to create an '[out] error_status_t *param_name' parameter 1847 * that has the specified parameter attributes. 1848 */ 1849 new_param_id = NAMETABLE_add_id(param_name); 1850 new_param_p = AST_parameter_node(acf_location(acf), new_param_id); 1851 new_type_p = AST_type_node(acf_location(acf), AST_pointer_k); 1852 new_ptr_p = AST_pointer_node(acf_location(acf), status_type_p); 1853 1854 new_type_p->type_structure.pointer = new_ptr_p; 1855 AST_SET_REF(new_type_p); 1856 1857 new_param_p->name = new_param_id; 1858 new_param_p->type = new_type_p; 1859 new_param_p->uplink = op_p; 1860 if (param_attr->bit.comm_status) 1861 AST_SET_ADD_COMM_STATUS(new_param_p); 1862 if (param_attr->bit.fault_status) 1863 AST_SET_ADD_FAULT_STATUS(new_param_p); 1864 AST_SET_OUT(new_param_p); 1865 AST_SET_REF(new_param_p); 1866 1867 param_p = op_p->parameters; 1868 if (param_p == NULL) 1869 { 1870 /* Was null param list, now has one param. */ 1871 op_p->parameters = new_param_p; 1872 } 1873 else if (param_p->last == NULL) 1874 { 1875 /* Was one param, now have two params. */ 1876 param_p->next = new_param_p; 1877 param_p->last = new_param_p; 1878 } 1879 else 1880 { 1881 /* Was more than one param, now have one more. */ 1882 param_p->last->next = new_param_p; 1883 param_p->last = new_param_p; 1884 } 1885} 1886 1887/* 1888** p r o c e s s _ r e p _ a s _ t y p e 1889** 1890** Processes a [represent_as] clause applied to a type. Validates that 1891** [represent_as] types are not nested. Adds the type to a list of types 1892** that have the [represent_as] attribute. 1893*/ 1894 1895static void process_rep_as_type 1896( 1897 acf_parser_state_t *acf, 1898 AST_interface_n_t *int_p, /* [in] Ptr to AST interface node */ 1899 AST_type_n_t *type_p, /* [in] Ptr to AST type node */ 1900 char const *ref_type_name /* [in] Name in represent_as() clause */ 1901) 1902{ 1903 NAMETABLE_id_t ref_type_id; /* Nametable id of referenced name */ 1904 char const *file_name; /* Related file name */ 1905 char const *perm_name; /* Permanent copy of referenced name */ 1906 AST_type_n_t *parent_type_p; /* Parent type with same attribute */ 1907 char const *parent_name; /* Name of parent type */ 1908 1909 ref_type_id = NAMETABLE_add_id(ref_type_name); 1910 1911 /* 1912 * Report error if the type name referenced in the attribute is an AST 1913 * type which also has the same attribute, i.e. types with this attribute 1914 * cannot nest. 1915 */ 1916 if (lookup_rep_as_name(int_p->ra_types, ref_type_id, &parent_type_p, 1917 &perm_name)) 1918 { 1919 NAMETABLE_id_to_string(parent_type_p->name, &parent_name); 1920 STRTAB_str_to_string(parent_type_p->fe_info->acf_file, &file_name); 1921 1922 acf_error(acf, NIDL_REPASNEST); 1923 acf_error(acf, NIDL_TYPEREPAS, parent_name, perm_name); 1924 acf_error(acf, NIDL_NAMEDECLAT, parent_name, file_name, 1925 parent_type_p->fe_info->acf_source_line); 1926 } 1927 1928 /* 1929 * If the type node already has a type name for this attribute, 1930 * this one must duplicate that same name. 1931 */ 1932 if (type_p->rep_as_type != NULL) 1933 { 1934 NAMETABLE_id_to_string(type_p->rep_as_type->type_name, &perm_name); 1935 1936 if (strcmp(perm_name, ref_type_name) != 0) 1937 { 1938 char const *new_ref_type_name; /* Ptr to permanent copy */ 1939 NAMETABLE_id_t name_id; /* Handle on perm copy */ 1940 1941 name_id = NAMETABLE_add_id(ref_type_name); 1942 NAMETABLE_id_to_string(name_id, &new_ref_type_name); 1943 1944 STRTAB_str_to_string( 1945 type_p->rep_as_type->fe_info->acf_file, &file_name); 1946 1947 acf_error(acf, NIDL_CONFREPRTYPE, new_ref_type_name, perm_name); 1948 acf_error(acf, NIDL_NAMEDECLAT, perm_name, file_name, 1949 type_p->rep_as_type->fe_info->acf_source_line); 1950 } 1951 } 1952 else 1953 { 1954 /* 1955 * Process valid [represent_as] clause. 1956 */ 1957 AST_type_p_n_t *typep_p; /* Used to link type nodes */ 1958 AST_rep_as_n_t *repas_p; /* Ptr to represent_as node */ 1959 1960 /* Add represent_as type name and build rep_as AST node. */ 1961 1962 repas_p = type_p->rep_as_type = 1963 AST_represent_as_node(acf_location(acf),ref_type_id); 1964 /* Store source information. */ 1965 if (repas_p->fe_info != NULL) 1966 { 1967 repas_p->fe_info->acf_file = acf->acf_location.fileid; 1968 repas_p->fe_info->acf_source_line = acf_yylineno(acf); 1969 } 1970 1971 /* Check for associated def-as-tag node. */ 1972 1973 if (type_p->fe_info->tag_ptr != NULL) 1974 type_p->fe_info->tag_ptr->rep_as_type = type_p->rep_as_type; 1975 1976 /* Link type node into list of represent_as types. */ 1977 1978 typep_p = AST_type_ptr_node(acf_location(acf)); 1979 typep_p->type = type_p; 1980 1981 int_p->ra_types = (AST_type_p_n_t *)AST_concat_element( 1982 (ASTP_node_t *)int_p->ra_types, 1983 (ASTP_node_t *)typep_p); 1984 } 1985} 1986 1987/* 1988** p r o c e s s _ c s _ c h a r _ t y p e 1989** 1990** Processes a [cs_char] clause applied to a type. Validates that 1991** [cs_char] types are not nested. Adds the type to a list of types 1992** that have the [cs_char] attribute. 1993*/ 1994 1995static void process_cs_char_type 1996( 1997 acf_parser_state_t *acf, 1998 AST_interface_n_t *int_p, /* [in] Ptr to AST interface node */ 1999 AST_type_n_t *type_p, /* [in] Ptr to AST type node */ 2000 char const *ref_type_name /* [in] Name in cs_char() clause */ 2001) 2002{ 2003 NAMETABLE_id_t ref_type_id; /* Nametable id of referenced name */ 2004 char const *file_name; /* Related file name */ 2005 char const *perm_name; /* Permanent copy of referenced name */ 2006 AST_type_n_t *parent_type_p; /* Parent type with same attribute */ 2007 char const *parent_name; /* Name of parent type */ 2008 2009 ref_type_id = NAMETABLE_add_id(ref_type_name); 2010 2011 /* 2012 * Report error if the type name referenced in the attribute is an AST 2013 * type which also has the same attribute, i.e. types with this attribute 2014 * cannot nest. 2015 */ 2016 if (lookup_cs_char_name(int_p->cs_types, ref_type_id, &parent_type_p, 2017 &perm_name)) 2018 { 2019 NAMETABLE_id_to_string(parent_type_p->name, &parent_name); 2020 STRTAB_str_to_string(parent_type_p->fe_info->acf_file, &file_name); 2021 2022 /*** This needs updating ***/ 2023 acf_error(acf, NIDL_REPASNEST); 2024 acf_error(acf, NIDL_TYPEREPAS, parent_name, perm_name); 2025 acf_error(acf, NIDL_NAMEDECLAT, parent_name, file_name, 2026 parent_type_p->fe_info->acf_source_line); 2027 } 2028 2029 /* 2030 * If the type node already has a type name for this attribute, 2031 * this one must duplicate that same name. 2032 */ 2033 if (type_p->cs_char_type != NULL) 2034 { 2035 NAMETABLE_id_to_string(type_p->cs_char_type->type_name, &perm_name); 2036 2037 if (strcmp(perm_name, ref_type_name) != 0) 2038 { 2039 char const *new_ref_type_name; /* Ptr to permanent copy */ 2040 NAMETABLE_id_t name_id; /* Handle on perm copy */ 2041 2042 name_id = NAMETABLE_add_id(ref_type_name); 2043 NAMETABLE_id_to_string(name_id, &new_ref_type_name); 2044 2045 STRTAB_str_to_string( 2046 type_p->cs_char_type->fe_info->acf_file, &file_name); 2047 2048 /*** This needs updating ***/ 2049 acf_error(acf, NIDL_CONFREPRTYPE, new_ref_type_name, perm_name); 2050 acf_error(acf, NIDL_NAMEDECLAT, perm_name, file_name, 2051 type_p->cs_char_type->fe_info->acf_source_line); 2052 } 2053 } 2054 else 2055 { 2056 /* 2057 * Process valid [cs_char] clause. 2058 */ 2059 AST_type_p_n_t *typep_p; /* Used to link type nodes */ 2060 AST_cs_char_n_t *cschar_p; /* Ptr to cs_char node */ 2061 2062 /* Add cs_char type name and build cs_char AST node. */ 2063 2064 cschar_p = type_p->cs_char_type = AST_cs_char_node( 2065 acf_location(acf), ref_type_id); 2066 /* Store source information. */ 2067 if (cschar_p->fe_info != NULL) 2068 { 2069 cschar_p->fe_info->acf_file = acf->acf_location.fileid; 2070 cschar_p->fe_info->acf_source_line = acf_yylineno(acf); 2071 } 2072 2073 /* Check for associated def-as-tag node. */ 2074 2075 if (type_p->fe_info->tag_ptr != NULL) 2076 type_p->fe_info->tag_ptr->cs_char_type = type_p->cs_char_type; 2077 2078 /* Link type node into list of cs_char types. */ 2079 2080 typep_p = AST_type_ptr_node(acf_location(acf)); 2081 typep_p->type = type_p; 2082 2083 int_p->cs_types = (AST_type_p_n_t *)AST_concat_element( 2084 (ASTP_node_t *)int_p->cs_types, 2085 (ASTP_node_t *)typep_p); 2086 } 2087} 2088 2089/* 2090 * d u m p _ a t t r i b u t e s 2091 * 2092 * Function: Prints list of attributes parsed for a particular node type 2093 * 2094 * Inputs: header_text - Initial text before node name and attributes 2095 * node_name - Name of interface, type, operation, or parameter 2096 * node_attr_p - Address of node attributes structure 2097 * 2098 * Globals: repr_type_name - represent_as type name, used if bit is set 2099 * cs_char_type_name - cs_char type name, used if bit is set 2100 * cs_tag_rtn_name - cs_tag_rtn name, used if bit is set 2101 * binding_callout_name - binding_callout name, used if bit is set 2102 */ 2103 2104static void dump_attributes 2105( 2106 acf_parser_state_t *acf, 2107 const char *header_text, /* [in] Initial output text */ 2108 char const *node_name, /* [in] Name of tree node */ 2109 acf_attrib_t *node_attr_p /* [in] Node attributes ptr */ 2110) 2111#define MAX_ATTR_TEXT 1024 /* Big enough for lots of extern_exceptions */ 2112{ 2113 char attr_text[MAX_ATTR_TEXT]; /* Buf for formatting attrs */ 2114 int pos; /* Position in buffer */ 2115 acf_attrib_t node_attr; /* Node attributes */ 2116 2117 node_attr = *node_attr_p; 2118 2119 printf("%s %s", header_text, node_name); 2120 2121 if (node_attr.mask == 0) 2122 { 2123 printf("\n"); 2124 } 2125 else 2126 { 2127 printf(" attributes: "); 2128 strlcpy(attr_text, "[", sizeof (attr_text)); 2129 2130 if (node_attr.bit.auto_handle) 2131 strlcat(attr_text, "auto_handle, ", sizeof(attr_text)); 2132 if (node_attr.bit.code) 2133 strlcat(attr_text, "code, ", sizeof(attr_text)); 2134 if (node_attr.bit.nocode) 2135 strlcat(attr_text, "nocode, ", sizeof(attr_text)); 2136 if (node_attr.bit.comm_status) 2137 strlcat(attr_text, "comm_status, ", sizeof(attr_text)); 2138 if (node_attr.bit.decode) 2139 strlcat(attr_text, "decode, ", sizeof(attr_text)); 2140 if (node_attr.bit.enable_allocate) 2141 strlcat(attr_text, "enable_allocate, ", sizeof(attr_text)); 2142 if (node_attr.bit.encode) 2143 strlcat(attr_text, "encode, ", sizeof(attr_text)); 2144 if (node_attr.bit.explicit_handle) 2145 strlcat(attr_text, "explicit_handle, ", sizeof(attr_text)); 2146 if (node_attr.bit.nocancel) 2147 strlcat(attr_text, "nocancel, ", sizeof(attr_text)); 2148 if (node_attr.bit.extern_exceps && ASTP_parsing_main_idl) 2149 { 2150 AST_exception_n_t *excep_p; 2151 char const *name; 2152 strlcat(attr_text, "extern_exceptions(", sizeof(attr_text)); 2153 for (excep_p = the_interface->exceptions; 2154 excep_p != NULL; 2155 excep_p = excep_p->next) 2156 { 2157 if (AST_EXTERN_SET(excep_p)) 2158 { 2159 NAMETABLE_id_to_string(excep_p->name, &name); 2160 strlcat(attr_text, name, sizeof(attr_text)); 2161 strlcat(attr_text, ",", sizeof(attr_text)); 2162 } 2163 } 2164 attr_text[strlen(attr_text)-1] = '\0'; /* overwrite trailing ',' */ 2165 strlcat(attr_text, "), ", sizeof(attr_text)); 2166 } 2167 if (node_attr.bit.fault_status) 2168 strlcat(attr_text, "fault_status, ", sizeof(attr_text)); 2169 if (node_attr.bit.heap) 2170 strlcat(attr_text, "heap, ", sizeof(attr_text)); 2171 if (node_attr.bit.implicit_handle) 2172 strlcat(attr_text, "implicit_handle, ", sizeof(attr_text)); 2173 if (node_attr.bit.in_line) 2174 strlcat(attr_text, "in_line, ", sizeof(attr_text)); 2175 if (node_attr.bit.out_of_line) 2176 strlcat(attr_text, "out_of_line, ", sizeof(attr_text)); 2177 if (node_attr.bit.cs_stag) 2178 strlcat(attr_text, "cs_stag, ", sizeof(attr_text)); 2179 if (node_attr.bit.cs_drtag) 2180 strlcat(attr_text, "cs_drtag, ", sizeof(attr_text)); 2181 if (node_attr.bit.cs_rtag) 2182 strlcat(attr_text, "cs_rtag, ", sizeof(attr_text)); 2183 if (node_attr.bit.represent_as) 2184 { 2185 strlcat(attr_text, "represent_as(", sizeof(attr_text)); 2186 strlcat(attr_text, acf->acf_repr_type_name, sizeof(attr_text)); 2187 strlcat(attr_text, "), ", sizeof(attr_text)); 2188 } 2189 if (node_attr.bit.cs_char) 2190 { 2191 strlcat(attr_text, "cs_char(", sizeof(attr_text)); 2192 strlcat(attr_text, acf->acf_cs_char_type_name, sizeof(attr_text)); 2193 strlcat(attr_text, "), ", sizeof(attr_text)); 2194 } 2195 if (node_attr.bit.cs_tag_rtn) 2196 { 2197 strlcat(attr_text, "cs_tag_rtn(", sizeof(attr_text)); 2198 strlcat(attr_text, acf->acf_cs_tag_rtn_name, sizeof(attr_text)); 2199 strlcat(attr_text, "), ", sizeof(attr_text)); 2200 } 2201 if (node_attr.bit.binding_callout) 2202 { 2203 strlcat(attr_text, "binding_callout(", sizeof(attr_text)); 2204 strlcat(attr_text, acf->acf_binding_callout_name, sizeof(attr_text)); 2205 strlcat(attr_text, "), ", sizeof(attr_text)); 2206 } 2207 2208 /* Overwrite trailing ", " with "]" */ 2209 2210 pos = strlen(attr_text) - strlen(", "); 2211 attr_text[pos] = ']'; 2212 attr_text[pos+1] = '\0'; 2213 2214 printf("%s\n", attr_text); 2215 } 2216} 2217 2218/* preserve coding style vim: set tw=78 sw=4 : */ 2219