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