Annotation of src/usr.bin/rpcgen/rpc_parse.c, Revision 1.18
1.18 ! millert 1: /* $OpenBSD: rpc_parse.c,v 1.17 2009/10/27 23:59:42 deraadt Exp $ */
1.1 deraadt 2: /* $NetBSD: rpc_parse.c,v 1.5 1995/08/29 23:05:55 cgd Exp $ */
1.18 ! millert 3:
1.1 deraadt 4: /*
1.18 ! millert 5: * Copyright (c) 2010, Oracle America, Inc.
1.1 deraadt 6: *
1.18 ! millert 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions are
! 9: * met:
1.1 deraadt 10: *
1.18 ! millert 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.
1.1 deraadt 20: *
1.18 ! millert 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.
1.1 deraadt 33: */
34:
35: /*
1.8 deraadt 36: * rpc_parse.c, Parser for the RPC protocol compiler
1.1 deraadt 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:
1.11 deraadt 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 **);
1.1 deraadt 59:
60: /*
61: * return the next definition you see
62: */
63: definition *
1.13 deraadt 64: get_definition(void)
1.1 deraadt 65: {
66: definition *defp;
67: token tok;
68:
69: defp = ALLOC(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:
1.15 dhill 91: free(defp);
1.1 deraadt 92: return (NULL);
93: default:
94: error("definition keyword expected");
95: }
96: scan(TOK_SEMICOLON, &tok);
97: isdefined(defp);
98: return (defp);
99: }
100:
1.11 deraadt 101: static void
1.1 deraadt 102: isdefined(defp)
103: definition *defp;
104: {
105: STOREVAL(&defined, defp);
106: }
107:
1.11 deraadt 108: static void
1.1 deraadt 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 = ALLOC(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:
1.11 deraadt 136: static void
1.1 deraadt 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 = ALLOC(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 = ALLOC(proc_list);
1.8 deraadt 166: get_type(&plist->res_prefix, &plist->res_type,
1.11 deraadt 167: DEF_PROGRAM);
1.1 deraadt 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;
1.8 deraadt 177: /* type of DEF_PROGRAM in the first
1.1 deraadt 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"))
1.11 deraadt 183: isvoid = TRUE;
1.1 deraadt 184: decls = ALLOC(decl_list);
185: plist->args.decls = decls;
186: decls->decl = dec;
187: tailp = &decls->next;
188: /* get args */
1.8 deraadt 189: while (peekscan(TOK_COMMA, &tok)) {
1.11 deraadt 190: num_args++;
191: get_prog_declaration(&dec, DEF_STRUCT,
192: num_args);
193: decls = ALLOC(decl_list);
194: decls->decl = dec;
195: *tailp = decls;
196: if (streq(dec.type, "void"))
197: isvoid = TRUE;
198: tailp = &decls->next;
1.1 deraadt 199: }
200: /* multiple arguments are only allowed in newstyle */
1.11 deraadt 201: if (!newstyle && num_args > 1) {
202: error("only one argument is allowed");
1.1 deraadt 203: }
1.8 deraadt 204: if (isvoid && num_args > 1) {
1.11 deraadt 205: error("illegal use of void in program definition");
1.1 deraadt 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*/
1.11 deraadt 226: for (plist = vlist->procs; plist != NULL;
1.1 deraadt 227: plist = plist->next) {
228: plist->args.argname = make_argname(plist->proc_name,
1.11 deraadt 229: vlist->vers_num);
1.1 deraadt 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:
1.11 deraadt 242: static void
1.1 deraadt 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 = ALLOC(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:
1.11 deraadt 272: static void
1.1 deraadt 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:
1.11 deraadt 286: static void
1.1 deraadt 287: def_union(defp)
288: definition *defp;
289: {
1.11 deraadt 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 = ALLOC(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 = ALLOC(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 = ALLOC(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 = ALLOC(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: }
1.1 deraadt 350: }
351:
1.8 deraadt 352: static char *reserved_words[] = {
1.1 deraadt 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:
1.8 deraadt 368: static char *reserved_types[] = {
1.1 deraadt 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. */
1.11 deraadt 376: static void
1.14 deraadt 377: check_type_name(char *name, int new_type)
1.11 deraadt 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: }
1.1 deraadt 399: }
400:
1.11 deraadt 401: static void
1.1 deraadt 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;
1.11 deraadt 410: check_type_name(dec.name, 1);
1.1 deraadt 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:
1.11 deraadt 417: static void
1.1 deraadt 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:
1.11 deraadt 430: check_type_name(dec->type, 0);
1.1 deraadt 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:
1.11 deraadt 470: static void
1.1 deraadt 471: get_prog_declaration(dec, dkind, num)
472: declaration *dec;
473: defkind dkind;
1.11 deraadt 474: int num; /* arg number */
1.1 deraadt 475: {
476: token tok;
477:
1.8 deraadt 478: if (dkind == DEF_PROGRAM) {
1.11 deraadt 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: }
1.1 deraadt 487: }
488: get_type(&dec->prefix, &dec->type, dkind);
489: dec->rel = REL_ALIAS;
1.12 pvalchev 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 {
1.11 deraadt 495: /* default name of argument */
1.12 pvalchev 496: if (asprintf(&dec->name, "%s%d", ARGNAME, num) == -1)
497: error("out of memory");
1.11 deraadt 498: }
1.8 deraadt 499:
1.11 deraadt 500: if (streq(dec->type, "void"))
1.1 deraadt 501: return;
502:
1.11 deraadt 503: if (streq(dec->type, "opaque"))
1.1 deraadt 504: error("opaque -- illegal argument type");
1.11 deraadt 505:
1.8 deraadt 506: if (peekscan(TOK_STAR, &tok)) {
1.11 deraadt 507: if (streq(dec->type, "string"))
508: error("pointer to string not allowed in program arguments\n");
509:
1.1 deraadt 510: dec->rel = REL_POINTER;
1.11 deraadt 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");
1.1 deraadt 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")) {
1.11 deraadt 531: /* .x specifies just string as
532: * type of argument
533: * - make it string<>
534: */
535: if (dec->rel != REL_ARRAY) {
1.1 deraadt 536: dec->rel = REL_ARRAY;
537: dec->array_max = "~0";/* unspecified size, use max */
538: }
539: }
540: }
541:
1.11 deraadt 542: static void
1.1 deraadt 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_VOID:
575: if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
576: error("voids allowed only inside union and program definitions with one argument");
577: }
578: *typep = tok.str;
579: break;
580: case TOK_STRING:
581: case TOK_OPAQUE:
582: case TOK_CHAR:
583: case TOK_INT:
584: case TOK_FLOAT:
585: case TOK_DOUBLE:
586: case TOK_BOOL:
587: *typep = tok.str;
588: break;
589: default:
590: error("expected type specifier");
591: }
592: }
593:
1.11 deraadt 594: static void
1.1 deraadt 595: unsigned_dec(typep)
596: char **typep;
597: {
598: token tok;
599:
600: peek(&tok);
601: switch (tok.kind) {
602: case TOK_CHAR:
603: get_token(&tok);
604: *typep = "u_char";
605: break;
606: case TOK_SHORT:
607: get_token(&tok);
608: *typep = "u_short";
609: (void) peekscan(TOK_INT, &tok);
610: break;
611: case TOK_LONG:
612: get_token(&tok);
613: *typep = "u_long";
614: (void) peekscan(TOK_INT, &tok);
615: break;
616: case TOK_INT:
617: get_token(&tok);
618: *typep = "u_int";
619: break;
620: default:
621: *typep = "u_int";
622: break;
623: }
624: }