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