1 /* $FreeBSD$ */ 2 /* 3 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 4 * unrestricted use provided that this legend is included on all tape 5 * media and as a part of the software program in whole or part. Users 6 * may copy or modify Sun RPC without charge, but are not authorized 7 * to license or distribute it to anyone else except as part of a product or 8 * program developed by the user. 9 * 10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13 * 14 * Sun RPC is provided with no support and without any obligation on the 15 * part of Sun Microsystems, Inc. to assist in its use, correction, 16 * modification or enhancement. 17 * 18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20 * OR ANY PART THEREOF. 21 * 22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23 * or profits or other special, indirect and consequential damages, even if 24 * Sun has been advised of the possibility of such damages. 25 * 26 * Sun Microsystems, Inc. 27 * 2550 Garcia Avenue 28 * Mountain View, California 94043 29 */ 30 31 #ident "@(#)rpc_parse.c 1.12 93/07/05 SMI" 32 33 #ifndef lint 34 static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI"; 35 #endif 36 37 /* 38 * rpc_parse.c, Parser for the RPC protocol compiler 39 * Copyright (C) 1987 Sun Microsystems, Inc. 40 */ 41 #include <stdio.h> 42 #include <string.h> 43 #include "rpc/types.h" 44 #include "rpc_scan.h" 45 #include "rpc_parse.h" 46 #include "rpc_util.h" 47 48 #define ARGNAME "arg" 49 50 extern char *make_argname __P(( char *, char * )); 51 static void isdefined __P(( definition * )); 52 static void def_struct __P(( definition * )); 53 static void def_program __P(( definition * )); 54 static void def_enum __P(( definition * )); 55 static void def_const __P(( definition * )); 56 static void def_union __P(( definition * )); 57 static void def_typedef __P(( definition * )); 58 static void get_declaration __P(( declaration *, defkind )); 59 static void get_prog_declaration __P(( declaration *, defkind, int )); 60 static void get_type __P(( char **, char **, defkind )); 61 static void unsigned_dec __P(( char ** )); 62 63 #ifndef __FreeBSD__ 64 extern char *strdup(); 65 #endif 66 67 /* 68 * return the next definition you see 69 */ 70 definition * 71 get_definition() 72 { 73 definition *defp; 74 token tok; 75 76 defp = ALLOC(definition); 77 get_token(&tok); 78 switch (tok.kind) { 79 case TOK_STRUCT: 80 def_struct(defp); 81 break; 82 case TOK_UNION: 83 def_union(defp); 84 break; 85 case TOK_TYPEDEF: 86 def_typedef(defp); 87 break; 88 case TOK_ENUM: 89 def_enum(defp); 90 break; 91 case TOK_PROGRAM: 92 def_program(defp); 93 break; 94 case TOK_CONST: 95 def_const(defp); 96 break; 97 case TOK_EOF: 98 return (NULL); 99 default: 100 error("definition keyword expected"); 101 } 102 scan(TOK_SEMICOLON, &tok); 103 isdefined(defp); 104 return (defp); 105 } 106 107 static void 108 isdefined(defp) 109 definition *defp; 110 { 111 STOREVAL(&defined, defp); 112 } 113 114 static void 115 def_struct(defp) 116 definition *defp; 117 { 118 token tok; 119 declaration dec; 120 decl_list *decls; 121 decl_list **tailp; 122 123 defp->def_kind = DEF_STRUCT; 124 125 scan(TOK_IDENT, &tok); 126 defp->def_name = tok.str; 127 scan(TOK_LBRACE, &tok); 128 tailp = &defp->def.st.decls; 129 do { 130 get_declaration(&dec, DEF_STRUCT); 131 decls = ALLOC(decl_list); 132 decls->decl = dec; 133 *tailp = decls; 134 tailp = &decls->next; 135 scan(TOK_SEMICOLON, &tok); 136 peek(&tok); 137 } while (tok.kind != TOK_RBRACE); 138 get_token(&tok); 139 *tailp = NULL; 140 } 141 142 static void 143 def_program(defp) 144 definition *defp; 145 { 146 token tok; 147 declaration dec; 148 decl_list *decls; 149 decl_list **tailp; 150 version_list *vlist; 151 version_list **vtailp; 152 proc_list *plist; 153 proc_list **ptailp; 154 int num_args; 155 bool_t isvoid = FALSE; /* whether first argument is void */ 156 defp->def_kind = DEF_PROGRAM; 157 scan(TOK_IDENT, &tok); 158 defp->def_name = tok.str; 159 scan(TOK_LBRACE, &tok); 160 vtailp = &defp->def.pr.versions; 161 tailp = &defp->def.st.decls; 162 scan(TOK_VERSION, &tok); 163 do { 164 scan(TOK_IDENT, &tok); 165 vlist = ALLOC(version_list); 166 vlist->vers_name = tok.str; 167 scan(TOK_LBRACE, &tok); 168 ptailp = &vlist->procs; 169 do { 170 /* get result type */ 171 plist = ALLOC(proc_list); 172 get_type(&plist->res_prefix, &plist->res_type, 173 DEF_PROGRAM); 174 if (streq(plist->res_type, "opaque")) { 175 error("illegal result type"); 176 } 177 scan(TOK_IDENT, &tok); 178 plist->proc_name = tok.str; 179 scan(TOK_LPAREN, &tok); 180 /* get args - first one */ 181 num_args = 1; 182 isvoid = FALSE; 183 /* 184 * type of DEF_PROGRAM in the first 185 * get_prog_declaration and DEF_STURCT in the next 186 * allows void as argument if it is the only argument 187 */ 188 get_prog_declaration(&dec, DEF_PROGRAM, num_args); 189 if (streq(dec.type, "void")) 190 isvoid = TRUE; 191 decls = ALLOC(decl_list); 192 plist->args.decls = decls; 193 decls->decl = dec; 194 tailp = &decls->next; 195 /* get args */ 196 while (peekscan(TOK_COMMA, &tok)) { 197 num_args++; 198 get_prog_declaration(&dec, DEF_STRUCT, 199 num_args); 200 decls = ALLOC(decl_list); 201 decls->decl = dec; 202 *tailp = decls; 203 if (streq(dec.type, "void")) 204 isvoid = TRUE; 205 tailp = &decls->next; 206 } 207 /* multiple arguments are only allowed in newstyle */ 208 if (!newstyle && num_args > 1) { 209 error("only one argument is allowed"); 210 } 211 if (isvoid && num_args > 1) { 212 error("illegal use of void in program definition"); 213 } 214 *tailp = NULL; 215 scan(TOK_RPAREN, &tok); 216 scan(TOK_EQUAL, &tok); 217 scan_num(&tok); 218 scan(TOK_SEMICOLON, &tok); 219 plist->proc_num = tok.str; 220 plist->arg_num = num_args; 221 *ptailp = plist; 222 ptailp = &plist->next; 223 peek(&tok); 224 } while (tok.kind != TOK_RBRACE); 225 *ptailp = NULL; 226 *vtailp = vlist; 227 vtailp = &vlist->next; 228 scan(TOK_RBRACE, &tok); 229 scan(TOK_EQUAL, &tok); 230 scan_num(&tok); 231 vlist->vers_num = tok.str; 232 /* make the argument structure name for each arg */ 233 for (plist = vlist->procs; plist != NULL; 234 plist = plist->next) { 235 plist->args.argname = make_argname(plist->proc_name, 236 vlist->vers_num); 237 /* free the memory ?? */ 238 } 239 scan(TOK_SEMICOLON, &tok); 240 scan2(TOK_VERSION, TOK_RBRACE, &tok); 241 } while (tok.kind == TOK_VERSION); 242 scan(TOK_EQUAL, &tok); 243 scan_num(&tok); 244 defp->def.pr.prog_num = tok.str; 245 *vtailp = NULL; 246 } 247 248 249 static void 250 def_enum(defp) 251 definition *defp; 252 { 253 token tok; 254 enumval_list *elist; 255 enumval_list **tailp; 256 257 defp->def_kind = DEF_ENUM; 258 scan(TOK_IDENT, &tok); 259 defp->def_name = tok.str; 260 scan(TOK_LBRACE, &tok); 261 tailp = &defp->def.en.vals; 262 do { 263 scan(TOK_IDENT, &tok); 264 elist = ALLOC(enumval_list); 265 elist->name = tok.str; 266 elist->assignment = NULL; 267 scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); 268 if (tok.kind == TOK_EQUAL) { 269 scan_num(&tok); 270 elist->assignment = tok.str; 271 scan2(TOK_COMMA, TOK_RBRACE, &tok); 272 } 273 *tailp = elist; 274 tailp = &elist->next; 275 } while (tok.kind != TOK_RBRACE); 276 *tailp = NULL; 277 } 278 279 static void 280 def_const(defp) 281 definition *defp; 282 { 283 token tok; 284 285 defp->def_kind = DEF_CONST; 286 scan(TOK_IDENT, &tok); 287 defp->def_name = tok.str; 288 scan(TOK_EQUAL, &tok); 289 scan2(TOK_IDENT, TOK_STRCONST, &tok); 290 defp->def.co = tok.str; 291 } 292 293 static void 294 def_union(defp) 295 definition *defp; 296 { 297 token tok; 298 declaration dec; 299 case_list *cases; 300 case_list **tailp; 301 int flag; 302 303 defp->def_kind = DEF_UNION; 304 scan(TOK_IDENT, &tok); 305 defp->def_name = tok.str; 306 scan(TOK_SWITCH, &tok); 307 scan(TOK_LPAREN, &tok); 308 get_declaration(&dec, DEF_UNION); 309 defp->def.un.enum_decl = dec; 310 tailp = &defp->def.un.cases; 311 scan(TOK_RPAREN, &tok); 312 scan(TOK_LBRACE, &tok); 313 scan(TOK_CASE, &tok); 314 while (tok.kind == TOK_CASE) { 315 scan2(TOK_IDENT, TOK_CHARCONST, &tok); 316 cases = ALLOC(case_list); 317 cases->case_name = tok.str; 318 scan(TOK_COLON, &tok); 319 /* now peek at next token */ 320 flag = 0; 321 if (peekscan(TOK_CASE, &tok)){ 322 do { 323 scan2(TOK_IDENT, TOK_CHARCONST, &tok); 324 cases->contflag = 1; 325 /* continued case statement */ 326 *tailp = cases; 327 tailp = &cases->next; 328 cases = ALLOC(case_list); 329 cases->case_name = tok.str; 330 scan(TOK_COLON, &tok); 331 } while (peekscan(TOK_CASE, &tok)); 332 } 333 else 334 if (flag) 335 { 336 337 *tailp = cases; 338 tailp = &cases->next; 339 cases = ALLOC(case_list); 340 }; 341 342 get_declaration(&dec, DEF_UNION); 343 cases->case_decl = dec; 344 cases->contflag = 0; /* no continued case statement */ 345 *tailp = cases; 346 tailp = &cases->next; 347 scan(TOK_SEMICOLON, &tok); 348 349 scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); 350 } 351 *tailp = NULL; 352 if (tok.kind == TOK_DEFAULT) { 353 scan(TOK_COLON, &tok); 354 get_declaration(&dec, DEF_UNION); 355 defp->def.un.default_decl = ALLOC(declaration); 356 *defp->def.un.default_decl = dec; 357 scan(TOK_SEMICOLON, &tok); 358 scan(TOK_RBRACE, &tok); 359 } else { 360 defp->def.un.default_decl = NULL; 361 } 362 } 363 364 static char* reserved_words[] = 365 { 366 "array", 367 "bytes", 368 "destroy", 369 "free", 370 "getpos", 371 "inline", 372 "pointer", 373 "reference", 374 "setpos", 375 "sizeof", 376 "union", 377 "vector", 378 NULL 379 }; 380 381 static char* reserved_types[] = 382 { 383 "opaque", 384 "string", 385 NULL 386 }; 387 388 /* 389 * check that the given name is not one that would eventually result in 390 * xdr routines that would conflict with internal XDR routines. 391 */ 392 static void 393 check_type_name(name, new_type) 394 int new_type; 395 char* name; 396 { 397 int i; 398 char tmp[100]; 399 400 for (i = 0; reserved_words[i] != NULL; i++) { 401 if (strcmp(name, reserved_words[i]) == 0) { 402 sprintf(tmp, 403 "illegal (reserved) name :\'%s\' in type definition", 404 name); 405 error(tmp); 406 } 407 } 408 if (new_type) { 409 for (i = 0; reserved_types[i] != NULL; i++) { 410 if (strcmp(name, reserved_types[i]) == 0) { 411 sprintf(tmp, 412 "illegal (reserved) name :\'%s\' in type definition", 413 name); 414 error(tmp); 415 } 416 } 417 } 418 } 419 420 421 422 static void 423 def_typedef(defp) 424 definition *defp; 425 { 426 declaration dec; 427 428 defp->def_kind = DEF_TYPEDEF; 429 get_declaration(&dec, DEF_TYPEDEF); 430 defp->def_name = dec.name; 431 check_type_name(dec.name, 1); 432 defp->def.ty.old_prefix = dec.prefix; 433 defp->def.ty.old_type = dec.type; 434 defp->def.ty.rel = dec.rel; 435 defp->def.ty.array_max = dec.array_max; 436 } 437 438 static void 439 get_declaration(dec, dkind) 440 declaration *dec; 441 defkind dkind; 442 { 443 token tok; 444 445 get_type(&dec->prefix, &dec->type, dkind); 446 dec->rel = REL_ALIAS; 447 if (streq(dec->type, "void")) { 448 return; 449 } 450 451 check_type_name(dec->type, 0); 452 scan2(TOK_STAR, TOK_IDENT, &tok); 453 if (tok.kind == TOK_STAR) { 454 dec->rel = REL_POINTER; 455 scan(TOK_IDENT, &tok); 456 } 457 dec->name = tok.str; 458 if (peekscan(TOK_LBRACKET, &tok)) { 459 if (dec->rel == REL_POINTER) { 460 error("no array-of-pointer declarations -- use typedef"); 461 } 462 dec->rel = REL_VECTOR; 463 scan_num(&tok); 464 dec->array_max = tok.str; 465 scan(TOK_RBRACKET, &tok); 466 } else if (peekscan(TOK_LANGLE, &tok)) { 467 if (dec->rel == REL_POINTER) { 468 error("no array-of-pointer declarations -- use typedef"); 469 } 470 dec->rel = REL_ARRAY; 471 if (peekscan(TOK_RANGLE, &tok)) { 472 dec->array_max = "~0"; /* unspecified size, use max */ 473 } else { 474 scan_num(&tok); 475 dec->array_max = tok.str; 476 scan(TOK_RANGLE, &tok); 477 } 478 } 479 if (streq(dec->type, "opaque")) { 480 if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { 481 error("array declaration expected"); 482 } 483 } else if (streq(dec->type, "string")) { 484 if (dec->rel != REL_ARRAY) { 485 error("variable-length array declaration expected"); 486 } 487 } 488 } 489 490 491 static void 492 get_prog_declaration(dec, dkind, num) 493 declaration *dec; 494 defkind dkind; 495 int num; /* arg number */ 496 { 497 token tok; 498 char name[10]; /* argument name */ 499 500 if (dkind == DEF_PROGRAM) { 501 peek(&tok); 502 if (tok.kind == TOK_RPAREN) { /* no arguments */ 503 dec->rel = REL_ALIAS; 504 dec->type = "void"; 505 dec->prefix = NULL; 506 dec->name = NULL; 507 return; 508 } 509 } 510 get_type(&dec->prefix, &dec->type, dkind); 511 dec->rel = REL_ALIAS; 512 if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */ 513 strcpy(name, tok.str); 514 else 515 sprintf(name, "%s%d", ARGNAME, num); 516 /* default name of argument */ 517 518 dec->name = (char *) strdup(name); 519 if (streq(dec->type, "void")) { 520 return; 521 } 522 523 if (streq(dec->type, "opaque")) { 524 error("opaque -- illegal argument type"); 525 } 526 if (peekscan(TOK_STAR, &tok)) { 527 if (streq(dec->type, "string")) { 528 error("pointer to string not allowed in program arguments\n"); 529 } 530 dec->rel = REL_POINTER; 531 if (peekscan(TOK_IDENT, &tok)) 532 /* optional name of argument */ 533 dec->name = strdup(tok.str); 534 } 535 if (peekscan(TOK_LANGLE, &tok)) { 536 if (!streq(dec->type, "string")) { 537 error("arrays cannot be declared as arguments to procedures -- use typedef"); 538 } 539 dec->rel = REL_ARRAY; 540 if (peekscan(TOK_RANGLE, &tok)) { 541 dec->array_max = "~0"; 542 /* unspecified size, use max */ 543 } else { 544 scan_num(&tok); 545 dec->array_max = tok.str; 546 scan(TOK_RANGLE, &tok); 547 } 548 } 549 if (streq(dec->type, "string")) { 550 if (dec->rel != REL_ARRAY) { 551 /* 552 * .x specifies just string as 553 * type of argument 554 * - make it string<> 555 */ 556 dec->rel = REL_ARRAY; 557 dec->array_max = "~0"; /* unspecified size, use max */ 558 } 559 } 560 } 561 562 563 564 static void 565 get_type(prefixp, typep, dkind) 566 char **prefixp; 567 char **typep; 568 defkind dkind; 569 { 570 token tok; 571 572 *prefixp = NULL; 573 get_token(&tok); 574 switch (tok.kind) { 575 case TOK_IDENT: 576 *typep = tok.str; 577 break; 578 case TOK_STRUCT: 579 case TOK_ENUM: 580 case TOK_UNION: 581 *prefixp = tok.str; 582 scan(TOK_IDENT, &tok); 583 *typep = tok.str; 584 break; 585 case TOK_UNSIGNED: 586 unsigned_dec(typep); 587 break; 588 case TOK_SHORT: 589 *typep = "short"; 590 (void) peekscan(TOK_INT, &tok); 591 break; 592 case TOK_LONG: 593 *typep = "long"; 594 (void) peekscan(TOK_INT, &tok); 595 break; 596 case TOK_HYPER: 597 #ifdef __FreeBSD__ 598 *typep = "int64_t"; 599 #else 600 *typep = "longlong_t"; 601 #endif 602 (void) peekscan(TOK_INT, &tok); 603 break; 604 605 case TOK_VOID: 606 if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { 607 error("voids allowed only inside union and program definitions with one argument"); 608 } 609 *typep = tok.str; 610 break; 611 case TOK_STRING: 612 case TOK_OPAQUE: 613 case TOK_CHAR: 614 case TOK_INT: 615 case TOK_FLOAT: 616 case TOK_DOUBLE: 617 case TOK_BOOL: 618 case TOK_QUAD: 619 *typep = tok.str; 620 break; 621 default: 622 error("expected type specifier"); 623 } 624 } 625 626 static void 627 unsigned_dec(typep) 628 char **typep; 629 { 630 token tok; 631 632 peek(&tok); 633 switch (tok.kind) { 634 case TOK_CHAR: 635 get_token(&tok); 636 *typep = "u_char"; 637 break; 638 case TOK_SHORT: 639 get_token(&tok); 640 *typep = "u_short"; 641 (void) peekscan(TOK_INT, &tok); 642 break; 643 case TOK_LONG: 644 get_token(&tok); 645 *typep = "u_long"; 646 (void) peekscan(TOK_INT, &tok); 647 break; 648 case TOK_HYPER: 649 get_token(&tok); 650 #ifdef __FreeBSD__ 651 *typep = "u_int64_t"; 652 #else 653 *typep = "longlong_t"; 654 #endif 655 656 (void) peekscan(TOK_INT, &tok); 657 break; 658 case TOK_INT: 659 get_token(&tok); 660 *typep = "u_int"; 661 break; 662 default: 663 *typep = "u_int"; 664 break; 665 } 666 } 667