Home | History | Annotate | Line # | Download | only in rpcgen
rpc_parse.c revision 1.16.12.1
      1  1.16.12.1       tls /*	$NetBSD: rpc_parse.c,v 1.16.12.1 2014/08/20 00:05:03 tls Exp $	*/
      2        1.1     glass /*
      3        1.1     glass  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
      4        1.1     glass  * unrestricted use provided that this legend is included on all tape
      5        1.1     glass  * media and as a part of the software program in whole or part.  Users
      6        1.1     glass  * may copy or modify Sun RPC without charge, but are not authorized
      7        1.1     glass  * to license or distribute it to anyone else except as part of a product or
      8        1.4        pk  * program developed by the user or with the express written consent of
      9        1.4        pk  * Sun Microsystems, Inc.
     10        1.4        pk  *
     11        1.1     glass  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
     12        1.1     glass  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
     13        1.1     glass  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
     14        1.4        pk  *
     15        1.1     glass  * Sun RPC is provided with no support and without any obligation on the
     16        1.1     glass  * part of Sun Microsystems, Inc. to assist in its use, correction,
     17        1.1     glass  * modification or enhancement.
     18        1.4        pk  *
     19        1.1     glass  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
     20        1.1     glass  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
     21        1.1     glass  * OR ANY PART THEREOF.
     22        1.4        pk  *
     23        1.1     glass  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
     24        1.1     glass  * or profits or other special, indirect and consequential damages, even if
     25        1.1     glass  * Sun has been advised of the possibility of such damages.
     26        1.4        pk  *
     27        1.1     glass  * Sun Microsystems, Inc.
     28        1.1     glass  * 2550 Garcia Avenue
     29        1.1     glass  * Mountain View, California  94043
     30        1.1     glass  */
     31        1.4        pk 
     32       1.13       jmc #if HAVE_NBTOOL_CONFIG_H
     33       1.13       jmc #include "nbtool_config.h"
     34       1.13       jmc #endif
     35       1.13       jmc 
     36        1.6  christos #include <sys/cdefs.h>
     37       1.11        tv #if defined(__RCSID) && !defined(lint)
     38        1.6  christos #if 0
     39        1.4        pk static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
     40        1.6  christos #else
     41  1.16.12.1       tls __RCSID("$NetBSD: rpc_parse.c,v 1.16.12.1 2014/08/20 00:05:03 tls Exp $");
     42        1.6  christos #endif
     43        1.1     glass #endif
     44        1.1     glass 
     45        1.1     glass /*
     46        1.7     lukem  * rpc_parse.c, Parser for the RPC protocol compiler
     47        1.1     glass  * Copyright (C) 1987 Sun Microsystems, Inc.
     48        1.1     glass  */
     49        1.1     glass #include <stdio.h>
     50        1.5       cgd #include <stdlib.h>
     51        1.5       cgd #include <string.h>
     52        1.4        pk #include "rpc/types.h"
     53        1.1     glass #include "rpc_scan.h"
     54        1.1     glass #include "rpc_parse.h"
     55        1.4        pk #include "rpc_util.h"
     56        1.4        pk 
     57        1.4        pk #define ARGNAME "arg"
     58        1.4        pk 
     59  1.16.12.1       tls static void isdefined(definition *);
     60  1.16.12.1       tls static void def_struct(definition *);
     61  1.16.12.1       tls static void def_program(definition *);
     62  1.16.12.1       tls static void def_enum(definition *);
     63  1.16.12.1       tls static void def_const(definition *);
     64  1.16.12.1       tls static void def_union(definition *);
     65  1.16.12.1       tls static void check_type_name(const char *, int);
     66  1.16.12.1       tls static void def_typedef(definition *);
     67  1.16.12.1       tls static void get_declaration(declaration *, defkind);
     68  1.16.12.1       tls static void get_prog_declaration(declaration *, defkind, int);
     69  1.16.12.1       tls static void get_type(const char **, const char **, defkind);
     70  1.16.12.1       tls static void unsigned_dec(const char **);
     71        1.1     glass 
     72        1.1     glass /*
     73        1.1     glass  * return the next definition you see
     74        1.1     glass  */
     75        1.1     glass definition *
     76  1.16.12.1       tls get_definition(void)
     77        1.1     glass {
     78        1.1     glass 	definition *defp;
     79        1.7     lukem 	token   tok;
     80        1.1     glass 
     81        1.1     glass 	defp = ALLOC(definition);
     82        1.1     glass 	get_token(&tok);
     83        1.1     glass 	switch (tok.kind) {
     84        1.1     glass 	case TOK_STRUCT:
     85        1.1     glass 		def_struct(defp);
     86        1.1     glass 		break;
     87        1.1     glass 	case TOK_UNION:
     88        1.1     glass 		def_union(defp);
     89        1.1     glass 		break;
     90        1.1     glass 	case TOK_TYPEDEF:
     91        1.1     glass 		def_typedef(defp);
     92        1.1     glass 		break;
     93        1.1     glass 	case TOK_ENUM:
     94        1.1     glass 		def_enum(defp);
     95        1.1     glass 		break;
     96        1.1     glass 	case TOK_PROGRAM:
     97        1.1     glass 		def_program(defp);
     98        1.1     glass 		break;
     99        1.1     glass 	case TOK_CONST:
    100        1.1     glass 		def_const(defp);
    101        1.1     glass 		break;
    102        1.1     glass 	case TOK_EOF:
    103       1.14      elad 		free(defp);
    104        1.1     glass 		return (NULL);
    105        1.1     glass 	default:
    106        1.1     glass 		error("definition keyword expected");
    107        1.1     glass 	}
    108        1.1     glass 	scan(TOK_SEMICOLON, &tok);
    109        1.1     glass 	isdefined(defp);
    110        1.1     glass 	return (defp);
    111        1.1     glass }
    112        1.1     glass 
    113        1.6  christos static void
    114  1.16.12.1       tls isdefined(definition *defp)
    115        1.1     glass {
    116        1.1     glass 	STOREVAL(&defined, defp);
    117        1.1     glass }
    118        1.1     glass 
    119        1.6  christos static void
    120  1.16.12.1       tls def_struct(definition *defp)
    121        1.1     glass {
    122        1.7     lukem 	token   tok;
    123        1.1     glass 	declaration dec;
    124        1.1     glass 	decl_list *decls;
    125        1.1     glass 	decl_list **tailp;
    126        1.1     glass 
    127        1.1     glass 	defp->def_kind = DEF_STRUCT;
    128        1.1     glass 
    129        1.1     glass 	scan(TOK_IDENT, &tok);
    130        1.1     glass 	defp->def_name = tok.str;
    131        1.1     glass 	scan(TOK_LBRACE, &tok);
    132        1.1     glass 	tailp = &defp->def.st.decls;
    133        1.1     glass 	do {
    134        1.1     glass 		get_declaration(&dec, DEF_STRUCT);
    135        1.1     glass 		decls = ALLOC(decl_list);
    136        1.1     glass 		decls->decl = dec;
    137        1.1     glass 		*tailp = decls;
    138        1.1     glass 		tailp = &decls->next;
    139        1.1     glass 		scan(TOK_SEMICOLON, &tok);
    140        1.1     glass 		peek(&tok);
    141        1.1     glass 	} while (tok.kind != TOK_RBRACE);
    142        1.1     glass 	get_token(&tok);
    143        1.1     glass 	*tailp = NULL;
    144        1.1     glass }
    145        1.1     glass 
    146        1.6  christos static void
    147  1.16.12.1       tls def_program(definition *defp)
    148        1.1     glass {
    149        1.7     lukem 	token   tok;
    150        1.4        pk 	declaration dec;
    151        1.4        pk 	decl_list *decls;
    152        1.4        pk 	decl_list **tailp;
    153        1.1     glass 	version_list *vlist;
    154        1.1     glass 	version_list **vtailp;
    155        1.1     glass 	proc_list *plist;
    156        1.1     glass 	proc_list **ptailp;
    157        1.7     lukem 	int     num_args;
    158        1.7     lukem 	bool_t  isvoid = FALSE;	/* whether first argument is void */
    159        1.1     glass 	defp->def_kind = DEF_PROGRAM;
    160        1.1     glass 	scan(TOK_IDENT, &tok);
    161        1.1     glass 	defp->def_name = tok.str;
    162        1.1     glass 	scan(TOK_LBRACE, &tok);
    163        1.1     glass 	vtailp = &defp->def.pr.versions;
    164        1.4        pk 	tailp = &defp->def.st.decls;
    165        1.1     glass 	scan(TOK_VERSION, &tok);
    166        1.1     glass 	do {
    167        1.1     glass 		scan(TOK_IDENT, &tok);
    168        1.1     glass 		vlist = ALLOC(version_list);
    169        1.1     glass 		vlist->vers_name = tok.str;
    170        1.1     glass 		scan(TOK_LBRACE, &tok);
    171        1.1     glass 		ptailp = &vlist->procs;
    172        1.1     glass 		do {
    173        1.4        pk 			/* get result type */
    174        1.1     glass 			plist = ALLOC(proc_list);
    175        1.7     lukem 			get_type(&plist->res_prefix, &plist->res_type,
    176        1.7     lukem 			    DEF_PROGRAM);
    177        1.1     glass 			if (streq(plist->res_type, "opaque")) {
    178        1.1     glass 				error("illegal result type");
    179        1.1     glass 			}
    180        1.1     glass 			scan(TOK_IDENT, &tok);
    181        1.1     glass 			plist->proc_name = tok.str;
    182        1.1     glass 			scan(TOK_LPAREN, &tok);
    183        1.7     lukem 			/* get args - first one */
    184        1.4        pk 			num_args = 1;
    185        1.4        pk 			isvoid = FALSE;
    186        1.7     lukem 			/* type of DEF_PROGRAM in the first
    187        1.4        pk 			 * get_prog_declaration and DEF_STURCT in the next
    188        1.7     lukem 			 * allows void as argument if it is the only argument */
    189        1.4        pk 			get_prog_declaration(&dec, DEF_PROGRAM, num_args);
    190        1.4        pk 			if (streq(dec.type, "void"))
    191        1.7     lukem 				isvoid = TRUE;
    192        1.4        pk 			decls = ALLOC(decl_list);
    193        1.4        pk 			plist->args.decls = decls;
    194        1.4        pk 			decls->decl = dec;
    195        1.4        pk 			tailp = &decls->next;
    196        1.4        pk 			/* get args */
    197        1.7     lukem 			while (peekscan(TOK_COMMA, &tok)) {
    198        1.7     lukem 				num_args++;
    199        1.7     lukem 				get_prog_declaration(&dec, DEF_STRUCT,
    200        1.7     lukem 				    num_args);
    201        1.7     lukem 				decls = ALLOC(decl_list);
    202        1.7     lukem 				decls->decl = dec;
    203        1.7     lukem 				*tailp = decls;
    204        1.7     lukem 				if (streq(dec.type, "void"))
    205        1.7     lukem 					isvoid = TRUE;
    206        1.7     lukem 				tailp = &decls->next;
    207        1.1     glass 			}
    208        1.4        pk 			/* multiple arguments are only allowed in newstyle */
    209        1.7     lukem 			if (!newstyle && num_args > 1) {
    210        1.7     lukem 				error("only one argument is allowed");
    211        1.4        pk 			}
    212        1.7     lukem 			if (isvoid && num_args > 1) {
    213        1.7     lukem 				error("illegal use of void in program definition");
    214        1.4        pk 			}
    215        1.4        pk 			*tailp = NULL;
    216        1.1     glass 			scan(TOK_RPAREN, &tok);
    217        1.1     glass 			scan(TOK_EQUAL, &tok);
    218        1.1     glass 			scan_num(&tok);
    219        1.1     glass 			scan(TOK_SEMICOLON, &tok);
    220        1.1     glass 			plist->proc_num = tok.str;
    221        1.4        pk 			plist->arg_num = num_args;
    222        1.1     glass 			*ptailp = plist;
    223        1.1     glass 			ptailp = &plist->next;
    224        1.1     glass 			peek(&tok);
    225        1.1     glass 		} while (tok.kind != TOK_RBRACE);
    226        1.4        pk 		*ptailp = NULL;
    227        1.1     glass 		*vtailp = vlist;
    228        1.1     glass 		vtailp = &vlist->next;
    229        1.1     glass 		scan(TOK_RBRACE, &tok);
    230        1.1     glass 		scan(TOK_EQUAL, &tok);
    231        1.1     glass 		scan_num(&tok);
    232        1.1     glass 		vlist->vers_num = tok.str;
    233        1.7     lukem 		/* make the argument structure name for each arg */
    234        1.7     lukem 		for (plist = vlist->procs; plist != NULL;
    235        1.4        pk 		    plist = plist->next) {
    236        1.4        pk 			plist->args.argname = make_argname(plist->proc_name,
    237        1.7     lukem 			    vlist->vers_num);
    238        1.7     lukem 			/* free the memory ?? */
    239        1.4        pk 		}
    240        1.1     glass 		scan(TOK_SEMICOLON, &tok);
    241        1.1     glass 		scan2(TOK_VERSION, TOK_RBRACE, &tok);
    242        1.1     glass 	} while (tok.kind == TOK_VERSION);
    243        1.1     glass 	scan(TOK_EQUAL, &tok);
    244        1.1     glass 	scan_num(&tok);
    245        1.1     glass 	defp->def.pr.prog_num = tok.str;
    246        1.1     glass 	*vtailp = NULL;
    247        1.1     glass }
    248        1.1     glass 
    249        1.4        pk 
    250        1.6  christos static void
    251  1.16.12.1       tls def_enum(definition *defp)
    252        1.1     glass {
    253        1.7     lukem 	token   tok;
    254        1.1     glass 	enumval_list *elist;
    255        1.1     glass 	enumval_list **tailp;
    256        1.1     glass 
    257        1.1     glass 	defp->def_kind = DEF_ENUM;
    258        1.1     glass 	scan(TOK_IDENT, &tok);
    259        1.1     glass 	defp->def_name = tok.str;
    260        1.1     glass 	scan(TOK_LBRACE, &tok);
    261        1.1     glass 	tailp = &defp->def.en.vals;
    262        1.1     glass 	do {
    263        1.1     glass 		scan(TOK_IDENT, &tok);
    264        1.1     glass 		elist = ALLOC(enumval_list);
    265        1.1     glass 		elist->name = tok.str;
    266        1.1     glass 		elist->assignment = NULL;
    267        1.1     glass 		scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
    268        1.1     glass 		if (tok.kind == TOK_EQUAL) {
    269        1.1     glass 			scan_num(&tok);
    270        1.1     glass 			elist->assignment = tok.str;
    271        1.1     glass 			scan2(TOK_COMMA, TOK_RBRACE, &tok);
    272        1.1     glass 		}
    273        1.1     glass 		*tailp = elist;
    274        1.1     glass 		tailp = &elist->next;
    275        1.1     glass 	} while (tok.kind != TOK_RBRACE);
    276        1.1     glass 	*tailp = NULL;
    277        1.1     glass }
    278        1.1     glass 
    279        1.6  christos static void
    280  1.16.12.1       tls def_const(definition *defp)
    281        1.1     glass {
    282        1.7     lukem 	token   tok;
    283        1.1     glass 
    284        1.1     glass 	defp->def_kind = DEF_CONST;
    285        1.1     glass 	scan(TOK_IDENT, &tok);
    286        1.1     glass 	defp->def_name = tok.str;
    287        1.1     glass 	scan(TOK_EQUAL, &tok);
    288        1.1     glass 	scan2(TOK_IDENT, TOK_STRCONST, &tok);
    289        1.1     glass 	defp->def.co = tok.str;
    290        1.1     glass }
    291        1.1     glass 
    292        1.6  christos static void
    293  1.16.12.1       tls def_union(definition *defp)
    294        1.1     glass {
    295        1.7     lukem 	token   tok;
    296        1.7     lukem 	declaration dec;
    297        1.7     lukem 	case_list *cases;
    298        1.7     lukem 	case_list **tailp;
    299        1.7     lukem 
    300        1.7     lukem 	defp->def_kind = DEF_UNION;
    301        1.7     lukem 	scan(TOK_IDENT, &tok);
    302        1.7     lukem 	defp->def_name = tok.str;
    303        1.7     lukem 	scan(TOK_SWITCH, &tok);
    304        1.7     lukem 	scan(TOK_LPAREN, &tok);
    305        1.7     lukem 	get_declaration(&dec, DEF_UNION);
    306        1.7     lukem 	defp->def.un.enum_decl = dec;
    307        1.7     lukem 	tailp = &defp->def.un.cases;
    308        1.7     lukem 	scan(TOK_RPAREN, &tok);
    309        1.7     lukem 	scan(TOK_LBRACE, &tok);
    310        1.7     lukem 	scan(TOK_CASE, &tok);
    311        1.7     lukem 	while (tok.kind == TOK_CASE) {
    312        1.7     lukem 		scan2(TOK_IDENT, TOK_CHARCONST, &tok);
    313        1.7     lukem 		cases = ALLOC(case_list);
    314        1.7     lukem 		cases->case_name = tok.str;
    315        1.7     lukem 		scan(TOK_COLON, &tok);
    316        1.7     lukem 		/* now peek at next token */
    317        1.7     lukem 		if (peekscan(TOK_CASE, &tok)) {
    318        1.7     lukem 
    319        1.7     lukem 			do {
    320        1.7     lukem 				scan2(TOK_IDENT, TOK_CHARCONST, &tok);
    321        1.7     lukem 				cases->contflag = 1;	/* continued case
    322        1.7     lukem 							 * statement */
    323        1.7     lukem 				*tailp = cases;
    324        1.7     lukem 				tailp = &cases->next;
    325        1.7     lukem 				cases = ALLOC(case_list);
    326        1.7     lukem 				cases->case_name = tok.str;
    327        1.7     lukem 				scan(TOK_COLON, &tok);
    328        1.7     lukem 
    329        1.7     lukem 			} while (peekscan(TOK_CASE, &tok));
    330       1.15  christos 		}
    331        1.7     lukem 		get_declaration(&dec, DEF_UNION);
    332        1.7     lukem 		cases->case_decl = dec;
    333        1.7     lukem 		cases->contflag = 0;	/* no continued case statement */
    334        1.7     lukem 		*tailp = cases;
    335        1.7     lukem 		tailp = &cases->next;
    336        1.7     lukem 		scan(TOK_SEMICOLON, &tok);
    337        1.7     lukem 
    338        1.7     lukem 		scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
    339        1.7     lukem 	}
    340        1.7     lukem 	*tailp = NULL;
    341        1.7     lukem 	if (tok.kind == TOK_DEFAULT) {
    342        1.7     lukem 		scan(TOK_COLON, &tok);
    343        1.7     lukem 		get_declaration(&dec, DEF_UNION);
    344        1.7     lukem 		defp->def.un.default_decl = ALLOC(declaration);
    345        1.7     lukem 		*defp->def.un.default_decl = dec;
    346        1.7     lukem 		scan(TOK_SEMICOLON, &tok);
    347        1.7     lukem 		scan(TOK_RBRACE, &tok);
    348        1.7     lukem 	} else {
    349        1.7     lukem 		defp->def.un.default_decl = NULL;
    350        1.7     lukem 	}
    351        1.4        pk }
    352        1.4        pk 
    353  1.16.12.1       tls static const char *const reserved_words[] = {
    354        1.4        pk 	"array",
    355        1.4        pk 	"bytes",
    356        1.4        pk 	"destroy",
    357        1.4        pk 	"free",
    358        1.4        pk 	"getpos",
    359        1.4        pk 	"inline",
    360        1.4        pk 	"pointer",
    361        1.4        pk 	"reference",
    362        1.4        pk 	"setpos",
    363        1.4        pk 	"sizeof",
    364        1.4        pk 	"union",
    365        1.4        pk 	"vector",
    366        1.4        pk 	NULL
    367        1.4        pk };
    368        1.4        pk 
    369  1.16.12.1       tls static const char *const reserved_types[] = {
    370        1.4        pk 	"opaque",
    371        1.4        pk 	"string",
    372        1.4        pk 	NULL
    373        1.4        pk };
    374        1.4        pk /* check that the given name is not one that would eventually result in
    375        1.4        pk    xdr routines that would conflict with internal XDR routines. */
    376        1.6  christos static void
    377  1.16.12.1       tls check_type_name(const char *name, int new_type)
    378        1.7     lukem {
    379        1.7     lukem 	int     i;
    380        1.7     lukem 	char    tmp[100];
    381        1.7     lukem 
    382        1.7     lukem 	for (i = 0; reserved_words[i] != NULL; i++) {
    383        1.7     lukem 		if (strcmp(name, reserved_words[i]) == 0) {
    384        1.7     lukem 			sprintf(tmp,
    385        1.7     lukem 			    "illegal (reserved) name :\'%s\' in type definition", name);
    386        1.7     lukem 			error(tmp);
    387        1.7     lukem 		}
    388        1.7     lukem 	}
    389        1.7     lukem 	if (new_type) {
    390        1.7     lukem 		for (i = 0; reserved_types[i] != NULL; i++) {
    391        1.7     lukem 			if (strcmp(name, reserved_types[i]) == 0) {
    392        1.7     lukem 				sprintf(tmp,
    393        1.7     lukem 				    "illegal (reserved) name :\'%s\' in type definition", name);
    394        1.7     lukem 				error(tmp);
    395        1.7     lukem 			}
    396        1.7     lukem 		}
    397        1.7     lukem 	}
    398        1.1     glass }
    399        1.1     glass 
    400        1.6  christos static void
    401  1.16.12.1       tls def_typedef(definition *defp)
    402        1.1     glass {
    403        1.1     glass 	declaration dec;
    404        1.1     glass 
    405        1.1     glass 	defp->def_kind = DEF_TYPEDEF;
    406        1.1     glass 	get_declaration(&dec, DEF_TYPEDEF);
    407        1.1     glass 	defp->def_name = dec.name;
    408        1.7     lukem 	check_type_name(dec.name, 1);
    409        1.1     glass 	defp->def.ty.old_prefix = dec.prefix;
    410        1.1     glass 	defp->def.ty.old_type = dec.type;
    411        1.1     glass 	defp->def.ty.rel = dec.rel;
    412        1.1     glass 	defp->def.ty.array_max = dec.array_max;
    413        1.1     glass }
    414        1.1     glass 
    415        1.6  christos static void
    416  1.16.12.1       tls get_declaration(declaration *dec, defkind dkind)
    417        1.1     glass {
    418        1.7     lukem 	token   tok;
    419        1.1     glass 
    420        1.1     glass 	get_type(&dec->prefix, &dec->type, dkind);
    421        1.1     glass 	dec->rel = REL_ALIAS;
    422        1.1     glass 	if (streq(dec->type, "void")) {
    423        1.1     glass 		return;
    424        1.1     glass 	}
    425        1.7     lukem 	check_type_name(dec->type, 0);
    426        1.4        pk 
    427        1.1     glass 	scan2(TOK_STAR, TOK_IDENT, &tok);
    428        1.1     glass 	if (tok.kind == TOK_STAR) {
    429        1.1     glass 		dec->rel = REL_POINTER;
    430        1.1     glass 		scan(TOK_IDENT, &tok);
    431        1.1     glass 	}
    432        1.1     glass 	dec->name = tok.str;
    433        1.1     glass 	if (peekscan(TOK_LBRACKET, &tok)) {
    434        1.1     glass 		if (dec->rel == REL_POINTER) {
    435        1.1     glass 			error("no array-of-pointer declarations -- use typedef");
    436        1.1     glass 		}
    437        1.1     glass 		dec->rel = REL_VECTOR;
    438        1.1     glass 		scan_num(&tok);
    439        1.1     glass 		dec->array_max = tok.str;
    440        1.1     glass 		scan(TOK_RBRACKET, &tok);
    441        1.7     lukem 	} else
    442        1.7     lukem 		if (peekscan(TOK_LANGLE, &tok)) {
    443        1.7     lukem 			if (dec->rel == REL_POINTER) {
    444        1.7     lukem 				error("no array-of-pointer declarations -- use typedef");
    445        1.7     lukem 			}
    446        1.7     lukem 			dec->rel = REL_ARRAY;
    447        1.7     lukem 			if (peekscan(TOK_RANGLE, &tok)) {
    448       1.12  christos 				dec->array_max = "(u_int)~0";
    449       1.12  christos 				/* unspecified size, use * max */
    450        1.7     lukem 			} else {
    451        1.7     lukem 				scan_num(&tok);
    452        1.7     lukem 				dec->array_max = tok.str;
    453        1.7     lukem 				scan(TOK_RANGLE, &tok);
    454        1.7     lukem 			}
    455        1.1     glass 		}
    456        1.1     glass 	if (streq(dec->type, "opaque")) {
    457        1.1     glass 		if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
    458        1.1     glass 			error("array declaration expected");
    459        1.1     glass 		}
    460        1.7     lukem 	} else
    461        1.7     lukem 		if (streq(dec->type, "string")) {
    462        1.7     lukem 			if (dec->rel != REL_ARRAY) {
    463        1.7     lukem 				error("variable-length array declaration expected");
    464        1.7     lukem 			}
    465        1.1     glass 		}
    466        1.1     glass }
    467        1.1     glass 
    468        1.6  christos static void
    469  1.16.12.1       tls get_prog_declaration(declaration *dec, defkind dkind, int num /* arg number */)
    470        1.4        pk {
    471        1.7     lukem 	token   tok;
    472       1.10    bouyer 	char    name[255];	/* argument name */
    473        1.4        pk 
    474        1.7     lukem 	if (dkind == DEF_PROGRAM) {
    475        1.7     lukem 		peek(&tok);
    476        1.7     lukem 		if (tok.kind == TOK_RPAREN) {	/* no arguments */
    477        1.7     lukem 			dec->rel = REL_ALIAS;
    478        1.7     lukem 			dec->type = "void";
    479        1.7     lukem 			dec->prefix = NULL;
    480        1.7     lukem 			dec->name = NULL;
    481        1.7     lukem 			return;
    482        1.7     lukem 		}
    483        1.4        pk 	}
    484        1.4        pk 	get_type(&dec->prefix, &dec->type, dkind);
    485        1.4        pk 	dec->rel = REL_ALIAS;
    486        1.7     lukem 	if (peekscan(TOK_IDENT, &tok))	/* optional name of argument */
    487        1.4        pk 		strcpy(name, tok.str);
    488        1.7     lukem 	else
    489        1.7     lukem 		sprintf(name, "%s%d", ARGNAME, num);	/* default name of
    490        1.7     lukem 							 * argument */
    491        1.7     lukem 
    492        1.7     lukem 	dec->name = (char *) strdup(name);
    493        1.4        pk 
    494        1.4        pk 	if (streq(dec->type, "void")) {
    495        1.4        pk 		return;
    496        1.4        pk 	}
    497        1.4        pk 	if (streq(dec->type, "opaque")) {
    498        1.4        pk 		error("opaque -- illegal argument type");
    499        1.4        pk 	}
    500        1.7     lukem 	if (peekscan(TOK_STAR, &tok)) {
    501        1.7     lukem 		if (streq(dec->type, "string")) {
    502        1.7     lukem 			error("pointer to string not allowed in program arguments\n");
    503        1.7     lukem 		}
    504        1.4        pk 		dec->rel = REL_POINTER;
    505        1.7     lukem 		if (peekscan(TOK_IDENT, &tok))	/* optional name of argument */
    506        1.7     lukem 			dec->name = (char *) strdup(tok.str);
    507        1.7     lukem 	}
    508        1.7     lukem 	if (peekscan(TOK_LANGLE, &tok)) {
    509        1.7     lukem 		if (!streq(dec->type, "string")) {
    510        1.7     lukem 			error("arrays cannot be declared as arguments to procedures -- use typedef");
    511        1.7     lukem 		}
    512        1.4        pk 		dec->rel = REL_ARRAY;
    513        1.4        pk 		if (peekscan(TOK_RANGLE, &tok)) {
    514       1.12  christos 			dec->array_max = "(u_int)~0";
    515       1.12  christos 			/* unspecified size, use max */
    516        1.4        pk 		} else {
    517        1.4        pk 			scan_num(&tok);
    518        1.4        pk 			dec->array_max = tok.str;
    519        1.4        pk 			scan(TOK_RANGLE, &tok);
    520        1.4        pk 		}
    521        1.4        pk 	}
    522        1.4        pk 	if (streq(dec->type, "string")) {
    523        1.7     lukem 		if (dec->rel != REL_ARRAY) {	/* .x specifies just string as
    524        1.7     lukem 						 * type of argument - make it
    525        1.7     lukem 						 * string<> */
    526        1.4        pk 			dec->rel = REL_ARRAY;
    527       1.12  christos 			dec->array_max = "(u_int)~0";
    528       1.12  christos 			/* unspecified size, use max */
    529        1.4        pk 		}
    530        1.4        pk 	}
    531        1.4        pk }
    532        1.4        pk 
    533        1.4        pk 
    534        1.1     glass 
    535        1.6  christos static void
    536  1.16.12.1       tls get_type(const char **prefixp, const char **typep, defkind dkind)
    537        1.1     glass {
    538        1.7     lukem 	token   tok;
    539        1.1     glass 
    540        1.1     glass 	*prefixp = NULL;
    541        1.1     glass 	get_token(&tok);
    542        1.1     glass 	switch (tok.kind) {
    543        1.1     glass 	case TOK_IDENT:
    544        1.1     glass 		*typep = tok.str;
    545        1.1     glass 		break;
    546        1.1     glass 	case TOK_STRUCT:
    547        1.1     glass 	case TOK_ENUM:
    548        1.1     glass 	case TOK_UNION:
    549        1.1     glass 		*prefixp = tok.str;
    550        1.1     glass 		scan(TOK_IDENT, &tok);
    551        1.1     glass 		*typep = tok.str;
    552        1.1     glass 		break;
    553        1.1     glass 	case TOK_UNSIGNED:
    554        1.1     glass 		unsigned_dec(typep);
    555        1.1     glass 		break;
    556        1.1     glass 	case TOK_SHORT:
    557        1.9     lukem 		*typep = "short";
    558        1.1     glass 		(void) peekscan(TOK_INT, &tok);
    559        1.1     glass 		break;
    560        1.1     glass 	case TOK_LONG:
    561        1.9     lukem 		*typep = "long";
    562        1.1     glass 		(void) peekscan(TOK_INT, &tok);
    563        1.1     glass 		break;
    564       1.16  ginsbach 	case TOK_HYPER:
    565       1.16  ginsbach 		*typep = "longlong_t";
    566       1.16  ginsbach 		(void) peekscan(TOK_INT, &tok);
    567       1.16  ginsbach 		break;
    568        1.1     glass 	case TOK_VOID:
    569        1.1     glass 		if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
    570        1.4        pk 			error("voids allowed only inside union and program definitions with one argument");
    571        1.1     glass 		}
    572        1.1     glass 		*typep = tok.str;
    573        1.1     glass 		break;
    574        1.1     glass 	case TOK_STRING:
    575        1.1     glass 	case TOK_OPAQUE:
    576        1.1     glass 	case TOK_CHAR:
    577        1.9     lukem 	case TOK_INT:
    578        1.1     glass 	case TOK_FLOAT:
    579        1.1     glass 	case TOK_DOUBLE:
    580        1.1     glass 	case TOK_BOOL:
    581       1.16  ginsbach 	case TOK_QUAD:
    582        1.1     glass 		*typep = tok.str;
    583        1.1     glass 		break;
    584        1.1     glass 	default:
    585        1.1     glass 		error("expected type specifier");
    586        1.1     glass 	}
    587        1.1     glass }
    588        1.1     glass 
    589        1.6  christos static void
    590  1.16.12.1       tls unsigned_dec(const char **typep)
    591        1.1     glass {
    592        1.7     lukem 	token   tok;
    593        1.1     glass 
    594        1.1     glass 	peek(&tok);
    595        1.1     glass 	switch (tok.kind) {
    596        1.1     glass 	case TOK_CHAR:
    597        1.1     glass 		get_token(&tok);
    598        1.1     glass 		*typep = "u_char";
    599        1.1     glass 		break;
    600        1.1     glass 	case TOK_SHORT:
    601        1.1     glass 		get_token(&tok);
    602        1.9     lukem 		*typep = "u_short";
    603        1.1     glass 		(void) peekscan(TOK_INT, &tok);
    604        1.1     glass 		break;
    605        1.1     glass 	case TOK_LONG:
    606        1.1     glass 		get_token(&tok);
    607        1.9     lukem 		*typep = "u_long";
    608        1.1     glass 		(void) peekscan(TOK_INT, &tok);
    609        1.1     glass 		break;
    610       1.16  ginsbach 	case TOK_HYPER:
    611       1.16  ginsbach 		get_token(&tok);
    612       1.16  ginsbach 		*typep = "u_longlong_t";
    613       1.16  ginsbach 		(void) peekscan(TOK_INT, &tok);
    614       1.16  ginsbach 		break;
    615        1.1     glass 	case TOK_INT:
    616        1.1     glass 		get_token(&tok);
    617        1.9     lukem 		*typep = "u_int";
    618        1.1     glass 		break;
    619        1.1     glass 	default:
    620        1.9     lukem 		*typep = "u_int";
    621        1.1     glass 		break;
    622        1.1     glass 	}
    623        1.1     glass }
    624