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