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