xref: /freebsd/usr.bin/rpcgen/rpc_parse.c (revision c304ad8a23bc3b8e3f9315d01c2e291c391117c7)
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 
30ff49530fSBill Paul #ident	"@(#)rpc_parse.c	1.12	93/07/05 SMI"
31ff49530fSBill Paul 
324e115012SGarrett Wollman #ifndef lint
33ff49530fSBill Paul static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
344e115012SGarrett Wollman #endif
354e115012SGarrett Wollman 
364e115012SGarrett Wollman /*
374e115012SGarrett Wollman  * rpc_parse.c, Parser for the RPC protocol compiler
384e115012SGarrett Wollman  * Copyright (C) 1987 Sun Microsystems, Inc.
394e115012SGarrett Wollman  */
404e115012SGarrett Wollman #include <stdio.h>
41ff49530fSBill Paul #include <string.h>
42ff49530fSBill Paul #include "rpc/types.h"
434e115012SGarrett Wollman #include "rpc_scan.h"
444e115012SGarrett Wollman #include "rpc_parse.h"
45ff49530fSBill Paul #include "rpc_util.h"
464e115012SGarrett Wollman 
47ff49530fSBill Paul #define ARGNAME "arg"
48ff49530fSBill Paul 
49ff49530fSBill Paul extern char *make_argname __P(( char *, char * ));
50526195adSJordan K. Hubbard static void isdefined __P(( definition * ));
51526195adSJordan K. Hubbard static void def_struct __P(( definition * ));
52526195adSJordan K. Hubbard static void def_program __P(( definition * ));
53526195adSJordan K. Hubbard static void def_enum __P(( definition * ));
54526195adSJordan K. Hubbard static void def_const __P(( definition * ));
55526195adSJordan K. Hubbard static void def_union __P(( definition * ));
56526195adSJordan K. Hubbard static void def_typedef __P(( definition * ));
57526195adSJordan K. Hubbard static void get_declaration __P(( declaration *, defkind ));
58526195adSJordan K. Hubbard static void get_prog_declaration __P(( declaration *, defkind, int ));
59526195adSJordan K. Hubbard static void get_type __P(( char **, char **, defkind ));
60526195adSJordan K. Hubbard static void unsigned_dec __P(( char ** ));
61ff49530fSBill Paul 
62ff49530fSBill Paul #ifndef __FreeBSD__
63ff49530fSBill Paul extern char *strdup();
64ff49530fSBill Paul #endif
65ff49530fSBill Paul 
664e115012SGarrett Wollman /*
674e115012SGarrett Wollman  * return the next definition you see
684e115012SGarrett Wollman  */
694e115012SGarrett Wollman definition *
704e115012SGarrett Wollman get_definition()
714e115012SGarrett Wollman {
724e115012SGarrett Wollman 	definition *defp;
734e115012SGarrett Wollman 	token tok;
744e115012SGarrett Wollman 
754e115012SGarrett Wollman 	defp = ALLOC(definition);
764e115012SGarrett Wollman 	get_token(&tok);
774e115012SGarrett Wollman 	switch (tok.kind) {
784e115012SGarrett Wollman 	case TOK_STRUCT:
794e115012SGarrett Wollman 		def_struct(defp);
804e115012SGarrett Wollman 		break;
814e115012SGarrett Wollman 	case TOK_UNION:
824e115012SGarrett Wollman 		def_union(defp);
834e115012SGarrett Wollman 		break;
844e115012SGarrett Wollman 	case TOK_TYPEDEF:
854e115012SGarrett Wollman 		def_typedef(defp);
864e115012SGarrett Wollman 		break;
874e115012SGarrett Wollman 	case TOK_ENUM:
884e115012SGarrett Wollman 		def_enum(defp);
894e115012SGarrett Wollman 		break;
904e115012SGarrett Wollman 	case TOK_PROGRAM:
914e115012SGarrett Wollman 		def_program(defp);
924e115012SGarrett Wollman 		break;
934e115012SGarrett Wollman 	case TOK_CONST:
944e115012SGarrett Wollman 		def_const(defp);
954e115012SGarrett Wollman 		break;
964e115012SGarrett Wollman 	case TOK_EOF:
974e115012SGarrett Wollman 		return (NULL);
984e115012SGarrett Wollman 	default:
994e115012SGarrett Wollman 		error("definition keyword expected");
1004e115012SGarrett Wollman 	}
1014e115012SGarrett Wollman 	scan(TOK_SEMICOLON, &tok);
1024e115012SGarrett Wollman 	isdefined(defp);
1034e115012SGarrett Wollman 	return (defp);
1044e115012SGarrett Wollman }
1054e115012SGarrett Wollman 
106526195adSJordan K. Hubbard static void
1074e115012SGarrett Wollman isdefined(defp)
1084e115012SGarrett Wollman 	definition *defp;
1094e115012SGarrett Wollman {
1104e115012SGarrett Wollman 	STOREVAL(&defined, defp);
1114e115012SGarrett Wollman }
1124e115012SGarrett Wollman 
113526195adSJordan K. Hubbard static void
1144e115012SGarrett Wollman def_struct(defp)
1154e115012SGarrett Wollman 	definition *defp;
1164e115012SGarrett Wollman {
1174e115012SGarrett Wollman 	token tok;
1184e115012SGarrett Wollman 	declaration dec;
1194e115012SGarrett Wollman 	decl_list *decls;
1204e115012SGarrett Wollman 	decl_list **tailp;
1214e115012SGarrett Wollman 
1224e115012SGarrett Wollman 	defp->def_kind = DEF_STRUCT;
1234e115012SGarrett Wollman 
1244e115012SGarrett Wollman 	scan(TOK_IDENT, &tok);
1254e115012SGarrett Wollman 	defp->def_name = tok.str;
1264e115012SGarrett Wollman 	scan(TOK_LBRACE, &tok);
1274e115012SGarrett Wollman 	tailp = &defp->def.st.decls;
1284e115012SGarrett Wollman 	do {
1294e115012SGarrett Wollman 		get_declaration(&dec, DEF_STRUCT);
1304e115012SGarrett Wollman 		decls = ALLOC(decl_list);
1314e115012SGarrett Wollman 		decls->decl = dec;
1324e115012SGarrett Wollman 		*tailp = decls;
1334e115012SGarrett Wollman 		tailp = &decls->next;
1344e115012SGarrett Wollman 		scan(TOK_SEMICOLON, &tok);
1354e115012SGarrett Wollman 		peek(&tok);
1364e115012SGarrett Wollman 	} while (tok.kind != TOK_RBRACE);
1374e115012SGarrett Wollman 	get_token(&tok);
1384e115012SGarrett Wollman 	*tailp = NULL;
1394e115012SGarrett Wollman }
1404e115012SGarrett Wollman 
141526195adSJordan K. Hubbard static void
1424e115012SGarrett Wollman def_program(defp)
1434e115012SGarrett Wollman 	definition *defp;
1444e115012SGarrett Wollman {
1454e115012SGarrett Wollman 	token tok;
146ff49530fSBill Paul 	declaration dec;
147ff49530fSBill Paul 	decl_list *decls;
148ff49530fSBill Paul 	decl_list **tailp;
1494e115012SGarrett Wollman 	version_list *vlist;
1504e115012SGarrett Wollman 	version_list **vtailp;
1514e115012SGarrett Wollman 	proc_list *plist;
1524e115012SGarrett Wollman 	proc_list **ptailp;
153ff49530fSBill Paul 	int num_args;
154ff49530fSBill Paul 	bool_t isvoid = FALSE;	/* whether first argument is void */
1554e115012SGarrett Wollman 	defp->def_kind = DEF_PROGRAM;
1564e115012SGarrett Wollman 	scan(TOK_IDENT, &tok);
1574e115012SGarrett Wollman 	defp->def_name = tok.str;
1584e115012SGarrett Wollman 	scan(TOK_LBRACE, &tok);
1594e115012SGarrett Wollman 	vtailp = &defp->def.pr.versions;
160ff49530fSBill Paul 	tailp = &defp->def.st.decls;
1614e115012SGarrett Wollman 	scan(TOK_VERSION, &tok);
1624e115012SGarrett Wollman 	do {
1634e115012SGarrett Wollman 		scan(TOK_IDENT, &tok);
1644e115012SGarrett Wollman 		vlist = ALLOC(version_list);
1654e115012SGarrett Wollman 		vlist->vers_name = tok.str;
1664e115012SGarrett Wollman 		scan(TOK_LBRACE, &tok);
1674e115012SGarrett Wollman 		ptailp = &vlist->procs;
1684e115012SGarrett Wollman 		do {
169ff49530fSBill Paul 			/* get result type */
1704e115012SGarrett Wollman 			plist = ALLOC(proc_list);
171ff49530fSBill Paul 			get_type(&plist->res_prefix, &plist->res_type,
172ff49530fSBill Paul 				 DEF_PROGRAM);
1734e115012SGarrett Wollman 			if (streq(plist->res_type, "opaque")) {
1744e115012SGarrett Wollman 				error("illegal result type");
1754e115012SGarrett Wollman 			}
1764e115012SGarrett Wollman 			scan(TOK_IDENT, &tok);
1774e115012SGarrett Wollman 			plist->proc_name = tok.str;
1784e115012SGarrett Wollman 			scan(TOK_LPAREN, &tok);
179ff49530fSBill Paul 			/* get args - first one */
180ff49530fSBill Paul 			num_args = 1;
181ff49530fSBill Paul 			isvoid = FALSE;
182ff49530fSBill Paul 			/*
183ff49530fSBill Paul 			 * type of DEF_PROGRAM in the first
184ff49530fSBill Paul 			 * get_prog_declaration and DEF_STURCT in the next
185ff49530fSBill Paul 			 * allows void as argument if it is the only argument
186ff49530fSBill Paul 			 */
187ff49530fSBill Paul 			get_prog_declaration(&dec, DEF_PROGRAM, num_args);
188ff49530fSBill Paul 			if (streq(dec.type, "void"))
189ff49530fSBill Paul 				isvoid = TRUE;
190ff49530fSBill Paul 			decls = ALLOC(decl_list);
191ff49530fSBill Paul 			plist->args.decls = decls;
192ff49530fSBill Paul 			decls->decl = dec;
193ff49530fSBill Paul 			tailp = &decls->next;
194ff49530fSBill Paul 			/* get args */
195ff49530fSBill Paul 			while (peekscan(TOK_COMMA, &tok)) {
196ff49530fSBill Paul 				num_args++;
197ff49530fSBill Paul 				get_prog_declaration(&dec, DEF_STRUCT,
198ff49530fSBill Paul 						     num_args);
199ff49530fSBill Paul 				decls = ALLOC(decl_list);
200ff49530fSBill Paul 				decls->decl = dec;
201ff49530fSBill Paul 				*tailp = decls;
202ff49530fSBill Paul 				if (streq(dec.type, "void"))
203ff49530fSBill Paul 					isvoid = TRUE;
204ff49530fSBill Paul 				tailp = &decls->next;
2054e115012SGarrett Wollman 			}
206ff49530fSBill Paul 			/* multiple arguments are only allowed in newstyle */
207ff49530fSBill Paul 			if (!newstyle && num_args > 1) {
208ff49530fSBill Paul 				error("only one argument is allowed");
209ff49530fSBill Paul 			}
210ff49530fSBill Paul 			if (isvoid && num_args > 1) {
211ff49530fSBill Paul 				error("illegal use of void in program definition");
212ff49530fSBill Paul 			}
213ff49530fSBill Paul 			*tailp = NULL;
2144e115012SGarrett Wollman 			scan(TOK_RPAREN, &tok);
2154e115012SGarrett Wollman 			scan(TOK_EQUAL, &tok);
2164e115012SGarrett Wollman 			scan_num(&tok);
2174e115012SGarrett Wollman 			scan(TOK_SEMICOLON, &tok);
2184e115012SGarrett Wollman 			plist->proc_num = tok.str;
219ff49530fSBill Paul 			plist->arg_num = num_args;
2204e115012SGarrett Wollman 			*ptailp = plist;
2214e115012SGarrett Wollman 			ptailp = &plist->next;
2224e115012SGarrett Wollman 			peek(&tok);
2234e115012SGarrett Wollman 		} while (tok.kind != TOK_RBRACE);
2240b455160SAndrey A. Chernov 		*ptailp = NULL;
2254e115012SGarrett Wollman 		*vtailp = vlist;
2264e115012SGarrett Wollman 		vtailp = &vlist->next;
2274e115012SGarrett Wollman 		scan(TOK_RBRACE, &tok);
2284e115012SGarrett Wollman 		scan(TOK_EQUAL, &tok);
2294e115012SGarrett Wollman 		scan_num(&tok);
2304e115012SGarrett Wollman 		vlist->vers_num = tok.str;
231ff49530fSBill Paul 		/* make the argument structure name for each arg */
232ff49530fSBill Paul 		for (plist = vlist->procs; plist != NULL;
233ff49530fSBill Paul 		     plist = plist->next) {
234ff49530fSBill Paul 			plist->args.argname = make_argname(plist->proc_name,
235ff49530fSBill Paul 							   vlist->vers_num);
236ff49530fSBill Paul 			/* free the memory ?? */
237ff49530fSBill Paul 		}
2384e115012SGarrett Wollman 		scan(TOK_SEMICOLON, &tok);
2394e115012SGarrett Wollman 		scan2(TOK_VERSION, TOK_RBRACE, &tok);
2404e115012SGarrett Wollman 	} while (tok.kind == TOK_VERSION);
2414e115012SGarrett Wollman 	scan(TOK_EQUAL, &tok);
2424e115012SGarrett Wollman 	scan_num(&tok);
2434e115012SGarrett Wollman 	defp->def.pr.prog_num = tok.str;
2444e115012SGarrett Wollman 	*vtailp = NULL;
2454e115012SGarrett Wollman }
2464e115012SGarrett Wollman 
247ff49530fSBill Paul 
248526195adSJordan K. Hubbard static void
2494e115012SGarrett Wollman def_enum(defp)
2504e115012SGarrett Wollman 	definition *defp;
2514e115012SGarrett Wollman {
2524e115012SGarrett Wollman 	token tok;
2534e115012SGarrett Wollman 	enumval_list *elist;
2544e115012SGarrett Wollman 	enumval_list **tailp;
2554e115012SGarrett Wollman 
2564e115012SGarrett Wollman 	defp->def_kind = DEF_ENUM;
2574e115012SGarrett Wollman 	scan(TOK_IDENT, &tok);
2584e115012SGarrett Wollman 	defp->def_name = tok.str;
2594e115012SGarrett Wollman 	scan(TOK_LBRACE, &tok);
2604e115012SGarrett Wollman 	tailp = &defp->def.en.vals;
2614e115012SGarrett Wollman 	do {
2624e115012SGarrett Wollman 		scan(TOK_IDENT, &tok);
2634e115012SGarrett Wollman 		elist = ALLOC(enumval_list);
2644e115012SGarrett Wollman 		elist->name = tok.str;
2654e115012SGarrett Wollman 		elist->assignment = NULL;
2664e115012SGarrett Wollman 		scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
2674e115012SGarrett Wollman 		if (tok.kind == TOK_EQUAL) {
2684e115012SGarrett Wollman 			scan_num(&tok);
2694e115012SGarrett Wollman 			elist->assignment = tok.str;
2704e115012SGarrett Wollman 			scan2(TOK_COMMA, TOK_RBRACE, &tok);
2714e115012SGarrett Wollman 		}
2724e115012SGarrett Wollman 		*tailp = elist;
2734e115012SGarrett Wollman 		tailp = &elist->next;
2744e115012SGarrett Wollman 	} while (tok.kind != TOK_RBRACE);
2754e115012SGarrett Wollman 	*tailp = NULL;
2764e115012SGarrett Wollman }
2774e115012SGarrett Wollman 
278526195adSJordan K. Hubbard static void
2794e115012SGarrett Wollman def_const(defp)
2804e115012SGarrett Wollman 	definition *defp;
2814e115012SGarrett Wollman {
2824e115012SGarrett Wollman 	token tok;
2834e115012SGarrett Wollman 
2844e115012SGarrett Wollman 	defp->def_kind = DEF_CONST;
2854e115012SGarrett Wollman 	scan(TOK_IDENT, &tok);
2864e115012SGarrett Wollman 	defp->def_name = tok.str;
2874e115012SGarrett Wollman 	scan(TOK_EQUAL, &tok);
2884e115012SGarrett Wollman 	scan2(TOK_IDENT, TOK_STRCONST, &tok);
2894e115012SGarrett Wollman 	defp->def.co = tok.str;
2904e115012SGarrett Wollman }
2914e115012SGarrett Wollman 
292526195adSJordan K. Hubbard static void
2934e115012SGarrett Wollman def_union(defp)
2944e115012SGarrett Wollman 	definition *defp;
2954e115012SGarrett Wollman {
2964e115012SGarrett Wollman 	token tok;
2974e115012SGarrett Wollman 	declaration dec;
298526195adSJordan K. Hubbard 	case_list *cases;
2994e115012SGarrett Wollman 	case_list **tailp;
300ff49530fSBill Paul 	int flag;
3014e115012SGarrett Wollman 
3024e115012SGarrett Wollman 	defp->def_kind = DEF_UNION;
3034e115012SGarrett Wollman 	scan(TOK_IDENT, &tok);
3044e115012SGarrett Wollman 	defp->def_name = tok.str;
3054e115012SGarrett Wollman 	scan(TOK_SWITCH, &tok);
3064e115012SGarrett Wollman 	scan(TOK_LPAREN, &tok);
3074e115012SGarrett Wollman 	get_declaration(&dec, DEF_UNION);
3084e115012SGarrett Wollman 	defp->def.un.enum_decl = dec;
3094e115012SGarrett Wollman 	tailp = &defp->def.un.cases;
3104e115012SGarrett Wollman 	scan(TOK_RPAREN, &tok);
3114e115012SGarrett Wollman 	scan(TOK_LBRACE, &tok);
3124e115012SGarrett Wollman 	scan(TOK_CASE, &tok);
3134e115012SGarrett Wollman 	while (tok.kind == TOK_CASE) {
314ff49530fSBill Paul 		scan2(TOK_IDENT, TOK_CHARCONST, &tok);
3154e115012SGarrett Wollman 		cases = ALLOC(case_list);
3164e115012SGarrett Wollman 		cases->case_name = tok.str;
3174e115012SGarrett Wollman 		scan(TOK_COLON, &tok);
318ff49530fSBill Paul 		/* now peek at next token */
319ff49530fSBill Paul 		flag = 0;
320ff49530fSBill Paul 		if (peekscan(TOK_CASE, &tok)){
321ff49530fSBill Paul 			do {
322ff49530fSBill Paul 				scan2(TOK_IDENT, TOK_CHARCONST, &tok);
323ff49530fSBill Paul 				cases->contflag = 1;
324ff49530fSBill Paul 				/* continued case statement */
325ff49530fSBill Paul 				*tailp = cases;
326ff49530fSBill Paul 				tailp = &cases->next;
327ff49530fSBill Paul 				cases = ALLOC(case_list);
328ff49530fSBill Paul 				cases->case_name = tok.str;
329ff49530fSBill Paul 				scan(TOK_COLON, &tok);
330ff49530fSBill Paul 			} while (peekscan(TOK_CASE, &tok));
331ff49530fSBill Paul 		}
332ff49530fSBill Paul 		else
333ff49530fSBill Paul 			if (flag)
334ff49530fSBill Paul 			{
335ff49530fSBill Paul 
336ff49530fSBill Paul 				*tailp = cases;
337ff49530fSBill Paul 				tailp = &cases->next;
338ff49530fSBill Paul 				cases = ALLOC(case_list);
339ff49530fSBill Paul 			};
340ff49530fSBill Paul 
3414e115012SGarrett Wollman 		get_declaration(&dec, DEF_UNION);
3424e115012SGarrett Wollman 		cases->case_decl = dec;
343ff49530fSBill Paul 		cases->contflag = 0; /* no continued case statement */
3444e115012SGarrett Wollman 		*tailp = cases;
3454e115012SGarrett Wollman 		tailp = &cases->next;
3464e115012SGarrett Wollman 		scan(TOK_SEMICOLON, &tok);
347ff49530fSBill Paul 
3484e115012SGarrett Wollman 		scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
3494e115012SGarrett Wollman 	}
3504e115012SGarrett Wollman 	*tailp = NULL;
3514e115012SGarrett Wollman 	if (tok.kind == TOK_DEFAULT) {
3524e115012SGarrett Wollman 		scan(TOK_COLON, &tok);
3534e115012SGarrett Wollman 		get_declaration(&dec, DEF_UNION);
3544e115012SGarrett Wollman 		defp->def.un.default_decl = ALLOC(declaration);
3554e115012SGarrett Wollman 		*defp->def.un.default_decl = dec;
3564e115012SGarrett Wollman 		scan(TOK_SEMICOLON, &tok);
3574e115012SGarrett Wollman 		scan(TOK_RBRACE, &tok);
3584e115012SGarrett Wollman 	} else {
3594e115012SGarrett Wollman 		defp->def.un.default_decl = NULL;
3604e115012SGarrett Wollman 	}
3614e115012SGarrett Wollman }
3624e115012SGarrett Wollman 
363ff49530fSBill Paul static char* reserved_words[] =
364ff49530fSBill Paul {
365ff49530fSBill Paul 	"array",
366ff49530fSBill Paul 	"bytes",
367ff49530fSBill Paul 	"destroy",
368ff49530fSBill Paul 	"free",
369ff49530fSBill Paul 	"getpos",
370ff49530fSBill Paul 	"inline",
371ff49530fSBill Paul 	"pointer",
372ff49530fSBill Paul 	"reference",
373ff49530fSBill Paul 	"setpos",
374ff49530fSBill Paul 	"sizeof",
375ff49530fSBill Paul 	"union",
376ff49530fSBill Paul 	"vector",
377ff49530fSBill Paul 	NULL
378ff49530fSBill Paul 	};
379ff49530fSBill Paul 
380ff49530fSBill Paul static char* reserved_types[] =
381ff49530fSBill Paul {
382ff49530fSBill Paul 	"opaque",
383ff49530fSBill Paul 	"string",
384ff49530fSBill Paul 	NULL
385ff49530fSBill Paul 	};
386ff49530fSBill Paul 
387ff49530fSBill Paul /*
388ff49530fSBill Paul  * check that the given name is not one that would eventually result in
389ff49530fSBill Paul  * xdr routines that would conflict with internal XDR routines.
390ff49530fSBill Paul  */
391526195adSJordan K. Hubbard static void
392526195adSJordan K. Hubbard check_type_name(name, new_type)
393ff49530fSBill Paul int new_type;
394ff49530fSBill Paul char* name;
395ff49530fSBill Paul {
396ff49530fSBill Paul 	int i;
397ff49530fSBill Paul 	char tmp[100];
398ff49530fSBill Paul 
399ff49530fSBill Paul 	for (i = 0; reserved_words[i] != NULL; i++) {
400ff49530fSBill Paul 		if (strcmp(name, reserved_words[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 	if (new_type) {
408ff49530fSBill Paul 		for (i = 0; reserved_types[i] != NULL; i++) {
409ff49530fSBill Paul 			if (strcmp(name, reserved_types[i]) == 0) {
410ff49530fSBill Paul 				sprintf(tmp,
411ff49530fSBill Paul 					"illegal (reserved) name :\'%s\' in type definition",
412ff49530fSBill Paul 					name);
413ff49530fSBill Paul 				error(tmp);
414ff49530fSBill Paul 			}
415ff49530fSBill Paul 		}
416ff49530fSBill Paul 	}
417ff49530fSBill Paul }
418ff49530fSBill Paul 
419ff49530fSBill Paul 
4204e115012SGarrett Wollman 
421526195adSJordan K. Hubbard static void
4224e115012SGarrett Wollman def_typedef(defp)
4234e115012SGarrett Wollman 	definition *defp;
4244e115012SGarrett Wollman {
4254e115012SGarrett Wollman 	declaration dec;
4264e115012SGarrett Wollman 
4274e115012SGarrett Wollman 	defp->def_kind = DEF_TYPEDEF;
4284e115012SGarrett Wollman 	get_declaration(&dec, DEF_TYPEDEF);
4294e115012SGarrett Wollman 	defp->def_name = dec.name;
430ff49530fSBill Paul 	check_type_name(dec.name, 1);
4314e115012SGarrett Wollman 	defp->def.ty.old_prefix = dec.prefix;
4324e115012SGarrett Wollman 	defp->def.ty.old_type = dec.type;
4334e115012SGarrett Wollman 	defp->def.ty.rel = dec.rel;
4344e115012SGarrett Wollman 	defp->def.ty.array_max = dec.array_max;
4354e115012SGarrett Wollman }
4364e115012SGarrett Wollman 
437526195adSJordan K. Hubbard static void
4384e115012SGarrett Wollman get_declaration(dec, dkind)
4394e115012SGarrett Wollman 	declaration *dec;
4404e115012SGarrett Wollman 	defkind dkind;
4414e115012SGarrett Wollman {
4424e115012SGarrett Wollman 	token tok;
4434e115012SGarrett Wollman 
4444e115012SGarrett Wollman 	get_type(&dec->prefix, &dec->type, dkind);
4454e115012SGarrett Wollman 	dec->rel = REL_ALIAS;
4464e115012SGarrett Wollman 	if (streq(dec->type, "void")) {
4474e115012SGarrett Wollman 		return;
4484e115012SGarrett Wollman 	}
449ff49530fSBill Paul 
450ff49530fSBill Paul 	check_type_name(dec->type, 0);
4514e115012SGarrett Wollman 	scan2(TOK_STAR, TOK_IDENT, &tok);
4524e115012SGarrett Wollman 	if (tok.kind == TOK_STAR) {
4534e115012SGarrett Wollman 		dec->rel = REL_POINTER;
4544e115012SGarrett Wollman 		scan(TOK_IDENT, &tok);
4554e115012SGarrett Wollman 	}
4564e115012SGarrett Wollman 	dec->name = tok.str;
4574e115012SGarrett Wollman 	if (peekscan(TOK_LBRACKET, &tok)) {
4584e115012SGarrett Wollman 		if (dec->rel == REL_POINTER) {
4594e115012SGarrett Wollman 			error("no array-of-pointer declarations -- use typedef");
4604e115012SGarrett Wollman 		}
4614e115012SGarrett Wollman 		dec->rel = REL_VECTOR;
4624e115012SGarrett Wollman 		scan_num(&tok);
4634e115012SGarrett Wollman 		dec->array_max = tok.str;
4644e115012SGarrett Wollman 		scan(TOK_RBRACKET, &tok);
4654e115012SGarrett Wollman 	} else if (peekscan(TOK_LANGLE, &tok)) {
4664e115012SGarrett Wollman 		if (dec->rel == REL_POINTER) {
4674e115012SGarrett Wollman 			error("no array-of-pointer declarations -- use typedef");
4684e115012SGarrett Wollman 		}
4694e115012SGarrett Wollman 		dec->rel = REL_ARRAY;
4704e115012SGarrett Wollman 		if (peekscan(TOK_RANGLE, &tok)) {
4714e115012SGarrett Wollman 			dec->array_max = "~0";	/* unspecified size, use max */
4724e115012SGarrett Wollman 		} else {
4734e115012SGarrett Wollman 			scan_num(&tok);
4744e115012SGarrett Wollman 			dec->array_max = tok.str;
4754e115012SGarrett Wollman 			scan(TOK_RANGLE, &tok);
4764e115012SGarrett Wollman 		}
4774e115012SGarrett Wollman 	}
4784e115012SGarrett Wollman 	if (streq(dec->type, "opaque")) {
4794e115012SGarrett Wollman 		if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
4804e115012SGarrett Wollman 			error("array declaration expected");
4814e115012SGarrett Wollman 		}
4824e115012SGarrett Wollman 	} else if (streq(dec->type, "string")) {
4834e115012SGarrett Wollman 		if (dec->rel != REL_ARRAY) {
4844e115012SGarrett Wollman 			error("variable-length array declaration expected");
4854e115012SGarrett Wollman 		}
4864e115012SGarrett Wollman 	}
4874e115012SGarrett Wollman }
4884e115012SGarrett Wollman 
4894e115012SGarrett Wollman 
490526195adSJordan K. Hubbard static void
491ff49530fSBill Paul get_prog_declaration(dec, dkind, num)
492ff49530fSBill Paul 	declaration *dec;
493ff49530fSBill Paul 	defkind dkind;
494ff49530fSBill Paul 	int num;  /* arg number */
495ff49530fSBill Paul {
496ff49530fSBill Paul 	token tok;
497ff49530fSBill Paul 	char name[10];		/* argument name */
498ff49530fSBill Paul 
499ff49530fSBill Paul 	if (dkind == DEF_PROGRAM) {
500ff49530fSBill Paul 		peek(&tok);
501ff49530fSBill Paul 		if (tok.kind == TOK_RPAREN) { /* no arguments */
502ff49530fSBill Paul 			dec->rel = REL_ALIAS;
503ff49530fSBill Paul 			dec->type = "void";
504ff49530fSBill Paul 			dec->prefix = NULL;
505ff49530fSBill Paul 			dec->name = NULL;
506ff49530fSBill Paul 			return;
507ff49530fSBill Paul 		}
508ff49530fSBill Paul 	}
509ff49530fSBill Paul 	get_type(&dec->prefix, &dec->type, dkind);
510ff49530fSBill Paul 	dec->rel = REL_ALIAS;
511ff49530fSBill Paul 	if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
512ff49530fSBill Paul 		strcpy(name, tok.str);
513ff49530fSBill Paul 	else
514ff49530fSBill Paul 		sprintf(name, "%s%d", ARGNAME, num);
515ff49530fSBill Paul 	/* default name of argument */
516ff49530fSBill Paul 
517ff49530fSBill Paul 	dec->name = (char *) strdup(name);
518ff49530fSBill Paul 	if (streq(dec->type, "void")) {
519ff49530fSBill Paul 		return;
520ff49530fSBill Paul 	}
521ff49530fSBill Paul 
522ff49530fSBill Paul 	if (streq(dec->type, "opaque")) {
523ff49530fSBill Paul 		error("opaque -- illegal argument type");
524ff49530fSBill Paul 	}
525ff49530fSBill Paul 	if (peekscan(TOK_STAR, &tok)) {
526ff49530fSBill Paul 		if (streq(dec->type, "string")) {
527ff49530fSBill Paul 			error("pointer to string not allowed in program arguments\n");
528ff49530fSBill Paul 		}
529ff49530fSBill Paul 		dec->rel = REL_POINTER;
530ff49530fSBill Paul 		if (peekscan(TOK_IDENT, &tok))
531ff49530fSBill Paul 			/* optional name of argument */
532ff49530fSBill Paul 			dec->name = strdup(tok.str);
533ff49530fSBill Paul 	}
534ff49530fSBill Paul 	if (peekscan(TOK_LANGLE, &tok)) {
535ff49530fSBill Paul 		if (!streq(dec->type, "string")) {
536ff49530fSBill Paul 			error("arrays cannot be declared as arguments to procedures -- use typedef");
537ff49530fSBill Paul 		}
538ff49530fSBill Paul 		dec->rel = REL_ARRAY;
539ff49530fSBill Paul 		if (peekscan(TOK_RANGLE, &tok)) {
540ff49530fSBill Paul 			dec->array_max = "~0";
541ff49530fSBill Paul 			/* unspecified size, use max */
542ff49530fSBill Paul 		} else {
543ff49530fSBill Paul 			scan_num(&tok);
544ff49530fSBill Paul 			dec->array_max = tok.str;
545ff49530fSBill Paul 			scan(TOK_RANGLE, &tok);
546ff49530fSBill Paul 		}
547ff49530fSBill Paul 	}
548ff49530fSBill Paul 	if (streq(dec->type, "string")) {
549ff49530fSBill Paul 		if (dec->rel != REL_ARRAY) {
550ff49530fSBill Paul 			/*
551ff49530fSBill Paul 			 * .x specifies just string as
552ff49530fSBill Paul 			 * type of argument
553ff49530fSBill Paul 			 * - make it string<>
554ff49530fSBill Paul 			 */
555ff49530fSBill Paul 			dec->rel = REL_ARRAY;
556ff49530fSBill Paul 			dec->array_max = "~0"; /* unspecified size, use max */
557ff49530fSBill Paul 		}
558ff49530fSBill Paul 	}
559ff49530fSBill Paul }
560ff49530fSBill Paul 
561ff49530fSBill Paul 
562ff49530fSBill Paul 
563526195adSJordan K. Hubbard static void
5644e115012SGarrett Wollman get_type(prefixp, typep, dkind)
5654e115012SGarrett Wollman 	char **prefixp;
5664e115012SGarrett Wollman 	char **typep;
5674e115012SGarrett Wollman 	defkind dkind;
5684e115012SGarrett Wollman {
5694e115012SGarrett Wollman 	token tok;
5704e115012SGarrett Wollman 
5714e115012SGarrett Wollman 	*prefixp = NULL;
5724e115012SGarrett Wollman 	get_token(&tok);
5734e115012SGarrett Wollman 	switch (tok.kind) {
5744e115012SGarrett Wollman 	case TOK_IDENT:
5754e115012SGarrett Wollman 		*typep = tok.str;
5764e115012SGarrett Wollman 		break;
5774e115012SGarrett Wollman 	case TOK_STRUCT:
5784e115012SGarrett Wollman 	case TOK_ENUM:
5794e115012SGarrett Wollman 	case TOK_UNION:
5804e115012SGarrett Wollman 		*prefixp = tok.str;
5814e115012SGarrett Wollman 		scan(TOK_IDENT, &tok);
5824e115012SGarrett Wollman 		*typep = tok.str;
5834e115012SGarrett Wollman 		break;
5844e115012SGarrett Wollman 	case TOK_UNSIGNED:
5854e115012SGarrett Wollman 		unsigned_dec(typep);
5864e115012SGarrett Wollman 		break;
5874e115012SGarrett Wollman 	case TOK_SHORT:
5884e115012SGarrett Wollman 		*typep = "short";
5894e115012SGarrett Wollman 		(void) peekscan(TOK_INT, &tok);
5904e115012SGarrett Wollman 		break;
5914e115012SGarrett Wollman 	case TOK_LONG:
5924e115012SGarrett Wollman 		*typep = "long";
5934e115012SGarrett Wollman 		(void) peekscan(TOK_INT, &tok);
5944e115012SGarrett Wollman 		break;
595ff49530fSBill Paul 	case TOK_HYPER:
596c304ad8aSDavid E. O'Brien 		*typep = "int64_t";
597ff49530fSBill Paul 		(void) peekscan(TOK_INT, &tok);
598ff49530fSBill Paul 		break;
599ff49530fSBill Paul 
6004e115012SGarrett Wollman 	case TOK_VOID:
6014e115012SGarrett Wollman 		if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
602ff49530fSBill Paul 			error("voids allowed only inside union and program definitions with one argument");
6034e115012SGarrett Wollman 		}
6044e115012SGarrett Wollman 		*typep = tok.str;
6054e115012SGarrett Wollman 		break;
6064e115012SGarrett Wollman 	case TOK_STRING:
6074e115012SGarrett Wollman 	case TOK_OPAQUE:
6084e115012SGarrett Wollman 	case TOK_CHAR:
6094e115012SGarrett Wollman 	case TOK_INT:
6104e115012SGarrett Wollman 	case TOK_FLOAT:
6114e115012SGarrett Wollman 	case TOK_DOUBLE:
6124e115012SGarrett Wollman 	case TOK_BOOL:
613ff49530fSBill Paul 	case TOK_QUAD:
6144e115012SGarrett Wollman 		*typep = tok.str;
6154e115012SGarrett Wollman 		break;
6164e115012SGarrett Wollman 	default:
6174e115012SGarrett Wollman 		error("expected type specifier");
6184e115012SGarrett Wollman 	}
6194e115012SGarrett Wollman }
6204e115012SGarrett Wollman 
621526195adSJordan K. Hubbard static void
6224e115012SGarrett Wollman unsigned_dec(typep)
6234e115012SGarrett Wollman 	char **typep;
6244e115012SGarrett Wollman {
6254e115012SGarrett Wollman 	token tok;
6264e115012SGarrett Wollman 
6274e115012SGarrett Wollman 	peek(&tok);
6284e115012SGarrett Wollman 	switch (tok.kind) {
6294e115012SGarrett Wollman 	case TOK_CHAR:
6304e115012SGarrett Wollman 		get_token(&tok);
6314e115012SGarrett Wollman 		*typep = "u_char";
6324e115012SGarrett Wollman 		break;
6334e115012SGarrett Wollman 	case TOK_SHORT:
6344e115012SGarrett Wollman 		get_token(&tok);
6354e115012SGarrett Wollman 		*typep = "u_short";
6364e115012SGarrett Wollman 		(void) peekscan(TOK_INT, &tok);
6374e115012SGarrett Wollman 		break;
6384e115012SGarrett Wollman 	case TOK_LONG:
6394e115012SGarrett Wollman 		get_token(&tok);
6404e115012SGarrett Wollman 		*typep = "u_long";
6414e115012SGarrett Wollman 		(void) peekscan(TOK_INT, &tok);
6424e115012SGarrett Wollman 		break;
643ff49530fSBill Paul 	case TOK_HYPER:
644ff49530fSBill Paul 		get_token(&tok);
645c304ad8aSDavid E. O'Brien 		*typep = "u_int64_t";
646ff49530fSBill Paul 		(void) peekscan(TOK_INT, &tok);
647ff49530fSBill Paul 		break;
6484e115012SGarrett Wollman 	case TOK_INT:
6494e115012SGarrett Wollman 		get_token(&tok);
6504e115012SGarrett Wollman 		*typep = "u_int";
6514e115012SGarrett Wollman 		break;
6524e115012SGarrett Wollman 	default:
6534e115012SGarrett Wollman 		*typep = "u_int";
6544e115012SGarrett Wollman 		break;
6554e115012SGarrett Wollman 	}
6564e115012SGarrett Wollman }
657