11897Swollman/*
21897Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
31897Swollman * unrestricted use provided that this legend is included on all tape
41897Swollman * media and as a part of the software program in whole or part.  Users
51897Swollman * may copy or modify Sun RPC without charge, but are not authorized
61897Swollman * to license or distribute it to anyone else except as part of a product or
71897Swollman * program developed by the user.
8100441Scharnier *
91897Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
101897Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
111897Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12100441Scharnier *
131897Swollman * Sun RPC is provided with no support and without any obligation on the
141897Swollman * part of Sun Microsystems, Inc. to assist in its use, correction,
151897Swollman * modification or enhancement.
16100441Scharnier *
171897Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
181897Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
191897Swollman * OR ANY PART THEREOF.
20100441Scharnier *
211897Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue
221897Swollman * or profits or other special, indirect and consequential damages, even if
231897Swollman * Sun has been advised of the possibility of such damages.
24100441Scharnier *
251897Swollman * Sun Microsystems, Inc.
261897Swollman * 2550 Garcia Avenue
271897Swollman * Mountain View, California  94043
281897Swollman */
2912798Swpaul
30100441Scharnier#if 0
311897Swollman#ifndef lint
32146833Sstefanf#ident	"@(#)rpc_parse.c	1.12	93/07/05 SMI"
3312798Swpaulstatic char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
341897Swollman#endif
3599979Salfred#endif
361897Swollman
37100441Scharnier#include <sys/cdefs.h>
38100441Scharnier__FBSDID("$FreeBSD: stable/10/usr.bin/rpcgen/rpc_parse.c 313103 2017-02-02 19:50:28Z asomers $");
39100441Scharnier
401897Swollman/*
418874Srgrimes * rpc_parse.c, Parser for the RPC protocol compiler
421897Swollman * Copyright (C) 1987 Sun Microsystems, Inc.
431897Swollman */
441897Swollman#include <stdio.h>
4512798Swpaul#include <string.h>
4612798Swpaul#include "rpc/types.h"
47152398Sdwmalone#include "rpc_parse.h"
481897Swollman#include "rpc_scan.h"
4912798Swpaul#include "rpc_util.h"
501897Swollman
5112798Swpaul#define ARGNAME "arg"
5212798Swpaul
5392921Simpstatic void isdefined( definition * );
5492921Simpstatic void def_struct( definition * );
5592921Simpstatic void def_program( definition * );
5692921Simpstatic void def_enum( definition * );
5792921Simpstatic void def_const( definition * );
5892921Simpstatic void def_union( definition * );
5992921Simpstatic void def_typedef( definition * );
6092921Simpstatic void get_declaration( declaration *, defkind );
6192921Simpstatic void get_prog_declaration( declaration *, defkind, int );
62152398Sdwmalonestatic void get_type(const char **, const char **, defkind);
63152398Sdwmalonestatic void unsigned_dec(const char ** );
6412798Swpaul
651897Swollman/*
661897Swollman * return the next definition you see
671897Swollman */
681897Swollmandefinition *
69152398Sdwmaloneget_definition(void)
701897Swollman{
711897Swollman	definition *defp;
721897Swollman	token tok;
731897Swollman
74100441Scharnier	defp = XALLOC(definition);
751897Swollman	get_token(&tok);
761897Swollman	switch (tok.kind) {
771897Swollman	case TOK_STRUCT:
781897Swollman		def_struct(defp);
791897Swollman		break;
801897Swollman	case TOK_UNION:
811897Swollman		def_union(defp);
821897Swollman		break;
831897Swollman	case TOK_TYPEDEF:
841897Swollman		def_typedef(defp);
851897Swollman		break;
861897Swollman	case TOK_ENUM:
871897Swollman		def_enum(defp);
881897Swollman		break;
891897Swollman	case TOK_PROGRAM:
901897Swollman		def_program(defp);
911897Swollman		break;
921897Swollman	case TOK_CONST:
931897Swollman		def_const(defp);
941897Swollman		break;
951897Swollman	case TOK_EOF:
961897Swollman		return (NULL);
971897Swollman	default:
981897Swollman		error("definition keyword expected");
991897Swollman	}
1001897Swollman	scan(TOK_SEMICOLON, &tok);
1011897Swollman	isdefined(defp);
1021897Swollman	return (defp);
1031897Swollman}
1041897Swollman
10517142Sjkhstatic void
106152398Sdwmaloneisdefined(definition *defp)
1071897Swollman{
1081897Swollman	STOREVAL(&defined, defp);
1091897Swollman}
1101897Swollman
11117142Sjkhstatic void
112152398Sdwmalonedef_struct(definition *defp)
1131897Swollman{
1141897Swollman	token tok;
1151897Swollman	declaration dec;
1161897Swollman	decl_list *decls;
1171897Swollman	decl_list **tailp;
1181897Swollman
1191897Swollman	defp->def_kind = DEF_STRUCT;
1201897Swollman
1211897Swollman	scan(TOK_IDENT, &tok);
1221897Swollman	defp->def_name = tok.str;
1231897Swollman	scan(TOK_LBRACE, &tok);
1241897Swollman	tailp = &defp->def.st.decls;
1251897Swollman	do {
1261897Swollman		get_declaration(&dec, DEF_STRUCT);
127100441Scharnier		decls = XALLOC(decl_list);
1281897Swollman		decls->decl = dec;
1291897Swollman		*tailp = decls;
1301897Swollman		tailp = &decls->next;
1311897Swollman		scan(TOK_SEMICOLON, &tok);
1321897Swollman		peek(&tok);
1331897Swollman	} while (tok.kind != TOK_RBRACE);
1341897Swollman	get_token(&tok);
1351897Swollman	*tailp = NULL;
1361897Swollman}
1371897Swollman
13817142Sjkhstatic void
139152398Sdwmalonedef_program(definition *defp)
1401897Swollman{
1411897Swollman	token tok;
14212798Swpaul	declaration dec;
14312798Swpaul	decl_list *decls;
14412798Swpaul	decl_list **tailp;
1451897Swollman	version_list *vlist;
1461897Swollman	version_list **vtailp;
1471897Swollman	proc_list *plist;
1481897Swollman	proc_list **ptailp;
14912798Swpaul	int num_args;
15012798Swpaul	bool_t isvoid = FALSE;	/* whether first argument is void */
1511897Swollman	defp->def_kind = DEF_PROGRAM;
1521897Swollman	scan(TOK_IDENT, &tok);
1531897Swollman	defp->def_name = tok.str;
1541897Swollman	scan(TOK_LBRACE, &tok);
1551897Swollman	vtailp = &defp->def.pr.versions;
15612798Swpaul	tailp = &defp->def.st.decls;
1571897Swollman	scan(TOK_VERSION, &tok);
1581897Swollman	do {
1591897Swollman		scan(TOK_IDENT, &tok);
160100441Scharnier		vlist = XALLOC(version_list);
1611897Swollman		vlist->vers_name = tok.str;
1621897Swollman		scan(TOK_LBRACE, &tok);
1631897Swollman		ptailp = &vlist->procs;
1641897Swollman		do {
16512798Swpaul			/* get result type */
166100441Scharnier			plist = XALLOC(proc_list);
16712798Swpaul			get_type(&plist->res_prefix, &plist->res_type,
16812798Swpaul				 DEF_PROGRAM);
1691897Swollman			if (streq(plist->res_type, "opaque")) {
1701897Swollman				error("illegal result type");
1711897Swollman			}
1721897Swollman			scan(TOK_IDENT, &tok);
1731897Swollman			plist->proc_name = tok.str;
1741897Swollman			scan(TOK_LPAREN, &tok);
17512798Swpaul			/* get args - first one */
17612798Swpaul			num_args = 1;
17712798Swpaul			isvoid = FALSE;
17812798Swpaul			/*
17912798Swpaul			 * type of DEF_PROGRAM in the first
18012798Swpaul			 * get_prog_declaration and DEF_STURCT in the next
18112798Swpaul			 * allows void as argument if it is the only argument
18212798Swpaul			 */
18312798Swpaul			get_prog_declaration(&dec, DEF_PROGRAM, num_args);
18412798Swpaul			if (streq(dec.type, "void"))
18512798Swpaul				isvoid = TRUE;
186100441Scharnier			decls = XALLOC(decl_list);
18712798Swpaul			plist->args.decls = decls;
18812798Swpaul			decls->decl = dec;
18912798Swpaul			tailp = &decls->next;
19012798Swpaul			/* get args */
19112798Swpaul			while (peekscan(TOK_COMMA, &tok)) {
19212798Swpaul				num_args++;
19312798Swpaul				get_prog_declaration(&dec, DEF_STRUCT,
19412798Swpaul						     num_args);
195100441Scharnier				decls = XALLOC(decl_list);
19612798Swpaul				decls->decl = dec;
19712798Swpaul				*tailp = decls;
19812798Swpaul				if (streq(dec.type, "void"))
19912798Swpaul					isvoid = TRUE;
20012798Swpaul				tailp = &decls->next;
2011897Swollman			}
20212798Swpaul			/* multiple arguments are only allowed in newstyle */
20312798Swpaul			if (!newstyle && num_args > 1) {
20412798Swpaul				error("only one argument is allowed");
20512798Swpaul			}
20612798Swpaul			if (isvoid && num_args > 1) {
20712798Swpaul				error("illegal use of void in program definition");
20812798Swpaul			}
20912798Swpaul			*tailp = NULL;
2101897Swollman			scan(TOK_RPAREN, &tok);
2111897Swollman			scan(TOK_EQUAL, &tok);
2121897Swollman			scan_num(&tok);
2131897Swollman			scan(TOK_SEMICOLON, &tok);
2141897Swollman			plist->proc_num = tok.str;
21512798Swpaul			plist->arg_num = num_args;
2161897Swollman			*ptailp = plist;
2171897Swollman			ptailp = &plist->next;
2181897Swollman			peek(&tok);
2191897Swollman		} while (tok.kind != TOK_RBRACE);
2208526Sache		*ptailp = NULL;
2211897Swollman		*vtailp = vlist;
2221897Swollman		vtailp = &vlist->next;
2231897Swollman		scan(TOK_RBRACE, &tok);
2241897Swollman		scan(TOK_EQUAL, &tok);
2251897Swollman		scan_num(&tok);
2261897Swollman		vlist->vers_num = tok.str;
22712798Swpaul		/* make the argument structure name for each arg */
22812798Swpaul		for (plist = vlist->procs; plist != NULL;
22912798Swpaul		     plist = plist->next) {
23012798Swpaul			plist->args.argname = make_argname(plist->proc_name,
23112798Swpaul							   vlist->vers_num);
23212798Swpaul			/* free the memory ?? */
23312798Swpaul		}
2341897Swollman		scan(TOK_SEMICOLON, &tok);
2351897Swollman		scan2(TOK_VERSION, TOK_RBRACE, &tok);
2361897Swollman	} while (tok.kind == TOK_VERSION);
2371897Swollman	scan(TOK_EQUAL, &tok);
2381897Swollman	scan_num(&tok);
2391897Swollman	defp->def.pr.prog_num = tok.str;
2401897Swollman	*vtailp = NULL;
2411897Swollman}
2421897Swollman
24312798Swpaul
24417142Sjkhstatic void
245152398Sdwmalonedef_enum(definition *defp)
2461897Swollman{
2471897Swollman	token tok;
2481897Swollman	enumval_list *elist;
2491897Swollman	enumval_list **tailp;
2501897Swollman
2511897Swollman	defp->def_kind = DEF_ENUM;
2521897Swollman	scan(TOK_IDENT, &tok);
2531897Swollman	defp->def_name = tok.str;
2541897Swollman	scan(TOK_LBRACE, &tok);
2551897Swollman	tailp = &defp->def.en.vals;
2561897Swollman	do {
2571897Swollman		scan(TOK_IDENT, &tok);
258100441Scharnier		elist = XALLOC(enumval_list);
2591897Swollman		elist->name = tok.str;
2601897Swollman		elist->assignment = NULL;
2611897Swollman		scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
2621897Swollman		if (tok.kind == TOK_EQUAL) {
2631897Swollman			scan_num(&tok);
2641897Swollman			elist->assignment = tok.str;
2651897Swollman			scan2(TOK_COMMA, TOK_RBRACE, &tok);
2661897Swollman		}
2671897Swollman		*tailp = elist;
2681897Swollman		tailp = &elist->next;
2691897Swollman	} while (tok.kind != TOK_RBRACE);
2701897Swollman	*tailp = NULL;
2711897Swollman}
2721897Swollman
27317142Sjkhstatic void
274152398Sdwmalonedef_const(definition *defp)
2751897Swollman{
2761897Swollman	token tok;
2771897Swollman
2781897Swollman	defp->def_kind = DEF_CONST;
2791897Swollman	scan(TOK_IDENT, &tok);
2801897Swollman	defp->def_name = tok.str;
2811897Swollman	scan(TOK_EQUAL, &tok);
2821897Swollman	scan2(TOK_IDENT, TOK_STRCONST, &tok);
2831897Swollman	defp->def.co = tok.str;
2841897Swollman}
2851897Swollman
28617142Sjkhstatic void
287152398Sdwmalonedef_union(definition *defp)
2881897Swollman{
2891897Swollman	token tok;
2901897Swollman	declaration dec;
29117142Sjkh	case_list *cases;
2921897Swollman	case_list **tailp;
2931897Swollman
2941897Swollman	defp->def_kind = DEF_UNION;
2951897Swollman	scan(TOK_IDENT, &tok);
2961897Swollman	defp->def_name = tok.str;
2971897Swollman	scan(TOK_SWITCH, &tok);
2981897Swollman	scan(TOK_LPAREN, &tok);
2991897Swollman	get_declaration(&dec, DEF_UNION);
3001897Swollman	defp->def.un.enum_decl = dec;
3011897Swollman	tailp = &defp->def.un.cases;
3021897Swollman	scan(TOK_RPAREN, &tok);
3031897Swollman	scan(TOK_LBRACE, &tok);
3041897Swollman	scan(TOK_CASE, &tok);
3051897Swollman	while (tok.kind == TOK_CASE) {
30612798Swpaul		scan2(TOK_IDENT, TOK_CHARCONST, &tok);
307100441Scharnier		cases = XALLOC(case_list);
3081897Swollman		cases->case_name = tok.str;
3091897Swollman		scan(TOK_COLON, &tok);
31012798Swpaul		/* now peek at next token */
31112798Swpaul		if (peekscan(TOK_CASE, &tok)){
31212798Swpaul			do {
31312798Swpaul				scan2(TOK_IDENT, TOK_CHARCONST, &tok);
31412798Swpaul				cases->contflag = 1;
31512798Swpaul				/* continued case statement */
31612798Swpaul				*tailp = cases;
31712798Swpaul				tailp = &cases->next;
318100441Scharnier				cases = XALLOC(case_list);
31912798Swpaul				cases->case_name = tok.str;
32012798Swpaul				scan(TOK_COLON, &tok);
32112798Swpaul			} while (peekscan(TOK_CASE, &tok));
32212798Swpaul		}
32312798Swpaul
3241897Swollman		get_declaration(&dec, DEF_UNION);
3251897Swollman		cases->case_decl = dec;
32612798Swpaul		cases->contflag = 0; /* no continued case statement */
3271897Swollman		*tailp = cases;
3281897Swollman		tailp = &cases->next;
3291897Swollman		scan(TOK_SEMICOLON, &tok);
33012798Swpaul
3311897Swollman		scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
3321897Swollman	}
3331897Swollman	*tailp = NULL;
3341897Swollman	if (tok.kind == TOK_DEFAULT) {
3351897Swollman		scan(TOK_COLON, &tok);
3361897Swollman		get_declaration(&dec, DEF_UNION);
337100441Scharnier		defp->def.un.default_decl = XALLOC(declaration);
3381897Swollman		*defp->def.un.default_decl = dec;
3391897Swollman		scan(TOK_SEMICOLON, &tok);
3401897Swollman		scan(TOK_RBRACE, &tok);
3411897Swollman	} else {
3421897Swollman		defp->def.un.default_decl = NULL;
3431897Swollman	}
3441897Swollman}
3451897Swollman
346152398Sdwmalonestatic const char *reserved_words[] =
34712798Swpaul{
34812798Swpaul	"array",
34912798Swpaul	"bytes",
35012798Swpaul	"destroy",
35112798Swpaul	"free",
35212798Swpaul	"getpos",
35312798Swpaul	"inline",
35412798Swpaul	"pointer",
35512798Swpaul	"reference",
35612798Swpaul	"setpos",
35712798Swpaul	"sizeof",
35812798Swpaul	"union",
35912798Swpaul	"vector",
36012798Swpaul	NULL
36112798Swpaul	};
3621897Swollman
363152398Sdwmalonestatic const char *reserved_types[] =
36412798Swpaul{
36512798Swpaul	"opaque",
36612798Swpaul	"string",
36712798Swpaul	NULL
36812798Swpaul	};
36912798Swpaul
37012798Swpaul/*
37112798Swpaul * check that the given name is not one that would eventually result in
37212798Swpaul * xdr routines that would conflict with internal XDR routines.
37312798Swpaul */
37417142Sjkhstatic void
375152398Sdwmalonecheck_type_name(const char *name, int new_type)
37612798Swpaul{
37712798Swpaul	int i;
37812798Swpaul	char tmp[100];
37912798Swpaul
38012798Swpaul	for (i = 0; reserved_words[i] != NULL; i++) {
38112798Swpaul		if (strcmp(name, reserved_words[i]) == 0) {
38212798Swpaul			sprintf(tmp,
38312798Swpaul				"illegal (reserved) name :\'%s\' in type definition",
38412798Swpaul				name);
38512798Swpaul			error(tmp);
38612798Swpaul		}
38712798Swpaul	}
38812798Swpaul	if (new_type) {
38912798Swpaul		for (i = 0; reserved_types[i] != NULL; i++) {
39012798Swpaul			if (strcmp(name, reserved_types[i]) == 0) {
39112798Swpaul				sprintf(tmp,
39212798Swpaul					"illegal (reserved) name :\'%s\' in type definition",
39312798Swpaul					name);
39412798Swpaul				error(tmp);
39512798Swpaul			}
39612798Swpaul		}
39712798Swpaul	}
39812798Swpaul}
39912798Swpaul
40012798Swpaul
40112798Swpaul
40217142Sjkhstatic void
403152398Sdwmalonedef_typedef(definition *defp)
4041897Swollman{
4051897Swollman	declaration dec;
4061897Swollman
4071897Swollman	defp->def_kind = DEF_TYPEDEF;
4081897Swollman	get_declaration(&dec, DEF_TYPEDEF);
4091897Swollman	defp->def_name = dec.name;
41012798Swpaul	check_type_name(dec.name, 1);
4111897Swollman	defp->def.ty.old_prefix = dec.prefix;
4121897Swollman	defp->def.ty.old_type = dec.type;
4131897Swollman	defp->def.ty.rel = dec.rel;
4141897Swollman	defp->def.ty.array_max = dec.array_max;
4151897Swollman}
4161897Swollman
41717142Sjkhstatic void
418152398Sdwmaloneget_declaration(declaration *dec, defkind dkind)
4191897Swollman{
4201897Swollman	token tok;
4211897Swollman
4221897Swollman	get_type(&dec->prefix, &dec->type, dkind);
4231897Swollman	dec->rel = REL_ALIAS;
4241897Swollman	if (streq(dec->type, "void")) {
4251897Swollman		return;
4261897Swollman	}
42712798Swpaul
42812798Swpaul	check_type_name(dec->type, 0);
4291897Swollman	scan2(TOK_STAR, TOK_IDENT, &tok);
4301897Swollman	if (tok.kind == TOK_STAR) {
4311897Swollman		dec->rel = REL_POINTER;
4321897Swollman		scan(TOK_IDENT, &tok);
4331897Swollman	}
4341897Swollman	dec->name = tok.str;
4351897Swollman	if (peekscan(TOK_LBRACKET, &tok)) {
4361897Swollman		if (dec->rel == REL_POINTER) {
4371897Swollman			error("no array-of-pointer declarations -- use typedef");
4381897Swollman		}
4391897Swollman		dec->rel = REL_VECTOR;
4401897Swollman		scan_num(&tok);
4411897Swollman		dec->array_max = tok.str;
4421897Swollman		scan(TOK_RBRACKET, &tok);
4431897Swollman	} else if (peekscan(TOK_LANGLE, &tok)) {
4441897Swollman		if (dec->rel == REL_POINTER) {
4451897Swollman			error("no array-of-pointer declarations -- use typedef");
4461897Swollman		}
4471897Swollman		dec->rel = REL_ARRAY;
4481897Swollman		if (peekscan(TOK_RANGLE, &tok)) {
4491897Swollman			dec->array_max = "~0";	/* unspecified size, use max */
4501897Swollman		} else {
4511897Swollman			scan_num(&tok);
4521897Swollman			dec->array_max = tok.str;
4531897Swollman			scan(TOK_RANGLE, &tok);
4541897Swollman		}
4551897Swollman	}
4561897Swollman	if (streq(dec->type, "opaque")) {
4571897Swollman		if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
4581897Swollman			error("array declaration expected");
4591897Swollman		}
4601897Swollman	} else if (streq(dec->type, "string")) {
4611897Swollman		if (dec->rel != REL_ARRAY) {
4621897Swollman			error("variable-length array declaration expected");
4631897Swollman		}
4641897Swollman	}
4651897Swollman}
4661897Swollman
4671897Swollman
46817142Sjkhstatic void
469152398Sdwmaloneget_prog_declaration(declaration *dec, defkind dkind, int num)
47012798Swpaul{
47112798Swpaul	token tok;
47212798Swpaul	char name[10];		/* argument name */
47312798Swpaul
47412798Swpaul	if (dkind == DEF_PROGRAM) {
47512798Swpaul		peek(&tok);
47612798Swpaul		if (tok.kind == TOK_RPAREN) { /* no arguments */
47712798Swpaul			dec->rel = REL_ALIAS;
47812798Swpaul			dec->type = "void";
47912798Swpaul			dec->prefix = NULL;
48012798Swpaul			dec->name = NULL;
48112798Swpaul			return;
48212798Swpaul		}
48312798Swpaul	}
48412798Swpaul	get_type(&dec->prefix, &dec->type, dkind);
48512798Swpaul	dec->rel = REL_ALIAS;
48612798Swpaul	if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
48712798Swpaul		strcpy(name, tok.str);
48812798Swpaul	else
48912798Swpaul		sprintf(name, "%s%d", ARGNAME, num);
49012798Swpaul	/* default name of argument */
49112798Swpaul
492100441Scharnier	dec->name = (char *) xstrdup(name);
49312798Swpaul	if (streq(dec->type, "void")) {
49412798Swpaul		return;
49512798Swpaul	}
49612798Swpaul
49712798Swpaul	if (streq(dec->type, "opaque")) {
49812798Swpaul		error("opaque -- illegal argument type");
49912798Swpaul	}
50012798Swpaul	if (peekscan(TOK_STAR, &tok)) {
50112798Swpaul		if (streq(dec->type, "string")) {
502100441Scharnier			error("pointer to string not allowed in program arguments");
50312798Swpaul		}
50412798Swpaul		dec->rel = REL_POINTER;
505100441Scharnier		if (peekscan(TOK_IDENT, &tok)) {
50612798Swpaul			/* optional name of argument */
507100441Scharnier			dec->name = xstrdup(tok.str);
508100441Scharnier		}
50912798Swpaul	}
51012798Swpaul	if (peekscan(TOK_LANGLE, &tok)) {
51112798Swpaul		if (!streq(dec->type, "string")) {
51212798Swpaul			error("arrays cannot be declared as arguments to procedures -- use typedef");
51312798Swpaul		}
51412798Swpaul		dec->rel = REL_ARRAY;
51512798Swpaul		if (peekscan(TOK_RANGLE, &tok)) {
51612798Swpaul			dec->array_max = "~0";
51712798Swpaul			/* unspecified size, use max */
51812798Swpaul		} else {
51912798Swpaul			scan_num(&tok);
52012798Swpaul			dec->array_max = tok.str;
52112798Swpaul			scan(TOK_RANGLE, &tok);
52212798Swpaul		}
52312798Swpaul	}
52412798Swpaul	if (streq(dec->type, "string")) {
52512798Swpaul		if (dec->rel != REL_ARRAY) {
52612798Swpaul			/*
52712798Swpaul			 * .x specifies just string as
52812798Swpaul			 * type of argument
52912798Swpaul			 * - make it string<>
53012798Swpaul			 */
53112798Swpaul			dec->rel = REL_ARRAY;
53212798Swpaul			dec->array_max = "~0"; /* unspecified size, use max */
53312798Swpaul		}
53412798Swpaul	}
53512798Swpaul}
53612798Swpaul
53712798Swpaul
53812798Swpaul
53917142Sjkhstatic void
540152398Sdwmaloneget_type(const char **prefixp, const char **typep, defkind dkind)
5411897Swollman{
5421897Swollman	token tok;
5431897Swollman
5441897Swollman	*prefixp = NULL;
5451897Swollman	get_token(&tok);
5461897Swollman	switch (tok.kind) {
5471897Swollman	case TOK_IDENT:
5481897Swollman		*typep = tok.str;
5491897Swollman		break;
5501897Swollman	case TOK_STRUCT:
5511897Swollman	case TOK_ENUM:
5521897Swollman	case TOK_UNION:
5531897Swollman		*prefixp = tok.str;
5541897Swollman		scan(TOK_IDENT, &tok);
5551897Swollman		*typep = tok.str;
5561897Swollman		break;
5571897Swollman	case TOK_UNSIGNED:
5581897Swollman		unsigned_dec(typep);
5591897Swollman		break;
5601897Swollman	case TOK_SHORT:
5611897Swollman		*typep = "short";
5621897Swollman		(void) peekscan(TOK_INT, &tok);
5631897Swollman		break;
5641897Swollman	case TOK_LONG:
5651897Swollman		*typep = "long";
5661897Swollman		(void) peekscan(TOK_INT, &tok);
5671897Swollman		break;
56812798Swpaul	case TOK_HYPER:
56938952Sobrien		*typep = "int64_t";
57012798Swpaul		(void) peekscan(TOK_INT, &tok);
57112798Swpaul		break;
57212798Swpaul
5731897Swollman	case TOK_VOID:
5741897Swollman		if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
57512798Swpaul			error("voids allowed only inside union and program definitions with one argument");
5761897Swollman		}
5771897Swollman		*typep = tok.str;
5781897Swollman		break;
5791897Swollman	case TOK_STRING:
5801897Swollman	case TOK_OPAQUE:
5811897Swollman	case TOK_CHAR:
5821897Swollman	case TOK_INT:
5831897Swollman	case TOK_FLOAT:
5841897Swollman	case TOK_DOUBLE:
5851897Swollman	case TOK_BOOL:
58612798Swpaul	case TOK_QUAD:
5871897Swollman		*typep = tok.str;
5881897Swollman		break;
5891897Swollman	default:
5901897Swollman		error("expected type specifier");
5911897Swollman	}
5921897Swollman}
5931897Swollman
59417142Sjkhstatic void
595152398Sdwmaloneunsigned_dec(const char **typep)
5961897Swollman{
5971897Swollman	token tok;
5981897Swollman
5991897Swollman	peek(&tok);
6001897Swollman	switch (tok.kind) {
6011897Swollman	case TOK_CHAR:
6021897Swollman		get_token(&tok);
6031897Swollman		*typep = "u_char";
6041897Swollman		break;
6051897Swollman	case TOK_SHORT:
6061897Swollman		get_token(&tok);
6071897Swollman		*typep = "u_short";
6081897Swollman		(void) peekscan(TOK_INT, &tok);
6091897Swollman		break;
6101897Swollman	case TOK_LONG:
6111897Swollman		get_token(&tok);
6121897Swollman		*typep = "u_long";
6131897Swollman		(void) peekscan(TOK_INT, &tok);
6141897Swollman		break;
61512798Swpaul	case TOK_HYPER:
61612798Swpaul		get_token(&tok);
61738952Sobrien		*typep = "u_int64_t";
61874462Salfred
61912798Swpaul		(void) peekscan(TOK_INT, &tok);
62012798Swpaul		break;
6211897Swollman	case TOK_INT:
6221897Swollman		get_token(&tok);
6231897Swollman		*typep = "u_int";
6241897Swollman		break;
6251897Swollman	default:
6261897Swollman		*typep = "u_int";
6271897Swollman		break;
6281897Swollman	}
6291897Swollman}
630