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