1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 /* 29 * University Copyright- Copyright (c) 1982, 1986, 1988 30 * The Regents of the University of California 31 * All Rights Reserved 32 * 33 * University Acknowledgment- Portions of this document are derived from 34 * software developed by the University of California, Berkeley, and its 35 * contributors. 36 */ 37 38 /* 39 * rpc_parse.c, Parser for the RPC protocol compiler 40 */ 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include "rpc/types.h" 45 #include "rpc_scan.h" 46 #include "rpc_parse.h" 47 #include "rpc_util.h" 48 49 #define ARGNAME "arg" 50 51 extern char *make_argname(char *, char *); 52 53 static void isdefined(definition *); 54 static void def_struct(definition *); 55 static void def_program(definition *); 56 static void def_enum(definition *); 57 static void def_const(definition *); 58 static void def_union(definition *); 59 static void def_typedef(definition *); 60 static void get_declaration(declaration *, defkind); 61 static void get_prog_declaration(declaration *, defkind, int); 62 static void get_type(char **, char **, defkind); 63 static void unsigned_dec(char **); 64 65 /* 66 * return the next definition you see 67 */ 68 definition * 69 get_definition(void) 70 { 71 definition *defp; 72 token tok; 73 74 defp = calloc(1, sizeof (definition)); 75 get_token(&tok); 76 switch (tok.kind) { 77 case TOK_STRUCT: 78 def_struct(defp); 79 break; 80 case TOK_UNION: 81 def_union(defp); 82 break; 83 case TOK_TYPEDEF: 84 def_typedef(defp); 85 break; 86 case TOK_ENUM: 87 def_enum(defp); 88 break; 89 case TOK_PROGRAM: 90 def_program(defp); 91 break; 92 case TOK_CONST: 93 def_const(defp); 94 break; 95 case TOK_EOF: 96 return (NULL); 97 default: 98 error("definition keyword expected"); 99 } 100 scan(TOK_SEMICOLON, &tok); 101 isdefined(defp); 102 return (defp); 103 } 104 105 static void 106 isdefined(definition *defp) 107 { 108 STOREVAL(&defined, defp); 109 } 110 111 /* 112 * We treat s == NULL the same as *s == '\0' 113 */ 114 static int 115 streqn(const char *s1, const char *s2) 116 { 117 if (s1 == NULL) 118 s1 = ""; 119 if (s2 == NULL) 120 s2 = ""; 121 if (s1 == s2) 122 return (1); 123 124 return (strcmp(s1, s2) == 0); 125 } 126 127 static int 128 cmptype(definition *defp, char *type) 129 { 130 /* We only want typedef definitions */ 131 if (streq(defp->def_name, type) && defp->def_kind == DEF_TYPEDEF) 132 return (1); 133 return (0); 134 } 135 136 static int 137 check_self_reference(const char *name, const declaration *decp, int first) 138 { 139 /* 140 * Now check for the following special case if first is true: 141 * 142 * struct foo { 143 * ... 144 * foo *next; 145 * }; 146 * 147 * 148 * In the above cases foo has not yet been entered in the type list, 149 * defined. So there is no typedef entry. The prefix in that case 150 * could be empty. 151 */ 152 if (decp->rel == REL_POINTER && 153 (streqn(decp->prefix, "struct") || 154 (first && streqn(decp->prefix, ""))) && 155 streqn(name, decp->type)) 156 return (1); 157 return (0); 158 } 159 160 static int 161 is_self_reference(definition *defp, declaration *decp) 162 { 163 declaration current; 164 definition *dp; 165 166 if (check_self_reference(defp->def_name, decp, 1)) 167 return (1); 168 169 /* 170 * Check for valid declaration: 171 * Only prefixes allowed are none and struct. 172 * Only relations allowed are pointer or alias. 173 */ 174 if (!streqn(decp->prefix, "struct") && !streqn(decp->prefix, "")) 175 return (0); 176 if (decp->rel != REL_POINTER && decp->rel != REL_ALIAS) 177 return (0); 178 179 current.rel = decp->rel; 180 current.prefix = decp->prefix; 181 current.type = decp->type; 182 current.name = decp->name; 183 decp = ¤t; 184 while (!check_self_reference(defp->def_name, decp, 0)) { 185 dp = FINDVAL(defined, decp->type, cmptype); 186 187 /* 188 * Check if we found a definition. 189 */ 190 if (dp == NULL) 191 return (0); 192 193 /* 194 * Check for valid prefix. We eventually need to see one 195 * and only one struct. 196 */ 197 if (streqn(decp->prefix, "")) { 198 /* 199 * If the current declaration prefix in empty 200 * then the definition found must have an empty 201 * prefix or a struct prefix 202 */ 203 if (!streqn(dp->def.ty.old_prefix, "") && 204 !streqn(dp->def.ty.old_prefix, "struct")) 205 return (0); 206 } else if (streqn(decp->prefix, "struct") && 207 !streqn(dp->def.ty.old_prefix, "")) 208 /* 209 * if the current prefix is struct tne new prefix 210 * must be empty 211 */ 212 return (0); 213 else if (!streqn(decp->prefix, "struct")) 214 /* Should never get here */ 215 return (0); 216 217 /* 218 * Check for valid relation. We need to see one and 219 * only one REL_POINTER. The only valid relation types 220 * are REL_POINTER and REL_ALIAS. 221 */ 222 if (decp->rel == REL_POINTER && dp->def.ty.rel != REL_ALIAS) 223 return (0); 224 if (decp->rel == REL_ALIAS && 225 (dp->def.ty.rel != REL_ALIAS && 226 dp->def.ty.rel != REL_POINTER)) 227 return (0); 228 if (decp->rel != REL_ALIAS && decp->rel != REL_POINTER) 229 /* Should never get here */ 230 return (0); 231 232 /* Set up the current declaration */ 233 if (streqn(decp->prefix, "")) 234 decp->prefix = dp->def.ty.old_prefix; 235 decp->type = dp->def.ty.old_type; 236 if (decp->rel == REL_ALIAS) 237 decp->rel = dp->def.ty.rel; 238 } 239 240 /* We have a self reference type */ 241 return (1); 242 } 243 244 static void 245 def_struct(definition *defp) 246 { 247 token tok; 248 declaration dec; 249 decl_list *decls; 250 decl_list **tailp, *endp; 251 252 defp->def_kind = DEF_STRUCT; 253 254 scan(TOK_IDENT, &tok); 255 defp->def_name = tok.str; 256 scan(TOK_LBRACE, &tok); 257 tailp = &defp->def.st.decls; 258 defp->def.st.tail = NULL; 259 do { 260 get_declaration(&dec, DEF_STRUCT); 261 decls = calloc(1, sizeof (decl_list)); 262 decls->decl = dec; 263 /* 264 * Keep a referenct to the last declaration to check for 265 * tail recurrsion. 266 */ 267 endp = *tailp = decls; 268 tailp = &decls->next; 269 scan(TOK_SEMICOLON, &tok); 270 peek(&tok); 271 } while (tok.kind != TOK_RBRACE); 272 *tailp = NULL; 273 /* 274 * Check for tail recurse. If the last declaration refers to this 275 * structure then mark this stucture to convert the tail recursion 276 * to itteration. 277 */ 278 defp->def.st.self_pointer = is_self_reference(defp, &endp->decl); 279 get_token(&tok); 280 defp->def.st.tail = endp; 281 } 282 283 static void 284 def_program(definition *defp) 285 { 286 token tok; 287 declaration dec; 288 decl_list *decls; 289 decl_list **tailp; 290 version_list *vlist; 291 version_list **vtailp; 292 proc_list *plist; 293 proc_list **ptailp; 294 int num_args; 295 bool_t isvoid = FALSE; /* whether first argument is void */ 296 defp->def_kind = DEF_PROGRAM; 297 scan(TOK_IDENT, &tok); 298 defp->def_name = tok.str; 299 scan(TOK_LBRACE, &tok); 300 vtailp = &defp->def.pr.versions; 301 tailp = &defp->def.st.decls; 302 scan(TOK_VERSION, &tok); 303 do { 304 scan(TOK_IDENT, &tok); 305 vlist = calloc(1, sizeof (version_list)); 306 vlist->vers_name = tok.str; 307 scan(TOK_LBRACE, &tok); 308 ptailp = &vlist->procs; 309 do { 310 /* get result type */ 311 plist = calloc(1, sizeof (proc_list)); 312 get_type(&plist->res_prefix, &plist->res_type, 313 DEF_RESULT); 314 if (streq(plist->res_type, "opaque")) { 315 error("illegal result type"); 316 } 317 scan(TOK_IDENT, &tok); 318 plist->proc_name = tok.str; 319 scan(TOK_LPAREN, &tok); 320 /* get args - first one */ 321 num_args = 1; 322 isvoid = FALSE; 323 /* 324 * type of DEF_PROGRAM in the first 325 * get_prog_declaration and DEF_STURCT in the next 326 * allows void as argument if it is the only argument 327 */ 328 get_prog_declaration(&dec, DEF_PROGRAM, num_args); 329 if (streq(dec.type, "void")) 330 isvoid = TRUE; 331 decls = calloc(1, sizeof (decl_list)); 332 plist->args.decls = decls; 333 decls->decl = dec; 334 tailp = &decls->next; 335 /* get args */ 336 while (peekscan(TOK_COMMA, &tok)) { 337 num_args++; 338 get_prog_declaration(&dec, DEF_STRUCT, 339 num_args); 340 decls = calloc(1, sizeof (decl_list)); 341 decls->decl = dec; 342 *tailp = decls; 343 if (streq(dec.type, "void")) 344 isvoid = TRUE; 345 tailp = &decls->next; 346 } 347 /* multiple arguments are only allowed in newstyle */ 348 if (!newstyle && num_args > 1) { 349 error("only one argument is allowed"); 350 } 351 if (isvoid && num_args > 1) { 352 error("illegal use of void " 353 "in program definition"); 354 } 355 *tailp = NULL; 356 scan(TOK_RPAREN, &tok); 357 scan(TOK_EQUAL, &tok); 358 scan_num(&tok); 359 scan(TOK_SEMICOLON, &tok); 360 plist->proc_num = tok.str; 361 plist->arg_num = num_args; 362 *ptailp = plist; 363 ptailp = &plist->next; 364 peek(&tok); 365 } while (tok.kind != TOK_RBRACE); 366 *ptailp = NULL; 367 *vtailp = vlist; 368 vtailp = &vlist->next; 369 scan(TOK_RBRACE, &tok); 370 scan(TOK_EQUAL, &tok); 371 scan_num(&tok); 372 vlist->vers_num = tok.str; 373 /* make the argument structure name for each arg */ 374 for (plist = vlist->procs; plist != NULL; plist = plist->next) { 375 plist->args.argname = make_argname(plist->proc_name, 376 vlist->vers_num); 377 /* free the memory ?? */ 378 } 379 scan(TOK_SEMICOLON, &tok); 380 scan2(TOK_VERSION, TOK_RBRACE, &tok); 381 } while (tok.kind == TOK_VERSION); 382 scan(TOK_EQUAL, &tok); 383 scan_num(&tok); 384 defp->def.pr.prog_num = tok.str; 385 *vtailp = NULL; 386 } 387 388 static void 389 def_enum(definition *defp) 390 { 391 token tok; 392 enumval_list *elist; 393 enumval_list **tailp; 394 395 defp->def_kind = DEF_ENUM; 396 scan(TOK_IDENT, &tok); 397 defp->def_name = tok.str; 398 scan(TOK_LBRACE, &tok); 399 tailp = &defp->def.en.vals; 400 do { 401 scan(TOK_IDENT, &tok); 402 elist = calloc(1, sizeof (enumval_list)); 403 elist->name = tok.str; 404 elist->assignment = NULL; 405 scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); 406 if (tok.kind == TOK_EQUAL) { 407 scan_num(&tok); 408 elist->assignment = tok.str; 409 scan2(TOK_COMMA, TOK_RBRACE, &tok); 410 } 411 *tailp = elist; 412 tailp = &elist->next; 413 } while (tok.kind != TOK_RBRACE); 414 *tailp = NULL; 415 } 416 417 static void 418 def_const(definition *defp) 419 { 420 token tok; 421 422 defp->def_kind = DEF_CONST; 423 scan(TOK_IDENT, &tok); 424 defp->def_name = tok.str; 425 scan(TOK_EQUAL, &tok); 426 scan2(TOK_IDENT, TOK_STRCONST, &tok); 427 defp->def.co = tok.str; 428 } 429 430 static void 431 def_union(definition *defp) 432 { 433 token tok; 434 declaration dec; 435 case_list *cases; 436 case_list **tailp; 437 int flag; 438 439 defp->def_kind = DEF_UNION; 440 scan(TOK_IDENT, &tok); 441 defp->def_name = tok.str; 442 scan(TOK_SWITCH, &tok); 443 scan(TOK_LPAREN, &tok); 444 get_declaration(&dec, DEF_UNION); 445 defp->def.un.enum_decl = dec; 446 tailp = &defp->def.un.cases; 447 scan(TOK_RPAREN, &tok); 448 scan(TOK_LBRACE, &tok); 449 scan(TOK_CASE, &tok); 450 while (tok.kind == TOK_CASE) { 451 scan2(TOK_IDENT, TOK_CHARCONST, &tok); 452 cases = calloc(1, sizeof (case_list)); 453 cases->case_name = tok.str; 454 scan(TOK_COLON, &tok); 455 /* now peek at next token */ 456 flag = 0; 457 if (peekscan(TOK_CASE, &tok)) { 458 do { 459 scan2(TOK_IDENT, TOK_CHARCONST, &tok); 460 cases->contflag = 1; 461 /* continued case statement */ 462 *tailp = cases; 463 tailp = &cases->next; 464 cases = calloc(1, sizeof (case_list)); 465 cases->case_name = tok.str; 466 scan(TOK_COLON, &tok); 467 } while (peekscan(TOK_CASE, &tok)); 468 } else if (flag) { 469 *tailp = cases; 470 tailp = &cases->next; 471 cases = calloc(1, sizeof (case_list)); 472 } 473 474 get_declaration(&dec, DEF_UNION); 475 cases->case_decl = dec; 476 cases->contflag = 0; /* no continued case statement */ 477 *tailp = cases; 478 tailp = &cases->next; 479 scan(TOK_SEMICOLON, &tok); 480 481 scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); 482 } 483 *tailp = NULL; 484 if (tok.kind == TOK_DEFAULT) { 485 scan(TOK_COLON, &tok); 486 get_declaration(&dec, DEF_UNION); 487 defp->def.un.default_decl = calloc(1, sizeof (declaration)); 488 *defp->def.un.default_decl = dec; 489 scan(TOK_SEMICOLON, &tok); 490 scan(TOK_RBRACE, &tok); 491 } else { 492 defp->def.un.default_decl = NULL; 493 } 494 } 495 496 static char *reserved_words[] = { 497 "array", 498 "bytes", 499 "destroy", 500 "free", 501 "getpos", 502 "inline", 503 "pointer", 504 "reference", 505 "setpos", 506 "sizeof", 507 "union", 508 "vector", 509 NULL 510 }; 511 512 static char *reserved_types[] = { 513 "opaque", 514 "string", 515 NULL 516 }; 517 518 /* 519 * check that the given name is not one that would eventually result in 520 * xdr routines that would conflict with internal XDR routines. 521 */ 522 static void 523 check_type_name(char *name, int new_type) 524 { 525 int i; 526 char tmp[100]; 527 528 for (i = 0; reserved_words[i] != NULL; i++) { 529 if (strcmp(name, reserved_words[i]) == 0) { 530 (void) snprintf(tmp, sizeof (tmp), 531 "illegal (reserved) name :\'%s\' " 532 "in type definition", 533 name); 534 error(tmp); 535 } 536 } 537 if (new_type) { 538 for (i = 0; reserved_types[i] != NULL; i++) { 539 if (strcmp(name, reserved_types[i]) == 0) { 540 (void) snprintf(tmp, sizeof (tmp), 541 "illegal (reserved) name :\'%s\' " 542 "in type definition", 543 name); 544 error(tmp); 545 } 546 } 547 } 548 } 549 550 static void 551 def_typedef(definition *defp) 552 { 553 declaration dec; 554 555 defp->def_kind = DEF_TYPEDEF; 556 get_declaration(&dec, DEF_TYPEDEF); 557 defp->def_name = dec.name; 558 check_type_name(dec.name, 1); 559 defp->def.ty.old_prefix = dec.prefix; 560 defp->def.ty.old_type = dec.type; 561 defp->def.ty.rel = dec.rel; 562 defp->def.ty.array_max = dec.array_max; 563 } 564 565 static void 566 get_declaration(declaration *dec, defkind dkind) 567 { 568 token tok; 569 570 get_type(&dec->prefix, &dec->type, dkind); 571 dec->rel = REL_ALIAS; 572 if (streq(dec->type, "void")) 573 return; 574 575 check_type_name(dec->type, 0); 576 scan2(TOK_STAR, TOK_IDENT, &tok); 577 if (tok.kind == TOK_STAR) { 578 dec->rel = REL_POINTER; 579 scan(TOK_IDENT, &tok); 580 } 581 dec->name = tok.str; 582 if (peekscan(TOK_LBRACKET, &tok)) { 583 if (dec->rel == REL_POINTER) 584 error("no array-of-pointer declarations " 585 "-- use typedef"); 586 dec->rel = REL_VECTOR; 587 scan_num(&tok); 588 dec->array_max = tok.str; 589 scan(TOK_RBRACKET, &tok); 590 } else if (peekscan(TOK_LANGLE, &tok)) { 591 if (dec->rel == REL_POINTER) 592 error("no array-of-pointer declarations " 593 "-- use typedef"); 594 dec->rel = REL_ARRAY; 595 if (peekscan(TOK_RANGLE, &tok)) { 596 dec->array_max = "~0"; /* unspecified size, use max */ 597 } else { 598 scan_num(&tok); 599 dec->array_max = tok.str; 600 scan(TOK_RANGLE, &tok); 601 } 602 } 603 if (streq(dec->type, "opaque")) { 604 if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { 605 error("array declaration expected"); 606 } 607 } else if (streq(dec->type, "string")) { 608 if (dec->rel != REL_ARRAY) { 609 error("variable-length array declaration expected"); 610 } 611 } 612 } 613 614 static void 615 get_prog_declaration(declaration *dec, defkind dkind, int num) 616 { 617 token tok; 618 char name[sizeof (ARGNAME) + 10]; 619 620 if (dkind == DEF_PROGRAM) { 621 peek(&tok); 622 if (tok.kind == TOK_RPAREN) { /* no arguments */ 623 dec->rel = REL_ALIAS; 624 dec->type = "void"; 625 dec->prefix = NULL; 626 dec->name = NULL; 627 return; 628 } 629 } 630 get_type(&dec->prefix, &dec->type, dkind); 631 dec->rel = REL_ALIAS; 632 if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */ 633 dec->name = strdup(tok.str); 634 else { 635 /* default name of argument */ 636 (void) snprintf(name, sizeof (name), "%s%d", ARGNAME, num); 637 dec->name = strdup(name); 638 } 639 if (dec->name == NULL) 640 error("internal error -- out of memory"); 641 642 if (streq(dec->type, "void")) 643 return; 644 645 if (streq(dec->type, "opaque")) 646 error("opaque -- illegal argument type"); 647 if (peekscan(TOK_STAR, &tok)) { 648 if (streq(dec->type, "string")) { 649 error("pointer to string not allowed " 650 "in program arguments\n"); 651 } 652 dec->rel = REL_POINTER; 653 if (peekscan(TOK_IDENT, &tok)) 654 /* optional name of argument */ 655 dec->name = strdup(tok.str); 656 } 657 if (peekscan(TOK_LANGLE, &tok)) { 658 if (!streq(dec->type, "string")) { 659 error("arrays cannot be declared as arguments " 660 "to procedures -- use typedef"); 661 } 662 dec->rel = REL_ARRAY; 663 if (peekscan(TOK_RANGLE, &tok)) { 664 dec->array_max = "~0"; 665 /* unspecified size, use max */ 666 } else { 667 scan_num(&tok); 668 dec->array_max = tok.str; 669 scan(TOK_RANGLE, &tok); 670 } 671 } 672 if (streq(dec->type, "string")) { 673 if (dec->rel != REL_ARRAY) { 674 /* 675 * .x specifies just string as 676 * type of argument 677 * - make it string<> 678 */ 679 dec->rel = REL_ARRAY; 680 dec->array_max = "~0"; /* unspecified size, use max */ 681 } 682 } 683 } 684 685 static void 686 get_type(char **prefixp, char **typep, defkind dkind) 687 { 688 token tok; 689 690 *prefixp = NULL; 691 get_token(&tok); 692 switch (tok.kind) { 693 case TOK_IDENT: 694 *typep = tok.str; 695 break; 696 case TOK_STRUCT: 697 case TOK_ENUM: 698 case TOK_UNION: 699 *prefixp = tok.str; 700 scan(TOK_IDENT, &tok); 701 *typep = tok.str; 702 break; 703 case TOK_UNSIGNED: 704 unsigned_dec(typep); 705 break; 706 case TOK_SHORT: 707 *typep = "short"; 708 (void) peekscan(TOK_INT, &tok); 709 break; 710 case TOK_LONG: 711 *typep = "long"; 712 (void) peekscan(TOK_INT, &tok); 713 break; 714 case TOK_HYPER: 715 *typep = "longlong_t"; 716 (void) peekscan(TOK_INT, &tok); 717 break; 718 719 case TOK_VOID: 720 if (dkind != DEF_UNION && dkind != DEF_PROGRAM && 721 dkind != DEF_RESULT) { 722 error("voids allowed only inside union and " 723 "program definitions with one argument"); 724 } 725 *typep = tok.str; 726 break; 727 case TOK_ONEWAY: 728 if (dkind != DEF_RESULT) { 729 error("oneways allowed only inside result definitions"); 730 } 731 *typep = tok.str; 732 break; 733 case TOK_STRING: 734 case TOK_OPAQUE: 735 case TOK_CHAR: 736 case TOK_INT: 737 case TOK_FLOAT: 738 case TOK_DOUBLE: 739 case TOK_BOOL: 740 case TOK_QUAD: 741 *typep = tok.str; 742 break; 743 default: 744 error("expected type specifier"); 745 } 746 } 747 748 static void 749 unsigned_dec(char **typep) 750 { 751 token tok; 752 753 peek(&tok); 754 switch (tok.kind) { 755 case TOK_CHAR: 756 get_token(&tok); 757 *typep = "u_char"; 758 break; 759 case TOK_SHORT: 760 get_token(&tok); 761 *typep = "u_short"; 762 (void) peekscan(TOK_INT, &tok); 763 break; 764 case TOK_LONG: 765 get_token(&tok); 766 *typep = "u_long"; 767 (void) peekscan(TOK_INT, &tok); 768 break; 769 case TOK_HYPER: 770 get_token(&tok); 771 *typep = "u_longlong_t"; 772 (void) peekscan(TOK_INT, &tok); 773 break; 774 case TOK_INT: 775 get_token(&tok); 776 *typep = "u_int"; 777 break; 778 default: 779 *typep = "u_int"; 780 break; 781 } 782 } 783