xref: /freebsd/usr.bin/rpcgen/rpc_parse.c (revision e390e3af7c6aa20ef57a33a4895039ee4787509c)
14e115012SGarrett Wollman /*
24e115012SGarrett Wollman  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
34e115012SGarrett Wollman  * unrestricted use provided that this legend is included on all tape
44e115012SGarrett Wollman  * media and as a part of the software program in whole or part.  Users
54e115012SGarrett Wollman  * may copy or modify Sun RPC without charge, but are not authorized
64e115012SGarrett Wollman  * to license or distribute it to anyone else except as part of a product or
74e115012SGarrett Wollman  * program developed by the user.
84e115012SGarrett Wollman  *
94e115012SGarrett Wollman  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
104e115012SGarrett Wollman  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
114e115012SGarrett Wollman  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
124e115012SGarrett Wollman  *
134e115012SGarrett Wollman  * Sun RPC is provided with no support and without any obligation on the
144e115012SGarrett Wollman  * part of Sun Microsystems, Inc. to assist in its use, correction,
154e115012SGarrett Wollman  * modification or enhancement.
164e115012SGarrett Wollman  *
174e115012SGarrett Wollman  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
184e115012SGarrett Wollman  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
194e115012SGarrett Wollman  * OR ANY PART THEREOF.
204e115012SGarrett Wollman  *
214e115012SGarrett Wollman  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
224e115012SGarrett Wollman  * or profits or other special, indirect and consequential damages, even if
234e115012SGarrett Wollman  * Sun has been advised of the possibility of such damages.
244e115012SGarrett Wollman  *
254e115012SGarrett Wollman  * Sun Microsystems, Inc.
264e115012SGarrett Wollman  * 2550 Garcia Avenue
274e115012SGarrett Wollman  * Mountain View, California  94043
284e115012SGarrett Wollman  */
29ff49530fSBill Paul 
3040ad8885SAlfred Perlstein #if 0
3175863a6dSPhilippe Charnier #ifndef lint
3263f17371SStefan Farfeleder #ident	"@(#)rpc_parse.c	1.12	93/07/05 SMI"
33ff49530fSBill Paul static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
344e115012SGarrett Wollman #endif
3540ad8885SAlfred Perlstein #endif
364e115012SGarrett Wollman 
3775863a6dSPhilippe Charnier #include <sys/cdefs.h>
3875863a6dSPhilippe Charnier __FBSDID("$FreeBSD$");
3975863a6dSPhilippe Charnier 
404e115012SGarrett Wollman /*
414e115012SGarrett Wollman  * rpc_parse.c, Parser for the RPC protocol compiler
424e115012SGarrett Wollman  * Copyright (C) 1987 Sun Microsystems, Inc.
434e115012SGarrett Wollman  */
444e115012SGarrett Wollman #include <stdio.h>
45ff49530fSBill Paul #include <string.h>
46ff49530fSBill Paul #include "rpc/types.h"
474e115012SGarrett Wollman #include "rpc_parse.h"
48e390e3afSDavid Malone #include "rpc_scan.h"
49ff49530fSBill Paul #include "rpc_util.h"
504e115012SGarrett Wollman 
51ff49530fSBill Paul #define ARGNAME "arg"
52ff49530fSBill Paul 
53d3cb5dedSWarner Losh static void isdefined( definition * );
54d3cb5dedSWarner Losh static void def_struct( definition * );
55d3cb5dedSWarner Losh static void def_program( definition * );
56d3cb5dedSWarner Losh static void def_enum( definition * );
57d3cb5dedSWarner Losh static void def_const( definition * );
58d3cb5dedSWarner Losh static void def_union( definition * );
59d3cb5dedSWarner Losh static void def_typedef( definition * );
60d3cb5dedSWarner Losh static void get_declaration( declaration *, defkind );
61d3cb5dedSWarner Losh static void get_prog_declaration( declaration *, defkind, int );
62e390e3afSDavid Malone static void get_type(const char **, const char **, defkind);
63e390e3afSDavid Malone static void unsigned_dec(const char ** );
64ff49530fSBill Paul 
654e115012SGarrett Wollman /*
664e115012SGarrett Wollman  * return the next definition you see
674e115012SGarrett Wollman  */
684e115012SGarrett Wollman definition *
69e390e3afSDavid Malone get_definition(void)
704e115012SGarrett Wollman {
714e115012SGarrett Wollman 	definition *defp;
724e115012SGarrett Wollman 	token tok;
734e115012SGarrett Wollman 
7475863a6dSPhilippe Charnier 	defp = XALLOC(definition);
754e115012SGarrett Wollman 	get_token(&tok);
764e115012SGarrett Wollman 	switch (tok.kind) {
774e115012SGarrett Wollman 	case TOK_STRUCT:
784e115012SGarrett Wollman 		def_struct(defp);
794e115012SGarrett Wollman 		break;
804e115012SGarrett Wollman 	case TOK_UNION:
814e115012SGarrett Wollman 		def_union(defp);
824e115012SGarrett Wollman 		break;
834e115012SGarrett Wollman 	case TOK_TYPEDEF:
844e115012SGarrett Wollman 		def_typedef(defp);
854e115012SGarrett Wollman 		break;
864e115012SGarrett Wollman 	case TOK_ENUM:
874e115012SGarrett Wollman 		def_enum(defp);
884e115012SGarrett Wollman 		break;
894e115012SGarrett Wollman 	case TOK_PROGRAM:
904e115012SGarrett Wollman 		def_program(defp);
914e115012SGarrett Wollman 		break;
924e115012SGarrett Wollman 	case TOK_CONST:
934e115012SGarrett Wollman 		def_const(defp);
944e115012SGarrett Wollman 		break;
954e115012SGarrett Wollman 	case TOK_EOF:
964e115012SGarrett Wollman 		return (NULL);
974e115012SGarrett Wollman 	default:
984e115012SGarrett Wollman 		error("definition keyword expected");
994e115012SGarrett Wollman 	}
1004e115012SGarrett Wollman 	scan(TOK_SEMICOLON, &tok);
1014e115012SGarrett Wollman 	isdefined(defp);
1024e115012SGarrett Wollman 	return (defp);
1034e115012SGarrett Wollman }
1044e115012SGarrett Wollman 
105526195adSJordan K. Hubbard static void
106e390e3afSDavid Malone isdefined(definition *defp)
1074e115012SGarrett Wollman {
1084e115012SGarrett Wollman 	STOREVAL(&defined, defp);
1094e115012SGarrett Wollman }
1104e115012SGarrett Wollman 
111526195adSJordan K. Hubbard static void
112e390e3afSDavid Malone def_struct(definition *defp)
1134e115012SGarrett Wollman {
1144e115012SGarrett Wollman 	token tok;
1154e115012SGarrett Wollman 	declaration dec;
1164e115012SGarrett Wollman 	decl_list *decls;
1174e115012SGarrett Wollman 	decl_list **tailp;
1184e115012SGarrett Wollman 
1194e115012SGarrett Wollman 	defp->def_kind = DEF_STRUCT;
1204e115012SGarrett Wollman 
1214e115012SGarrett Wollman 	scan(TOK_IDENT, &tok);
1224e115012SGarrett Wollman 	defp->def_name = tok.str;
1234e115012SGarrett Wollman 	scan(TOK_LBRACE, &tok);
1244e115012SGarrett Wollman 	tailp = &defp->def.st.decls;
1254e115012SGarrett Wollman 	do {
1264e115012SGarrett Wollman 		get_declaration(&dec, DEF_STRUCT);
12775863a6dSPhilippe Charnier 		decls = XALLOC(decl_list);
1284e115012SGarrett Wollman 		decls->decl = dec;
1294e115012SGarrett Wollman 		*tailp = decls;
1304e115012SGarrett Wollman 		tailp = &decls->next;
1314e115012SGarrett Wollman 		scan(TOK_SEMICOLON, &tok);
1324e115012SGarrett Wollman 		peek(&tok);
1334e115012SGarrett Wollman 	} while (tok.kind != TOK_RBRACE);
1344e115012SGarrett Wollman 	get_token(&tok);
1354e115012SGarrett Wollman 	*tailp = NULL;
1364e115012SGarrett Wollman }
1374e115012SGarrett Wollman 
138526195adSJordan K. Hubbard static void
139e390e3afSDavid Malone def_program(definition *defp)
1404e115012SGarrett Wollman {
1414e115012SGarrett Wollman 	token tok;
142ff49530fSBill Paul 	declaration dec;
143ff49530fSBill Paul 	decl_list *decls;
144ff49530fSBill Paul 	decl_list **tailp;
1454e115012SGarrett Wollman 	version_list *vlist;
1464e115012SGarrett Wollman 	version_list **vtailp;
1474e115012SGarrett Wollman 	proc_list *plist;
1484e115012SGarrett Wollman 	proc_list **ptailp;
149ff49530fSBill Paul 	int num_args;
150ff49530fSBill Paul 	bool_t isvoid = FALSE;	/* whether first argument is void */
1514e115012SGarrett Wollman 	defp->def_kind = DEF_PROGRAM;
1524e115012SGarrett Wollman 	scan(TOK_IDENT, &tok);
1534e115012SGarrett Wollman 	defp->def_name = tok.str;
1544e115012SGarrett Wollman 	scan(TOK_LBRACE, &tok);
1554e115012SGarrett Wollman 	vtailp = &defp->def.pr.versions;
156ff49530fSBill Paul 	tailp = &defp->def.st.decls;
1574e115012SGarrett Wollman 	scan(TOK_VERSION, &tok);
1584e115012SGarrett Wollman 	do {
1594e115012SGarrett Wollman 		scan(TOK_IDENT, &tok);
16075863a6dSPhilippe Charnier 		vlist = XALLOC(version_list);
1614e115012SGarrett Wollman 		vlist->vers_name = tok.str;
1624e115012SGarrett Wollman 		scan(TOK_LBRACE, &tok);
1634e115012SGarrett Wollman 		ptailp = &vlist->procs;
1644e115012SGarrett Wollman 		do {
165ff49530fSBill Paul 			/* get result type */
16675863a6dSPhilippe Charnier 			plist = XALLOC(proc_list);
167ff49530fSBill Paul 			get_type(&plist->res_prefix, &plist->res_type,
168ff49530fSBill Paul 				 DEF_PROGRAM);
1694e115012SGarrett Wollman 			if (streq(plist->res_type, "opaque")) {
1704e115012SGarrett Wollman 				error("illegal result type");
1714e115012SGarrett Wollman 			}
1724e115012SGarrett Wollman 			scan(TOK_IDENT, &tok);
1734e115012SGarrett Wollman 			plist->proc_name = tok.str;
1744e115012SGarrett Wollman 			scan(TOK_LPAREN, &tok);
175ff49530fSBill Paul 			/* get args - first one */
176ff49530fSBill Paul 			num_args = 1;
177ff49530fSBill Paul 			isvoid = FALSE;
178ff49530fSBill Paul 			/*
179ff49530fSBill Paul 			 * type of DEF_PROGRAM in the first
180ff49530fSBill Paul 			 * get_prog_declaration and DEF_STURCT in the next
181ff49530fSBill Paul 			 * allows void as argument if it is the only argument
182ff49530fSBill Paul 			 */
183ff49530fSBill Paul 			get_prog_declaration(&dec, DEF_PROGRAM, num_args);
184ff49530fSBill Paul 			if (streq(dec.type, "void"))
185ff49530fSBill Paul 				isvoid = TRUE;
18675863a6dSPhilippe Charnier 			decls = XALLOC(decl_list);
187ff49530fSBill Paul 			plist->args.decls = decls;
188ff49530fSBill Paul 			decls->decl = dec;
189ff49530fSBill Paul 			tailp = &decls->next;
190ff49530fSBill Paul 			/* get args */
191ff49530fSBill Paul 			while (peekscan(TOK_COMMA, &tok)) {
192ff49530fSBill Paul 				num_args++;
193ff49530fSBill Paul 				get_prog_declaration(&dec, DEF_STRUCT,
194ff49530fSBill Paul 						     num_args);
19575863a6dSPhilippe Charnier 				decls = XALLOC(decl_list);
196ff49530fSBill Paul 				decls->decl = dec;
197ff49530fSBill Paul 				*tailp = decls;
198ff49530fSBill Paul 				if (streq(dec.type, "void"))
199ff49530fSBill Paul 					isvoid = TRUE;
200ff49530fSBill Paul 				tailp = &decls->next;
2014e115012SGarrett Wollman 			}
202ff49530fSBill Paul 			/* multiple arguments are only allowed in newstyle */
203ff49530fSBill Paul 			if (!newstyle && num_args > 1) {
204ff49530fSBill Paul 				error("only one argument is allowed");
205ff49530fSBill Paul 			}
206ff49530fSBill Paul 			if (isvoid && num_args > 1) {
207ff49530fSBill Paul 				error("illegal use of void in program definition");
208ff49530fSBill Paul 			}
209ff49530fSBill Paul 			*tailp = NULL;
2104e115012SGarrett Wollman 			scan(TOK_RPAREN, &tok);
2114e115012SGarrett Wollman 			scan(TOK_EQUAL, &tok);
2124e115012SGarrett Wollman 			scan_num(&tok);
2134e115012SGarrett Wollman 			scan(TOK_SEMICOLON, &tok);
2144e115012SGarrett Wollman 			plist->proc_num = tok.str;
215ff49530fSBill Paul 			plist->arg_num = num_args;
2164e115012SGarrett Wollman 			*ptailp = plist;
2174e115012SGarrett Wollman 			ptailp = &plist->next;
2184e115012SGarrett Wollman 			peek(&tok);
2194e115012SGarrett Wollman 		} while (tok.kind != TOK_RBRACE);
2200b455160SAndrey A. Chernov 		*ptailp = NULL;
2214e115012SGarrett Wollman 		*vtailp = vlist;
2224e115012SGarrett Wollman 		vtailp = &vlist->next;
2234e115012SGarrett Wollman 		scan(TOK_RBRACE, &tok);
2244e115012SGarrett Wollman 		scan(TOK_EQUAL, &tok);
2254e115012SGarrett Wollman 		scan_num(&tok);
2264e115012SGarrett Wollman 		vlist->vers_num = tok.str;
227ff49530fSBill Paul 		/* make the argument structure name for each arg */
228ff49530fSBill Paul 		for (plist = vlist->procs; plist != NULL;
229ff49530fSBill Paul 		     plist = plist->next) {
230ff49530fSBill Paul 			plist->args.argname = make_argname(plist->proc_name,
231ff49530fSBill Paul 							   vlist->vers_num);
232ff49530fSBill Paul 			/* free the memory ?? */
233ff49530fSBill Paul 		}
2344e115012SGarrett Wollman 		scan(TOK_SEMICOLON, &tok);
2354e115012SGarrett Wollman 		scan2(TOK_VERSION, TOK_RBRACE, &tok);
2364e115012SGarrett Wollman 	} while (tok.kind == TOK_VERSION);
2374e115012SGarrett Wollman 	scan(TOK_EQUAL, &tok);
2384e115012SGarrett Wollman 	scan_num(&tok);
2394e115012SGarrett Wollman 	defp->def.pr.prog_num = tok.str;
2404e115012SGarrett Wollman 	*vtailp = NULL;
2414e115012SGarrett Wollman }
2424e115012SGarrett Wollman 
243ff49530fSBill Paul 
244526195adSJordan K. Hubbard static void
245e390e3afSDavid Malone def_enum(definition *defp)
2464e115012SGarrett Wollman {
2474e115012SGarrett Wollman 	token tok;
2484e115012SGarrett Wollman 	enumval_list *elist;
2494e115012SGarrett Wollman 	enumval_list **tailp;
2504e115012SGarrett Wollman 
2514e115012SGarrett Wollman 	defp->def_kind = DEF_ENUM;
2524e115012SGarrett Wollman 	scan(TOK_IDENT, &tok);
2534e115012SGarrett Wollman 	defp->def_name = tok.str;
2544e115012SGarrett Wollman 	scan(TOK_LBRACE, &tok);
2554e115012SGarrett Wollman 	tailp = &defp->def.en.vals;
2564e115012SGarrett Wollman 	do {
2574e115012SGarrett Wollman 		scan(TOK_IDENT, &tok);
25875863a6dSPhilippe Charnier 		elist = XALLOC(enumval_list);
2594e115012SGarrett Wollman 		elist->name = tok.str;
2604e115012SGarrett Wollman 		elist->assignment = NULL;
2614e115012SGarrett Wollman 		scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
2624e115012SGarrett Wollman 		if (tok.kind == TOK_EQUAL) {
2634e115012SGarrett Wollman 			scan_num(&tok);
2644e115012SGarrett Wollman 			elist->assignment = tok.str;
2654e115012SGarrett Wollman 			scan2(TOK_COMMA, TOK_RBRACE, &tok);
2664e115012SGarrett Wollman 		}
2674e115012SGarrett Wollman 		*tailp = elist;
2684e115012SGarrett Wollman 		tailp = &elist->next;
2694e115012SGarrett Wollman 	} while (tok.kind != TOK_RBRACE);
2704e115012SGarrett Wollman 	*tailp = NULL;
2714e115012SGarrett Wollman }
2724e115012SGarrett Wollman 
273526195adSJordan K. Hubbard static void
274e390e3afSDavid Malone def_const(definition *defp)
2754e115012SGarrett Wollman {
2764e115012SGarrett Wollman 	token tok;
2774e115012SGarrett Wollman 
2784e115012SGarrett Wollman 	defp->def_kind = DEF_CONST;
2794e115012SGarrett Wollman 	scan(TOK_IDENT, &tok);
2804e115012SGarrett Wollman 	defp->def_name = tok.str;
2814e115012SGarrett Wollman 	scan(TOK_EQUAL, &tok);
2824e115012SGarrett Wollman 	scan2(TOK_IDENT, TOK_STRCONST, &tok);
2834e115012SGarrett Wollman 	defp->def.co = tok.str;
2844e115012SGarrett Wollman }
2854e115012SGarrett Wollman 
286526195adSJordan K. Hubbard static void
287e390e3afSDavid Malone def_union(definition *defp)
2884e115012SGarrett Wollman {
2894e115012SGarrett Wollman 	token tok;
2904e115012SGarrett Wollman 	declaration dec;
291526195adSJordan K. Hubbard 	case_list *cases;
2924e115012SGarrett Wollman 	case_list **tailp;
293ff49530fSBill Paul 	int flag;
2944e115012SGarrett Wollman 
2954e115012SGarrett Wollman 	defp->def_kind = DEF_UNION;
2964e115012SGarrett Wollman 	scan(TOK_IDENT, &tok);
2974e115012SGarrett Wollman 	defp->def_name = tok.str;
2984e115012SGarrett Wollman 	scan(TOK_SWITCH, &tok);
2994e115012SGarrett Wollman 	scan(TOK_LPAREN, &tok);
3004e115012SGarrett Wollman 	get_declaration(&dec, DEF_UNION);
3014e115012SGarrett Wollman 	defp->def.un.enum_decl = dec;
3024e115012SGarrett Wollman 	tailp = &defp->def.un.cases;
3034e115012SGarrett Wollman 	scan(TOK_RPAREN, &tok);
3044e115012SGarrett Wollman 	scan(TOK_LBRACE, &tok);
3054e115012SGarrett Wollman 	scan(TOK_CASE, &tok);
3064e115012SGarrett Wollman 	while (tok.kind == TOK_CASE) {
307ff49530fSBill Paul 		scan2(TOK_IDENT, TOK_CHARCONST, &tok);
30875863a6dSPhilippe Charnier 		cases = XALLOC(case_list);
3094e115012SGarrett Wollman 		cases->case_name = tok.str;
3104e115012SGarrett Wollman 		scan(TOK_COLON, &tok);
311ff49530fSBill Paul 		/* now peek at next token */
312ff49530fSBill Paul 		flag = 0;
313ff49530fSBill Paul 		if (peekscan(TOK_CASE, &tok)){
314ff49530fSBill Paul 			do {
315ff49530fSBill Paul 				scan2(TOK_IDENT, TOK_CHARCONST, &tok);
316ff49530fSBill Paul 				cases->contflag = 1;
317ff49530fSBill Paul 				/* continued case statement */
318ff49530fSBill Paul 				*tailp = cases;
319ff49530fSBill Paul 				tailp = &cases->next;
32075863a6dSPhilippe Charnier 				cases = XALLOC(case_list);
321ff49530fSBill Paul 				cases->case_name = tok.str;
322ff49530fSBill Paul 				scan(TOK_COLON, &tok);
323ff49530fSBill Paul 			} while (peekscan(TOK_CASE, &tok));
324ff49530fSBill Paul 		}
325ff49530fSBill Paul 		else
326ff49530fSBill Paul 			if (flag)
327ff49530fSBill Paul 			{
328ff49530fSBill Paul 
329ff49530fSBill Paul 				*tailp = cases;
330ff49530fSBill Paul 				tailp = &cases->next;
33175863a6dSPhilippe Charnier 				cases = XALLOC(case_list);
332ff49530fSBill Paul 			};
333ff49530fSBill Paul 
3344e115012SGarrett Wollman 		get_declaration(&dec, DEF_UNION);
3354e115012SGarrett Wollman 		cases->case_decl = dec;
336ff49530fSBill Paul 		cases->contflag = 0; /* no continued case statement */
3374e115012SGarrett Wollman 		*tailp = cases;
3384e115012SGarrett Wollman 		tailp = &cases->next;
3394e115012SGarrett Wollman 		scan(TOK_SEMICOLON, &tok);
340ff49530fSBill Paul 
3414e115012SGarrett Wollman 		scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
3424e115012SGarrett Wollman 	}
3434e115012SGarrett Wollman 	*tailp = NULL;
3444e115012SGarrett Wollman 	if (tok.kind == TOK_DEFAULT) {
3454e115012SGarrett Wollman 		scan(TOK_COLON, &tok);
3464e115012SGarrett Wollman 		get_declaration(&dec, DEF_UNION);
34775863a6dSPhilippe Charnier 		defp->def.un.default_decl = XALLOC(declaration);
3484e115012SGarrett Wollman 		*defp->def.un.default_decl = dec;
3494e115012SGarrett Wollman 		scan(TOK_SEMICOLON, &tok);
3504e115012SGarrett Wollman 		scan(TOK_RBRACE, &tok);
3514e115012SGarrett Wollman 	} else {
3524e115012SGarrett Wollman 		defp->def.un.default_decl = NULL;
3534e115012SGarrett Wollman 	}
3544e115012SGarrett Wollman }
3554e115012SGarrett Wollman 
356e390e3afSDavid Malone static const char *reserved_words[] =
357ff49530fSBill Paul {
358ff49530fSBill Paul 	"array",
359ff49530fSBill Paul 	"bytes",
360ff49530fSBill Paul 	"destroy",
361ff49530fSBill Paul 	"free",
362ff49530fSBill Paul 	"getpos",
363ff49530fSBill Paul 	"inline",
364ff49530fSBill Paul 	"pointer",
365ff49530fSBill Paul 	"reference",
366ff49530fSBill Paul 	"setpos",
367ff49530fSBill Paul 	"sizeof",
368ff49530fSBill Paul 	"union",
369ff49530fSBill Paul 	"vector",
370ff49530fSBill Paul 	NULL
371ff49530fSBill Paul 	};
372ff49530fSBill Paul 
373e390e3afSDavid Malone static const char *reserved_types[] =
374ff49530fSBill Paul {
375ff49530fSBill Paul 	"opaque",
376ff49530fSBill Paul 	"string",
377ff49530fSBill Paul 	NULL
378ff49530fSBill Paul 	};
379ff49530fSBill Paul 
380ff49530fSBill Paul /*
381ff49530fSBill Paul  * check that the given name is not one that would eventually result in
382ff49530fSBill Paul  * xdr routines that would conflict with internal XDR routines.
383ff49530fSBill Paul  */
384526195adSJordan K. Hubbard static void
385e390e3afSDavid Malone check_type_name(const char *name, int new_type)
386ff49530fSBill Paul {
387ff49530fSBill Paul 	int i;
388ff49530fSBill Paul 	char tmp[100];
389ff49530fSBill Paul 
390ff49530fSBill Paul 	for (i = 0; reserved_words[i] != NULL; i++) {
391ff49530fSBill Paul 		if (strcmp(name, reserved_words[i]) == 0) {
392ff49530fSBill Paul 			sprintf(tmp,
393ff49530fSBill Paul 				"illegal (reserved) name :\'%s\' in type definition",
394ff49530fSBill Paul 				name);
395ff49530fSBill Paul 			error(tmp);
396ff49530fSBill Paul 		}
397ff49530fSBill Paul 	}
398ff49530fSBill Paul 	if (new_type) {
399ff49530fSBill Paul 		for (i = 0; reserved_types[i] != NULL; i++) {
400ff49530fSBill Paul 			if (strcmp(name, reserved_types[i]) == 0) {
401ff49530fSBill Paul 				sprintf(tmp,
402ff49530fSBill Paul 					"illegal (reserved) name :\'%s\' in type definition",
403ff49530fSBill Paul 					name);
404ff49530fSBill Paul 				error(tmp);
405ff49530fSBill Paul 			}
406ff49530fSBill Paul 		}
407ff49530fSBill Paul 	}
408ff49530fSBill Paul }
409ff49530fSBill Paul 
410ff49530fSBill Paul 
4114e115012SGarrett Wollman 
412526195adSJordan K. Hubbard static void
413e390e3afSDavid Malone def_typedef(definition *defp)
4144e115012SGarrett Wollman {
4154e115012SGarrett Wollman 	declaration dec;
4164e115012SGarrett Wollman 
4174e115012SGarrett Wollman 	defp->def_kind = DEF_TYPEDEF;
4184e115012SGarrett Wollman 	get_declaration(&dec, DEF_TYPEDEF);
4194e115012SGarrett Wollman 	defp->def_name = dec.name;
420ff49530fSBill Paul 	check_type_name(dec.name, 1);
4214e115012SGarrett Wollman 	defp->def.ty.old_prefix = dec.prefix;
4224e115012SGarrett Wollman 	defp->def.ty.old_type = dec.type;
4234e115012SGarrett Wollman 	defp->def.ty.rel = dec.rel;
4244e115012SGarrett Wollman 	defp->def.ty.array_max = dec.array_max;
4254e115012SGarrett Wollman }
4264e115012SGarrett Wollman 
427526195adSJordan K. Hubbard static void
428e390e3afSDavid Malone get_declaration(declaration *dec, defkind dkind)
4294e115012SGarrett Wollman {
4304e115012SGarrett Wollman 	token tok;
4314e115012SGarrett Wollman 
4324e115012SGarrett Wollman 	get_type(&dec->prefix, &dec->type, dkind);
4334e115012SGarrett Wollman 	dec->rel = REL_ALIAS;
4344e115012SGarrett Wollman 	if (streq(dec->type, "void")) {
4354e115012SGarrett Wollman 		return;
4364e115012SGarrett Wollman 	}
437ff49530fSBill Paul 
438ff49530fSBill Paul 	check_type_name(dec->type, 0);
4394e115012SGarrett Wollman 	scan2(TOK_STAR, TOK_IDENT, &tok);
4404e115012SGarrett Wollman 	if (tok.kind == TOK_STAR) {
4414e115012SGarrett Wollman 		dec->rel = REL_POINTER;
4424e115012SGarrett Wollman 		scan(TOK_IDENT, &tok);
4434e115012SGarrett Wollman 	}
4444e115012SGarrett Wollman 	dec->name = tok.str;
4454e115012SGarrett Wollman 	if (peekscan(TOK_LBRACKET, &tok)) {
4464e115012SGarrett Wollman 		if (dec->rel == REL_POINTER) {
4474e115012SGarrett Wollman 			error("no array-of-pointer declarations -- use typedef");
4484e115012SGarrett Wollman 		}
4494e115012SGarrett Wollman 		dec->rel = REL_VECTOR;
4504e115012SGarrett Wollman 		scan_num(&tok);
4514e115012SGarrett Wollman 		dec->array_max = tok.str;
4524e115012SGarrett Wollman 		scan(TOK_RBRACKET, &tok);
4534e115012SGarrett Wollman 	} else if (peekscan(TOK_LANGLE, &tok)) {
4544e115012SGarrett Wollman 		if (dec->rel == REL_POINTER) {
4554e115012SGarrett Wollman 			error("no array-of-pointer declarations -- use typedef");
4564e115012SGarrett Wollman 		}
4574e115012SGarrett Wollman 		dec->rel = REL_ARRAY;
4584e115012SGarrett Wollman 		if (peekscan(TOK_RANGLE, &tok)) {
4594e115012SGarrett Wollman 			dec->array_max = "~0";	/* unspecified size, use max */
4604e115012SGarrett Wollman 		} else {
4614e115012SGarrett Wollman 			scan_num(&tok);
4624e115012SGarrett Wollman 			dec->array_max = tok.str;
4634e115012SGarrett Wollman 			scan(TOK_RANGLE, &tok);
4644e115012SGarrett Wollman 		}
4654e115012SGarrett Wollman 	}
4664e115012SGarrett Wollman 	if (streq(dec->type, "opaque")) {
4674e115012SGarrett Wollman 		if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
4684e115012SGarrett Wollman 			error("array declaration expected");
4694e115012SGarrett Wollman 		}
4704e115012SGarrett Wollman 	} else if (streq(dec->type, "string")) {
4714e115012SGarrett Wollman 		if (dec->rel != REL_ARRAY) {
4724e115012SGarrett Wollman 			error("variable-length array declaration expected");
4734e115012SGarrett Wollman 		}
4744e115012SGarrett Wollman 	}
4754e115012SGarrett Wollman }
4764e115012SGarrett Wollman 
4774e115012SGarrett Wollman 
478526195adSJordan K. Hubbard static void
479e390e3afSDavid Malone get_prog_declaration(declaration *dec, defkind dkind, int num)
480ff49530fSBill Paul {
481ff49530fSBill Paul 	token tok;
482ff49530fSBill Paul 	char name[10];		/* argument name */
483ff49530fSBill Paul 
484ff49530fSBill Paul 	if (dkind == DEF_PROGRAM) {
485ff49530fSBill Paul 		peek(&tok);
486ff49530fSBill Paul 		if (tok.kind == TOK_RPAREN) { /* no arguments */
487ff49530fSBill Paul 			dec->rel = REL_ALIAS;
488ff49530fSBill Paul 			dec->type = "void";
489ff49530fSBill Paul 			dec->prefix = NULL;
490ff49530fSBill Paul 			dec->name = NULL;
491ff49530fSBill Paul 			return;
492ff49530fSBill Paul 		}
493ff49530fSBill Paul 	}
494ff49530fSBill Paul 	get_type(&dec->prefix, &dec->type, dkind);
495ff49530fSBill Paul 	dec->rel = REL_ALIAS;
496ff49530fSBill Paul 	if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
497ff49530fSBill Paul 		strcpy(name, tok.str);
498ff49530fSBill Paul 	else
499ff49530fSBill Paul 		sprintf(name, "%s%d", ARGNAME, num);
500ff49530fSBill Paul 	/* default name of argument */
501ff49530fSBill Paul 
50275863a6dSPhilippe Charnier 	dec->name = (char *) xstrdup(name);
503ff49530fSBill Paul 	if (streq(dec->type, "void")) {
504ff49530fSBill Paul 		return;
505ff49530fSBill Paul 	}
506ff49530fSBill Paul 
507ff49530fSBill Paul 	if (streq(dec->type, "opaque")) {
508ff49530fSBill Paul 		error("opaque -- illegal argument type");
509ff49530fSBill Paul 	}
510ff49530fSBill Paul 	if (peekscan(TOK_STAR, &tok)) {
511ff49530fSBill Paul 		if (streq(dec->type, "string")) {
51275863a6dSPhilippe Charnier 			error("pointer to string not allowed in program arguments");
513ff49530fSBill Paul 		}
514ff49530fSBill Paul 		dec->rel = REL_POINTER;
51575863a6dSPhilippe Charnier 		if (peekscan(TOK_IDENT, &tok)) {
516ff49530fSBill Paul 			/* optional name of argument */
51775863a6dSPhilippe Charnier 			dec->name = xstrdup(tok.str);
51875863a6dSPhilippe Charnier 		}
519ff49530fSBill Paul 	}
520ff49530fSBill Paul 	if (peekscan(TOK_LANGLE, &tok)) {
521ff49530fSBill Paul 		if (!streq(dec->type, "string")) {
522ff49530fSBill Paul 			error("arrays cannot be declared as arguments to procedures -- use typedef");
523ff49530fSBill Paul 		}
524ff49530fSBill Paul 		dec->rel = REL_ARRAY;
525ff49530fSBill Paul 		if (peekscan(TOK_RANGLE, &tok)) {
526ff49530fSBill Paul 			dec->array_max = "~0";
527ff49530fSBill Paul 			/* unspecified size, use max */
528ff49530fSBill Paul 		} else {
529ff49530fSBill Paul 			scan_num(&tok);
530ff49530fSBill Paul 			dec->array_max = tok.str;
531ff49530fSBill Paul 			scan(TOK_RANGLE, &tok);
532ff49530fSBill Paul 		}
533ff49530fSBill Paul 	}
534ff49530fSBill Paul 	if (streq(dec->type, "string")) {
535ff49530fSBill Paul 		if (dec->rel != REL_ARRAY) {
536ff49530fSBill Paul 			/*
537ff49530fSBill Paul 			 * .x specifies just string as
538ff49530fSBill Paul 			 * type of argument
539ff49530fSBill Paul 			 * - make it string<>
540ff49530fSBill Paul 			 */
541ff49530fSBill Paul 			dec->rel = REL_ARRAY;
542ff49530fSBill Paul 			dec->array_max = "~0"; /* unspecified size, use max */
543ff49530fSBill Paul 		}
544ff49530fSBill Paul 	}
545ff49530fSBill Paul }
546ff49530fSBill Paul 
547ff49530fSBill Paul 
548ff49530fSBill Paul 
549526195adSJordan K. Hubbard static void
550e390e3afSDavid Malone get_type(const char **prefixp, const char **typep, defkind dkind)
5514e115012SGarrett Wollman {
5524e115012SGarrett Wollman 	token tok;
5534e115012SGarrett Wollman 
5544e115012SGarrett Wollman 	*prefixp = NULL;
5554e115012SGarrett Wollman 	get_token(&tok);
5564e115012SGarrett Wollman 	switch (tok.kind) {
5574e115012SGarrett Wollman 	case TOK_IDENT:
5584e115012SGarrett Wollman 		*typep = tok.str;
5594e115012SGarrett Wollman 		break;
5604e115012SGarrett Wollman 	case TOK_STRUCT:
5614e115012SGarrett Wollman 	case TOK_ENUM:
5624e115012SGarrett Wollman 	case TOK_UNION:
5634e115012SGarrett Wollman 		*prefixp = tok.str;
5644e115012SGarrett Wollman 		scan(TOK_IDENT, &tok);
5654e115012SGarrett Wollman 		*typep = tok.str;
5664e115012SGarrett Wollman 		break;
5674e115012SGarrett Wollman 	case TOK_UNSIGNED:
5684e115012SGarrett Wollman 		unsigned_dec(typep);
5694e115012SGarrett Wollman 		break;
5704e115012SGarrett Wollman 	case TOK_SHORT:
5714e115012SGarrett Wollman 		*typep = "short";
5724e115012SGarrett Wollman 		(void) peekscan(TOK_INT, &tok);
5734e115012SGarrett Wollman 		break;
5744e115012SGarrett Wollman 	case TOK_LONG:
5754e115012SGarrett Wollman 		*typep = "long";
5764e115012SGarrett Wollman 		(void) peekscan(TOK_INT, &tok);
5774e115012SGarrett Wollman 		break;
578ff49530fSBill Paul 	case TOK_HYPER:
579c304ad8aSDavid E. O'Brien 		*typep = "int64_t";
580ff49530fSBill Paul 		(void) peekscan(TOK_INT, &tok);
581ff49530fSBill Paul 		break;
582ff49530fSBill Paul 
5834e115012SGarrett Wollman 	case TOK_VOID:
5844e115012SGarrett Wollman 		if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
585ff49530fSBill Paul 			error("voids allowed only inside union and program definitions with one argument");
5864e115012SGarrett Wollman 		}
5874e115012SGarrett Wollman 		*typep = tok.str;
5884e115012SGarrett Wollman 		break;
5894e115012SGarrett Wollman 	case TOK_STRING:
5904e115012SGarrett Wollman 	case TOK_OPAQUE:
5914e115012SGarrett Wollman 	case TOK_CHAR:
5924e115012SGarrett Wollman 	case TOK_INT:
5934e115012SGarrett Wollman 	case TOK_FLOAT:
5944e115012SGarrett Wollman 	case TOK_DOUBLE:
5954e115012SGarrett Wollman 	case TOK_BOOL:
596ff49530fSBill Paul 	case TOK_QUAD:
5974e115012SGarrett Wollman 		*typep = tok.str;
5984e115012SGarrett Wollman 		break;
5994e115012SGarrett Wollman 	default:
6004e115012SGarrett Wollman 		error("expected type specifier");
6014e115012SGarrett Wollman 	}
6024e115012SGarrett Wollman }
6034e115012SGarrett Wollman 
604526195adSJordan K. Hubbard static void
605e390e3afSDavid Malone unsigned_dec(const char **typep)
6064e115012SGarrett Wollman {
6074e115012SGarrett Wollman 	token tok;
6084e115012SGarrett Wollman 
6094e115012SGarrett Wollman 	peek(&tok);
6104e115012SGarrett Wollman 	switch (tok.kind) {
6114e115012SGarrett Wollman 	case TOK_CHAR:
6124e115012SGarrett Wollman 		get_token(&tok);
6134e115012SGarrett Wollman 		*typep = "u_char";
6144e115012SGarrett Wollman 		break;
6154e115012SGarrett Wollman 	case TOK_SHORT:
6164e115012SGarrett Wollman 		get_token(&tok);
6174e115012SGarrett Wollman 		*typep = "u_short";
6184e115012SGarrett Wollman 		(void) peekscan(TOK_INT, &tok);
6194e115012SGarrett Wollman 		break;
6204e115012SGarrett Wollman 	case TOK_LONG:
6214e115012SGarrett Wollman 		get_token(&tok);
6224e115012SGarrett Wollman 		*typep = "u_long";
6234e115012SGarrett Wollman 		(void) peekscan(TOK_INT, &tok);
6244e115012SGarrett Wollman 		break;
625ff49530fSBill Paul 	case TOK_HYPER:
626ff49530fSBill Paul 		get_token(&tok);
627c304ad8aSDavid E. O'Brien 		*typep = "u_int64_t";
6288360efbdSAlfred Perlstein 
629ff49530fSBill Paul 		(void) peekscan(TOK_INT, &tok);
630ff49530fSBill Paul 		break;
6314e115012SGarrett Wollman 	case TOK_INT:
6324e115012SGarrett Wollman 		get_token(&tok);
6334e115012SGarrett Wollman 		*typep = "u_int";
6344e115012SGarrett Wollman 		break;
6354e115012SGarrett Wollman 	default:
6364e115012SGarrett Wollman 		*typep = "u_int";
6374e115012SGarrett Wollman 		break;
6384e115012SGarrett Wollman 	}
6394e115012SGarrett Wollman }
640