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
304e115012SGarrett Wollman /*
314e115012SGarrett Wollman * rpc_parse.c, Parser for the RPC protocol compiler
324e115012SGarrett Wollman * Copyright (C) 1987 Sun Microsystems, Inc.
334e115012SGarrett Wollman */
344e115012SGarrett Wollman #include <stdio.h>
35ff49530fSBill Paul #include <string.h>
36ff49530fSBill Paul #include "rpc/types.h"
374e115012SGarrett Wollman #include "rpc_parse.h"
38e390e3afSDavid Malone #include "rpc_scan.h"
39ff49530fSBill Paul #include "rpc_util.h"
404e115012SGarrett Wollman
41ff49530fSBill Paul #define ARGNAME "arg"
42ff49530fSBill Paul
43d3cb5dedSWarner Losh static void isdefined( definition * );
44d3cb5dedSWarner Losh static void def_struct( definition * );
45d3cb5dedSWarner Losh static void def_program( definition * );
46d3cb5dedSWarner Losh static void def_enum( definition * );
47d3cb5dedSWarner Losh static void def_const( definition * );
48d3cb5dedSWarner Losh static void def_union( definition * );
49d3cb5dedSWarner Losh static void def_typedef( definition * );
50d3cb5dedSWarner Losh static void get_declaration( declaration *, defkind );
51d3cb5dedSWarner Losh static void get_prog_declaration( declaration *, defkind, int );
52e390e3afSDavid Malone static void get_type(const char **, const char **, defkind);
53e390e3afSDavid Malone static void unsigned_dec(const char ** );
54ff49530fSBill Paul
554e115012SGarrett Wollman /*
564e115012SGarrett Wollman * return the next definition you see
574e115012SGarrett Wollman */
584e115012SGarrett Wollman definition *
get_definition(void)59e390e3afSDavid Malone get_definition(void)
604e115012SGarrett Wollman {
614e115012SGarrett Wollman definition *defp;
624e115012SGarrett Wollman token tok;
634e115012SGarrett Wollman
6475863a6dSPhilippe Charnier defp = XALLOC(definition);
654e115012SGarrett Wollman get_token(&tok);
664e115012SGarrett Wollman switch (tok.kind) {
674e115012SGarrett Wollman case TOK_STRUCT:
684e115012SGarrett Wollman def_struct(defp);
694e115012SGarrett Wollman break;
704e115012SGarrett Wollman case TOK_UNION:
714e115012SGarrett Wollman def_union(defp);
724e115012SGarrett Wollman break;
734e115012SGarrett Wollman case TOK_TYPEDEF:
744e115012SGarrett Wollman def_typedef(defp);
754e115012SGarrett Wollman break;
764e115012SGarrett Wollman case TOK_ENUM:
774e115012SGarrett Wollman def_enum(defp);
784e115012SGarrett Wollman break;
794e115012SGarrett Wollman case TOK_PROGRAM:
804e115012SGarrett Wollman def_program(defp);
814e115012SGarrett Wollman break;
824e115012SGarrett Wollman case TOK_CONST:
834e115012SGarrett Wollman def_const(defp);
844e115012SGarrett Wollman break;
854e115012SGarrett Wollman case TOK_EOF:
86*e893031dSWarner Losh free(defp);
874e115012SGarrett Wollman return (NULL);
884e115012SGarrett Wollman default:
894e115012SGarrett Wollman error("definition keyword expected");
904e115012SGarrett Wollman }
914e115012SGarrett Wollman scan(TOK_SEMICOLON, &tok);
924e115012SGarrett Wollman isdefined(defp);
934e115012SGarrett Wollman return (defp);
944e115012SGarrett Wollman }
954e115012SGarrett Wollman
96526195adSJordan K. Hubbard static void
isdefined(definition * defp)97e390e3afSDavid Malone isdefined(definition *defp)
984e115012SGarrett Wollman {
994e115012SGarrett Wollman STOREVAL(&defined, defp);
1004e115012SGarrett Wollman }
1014e115012SGarrett Wollman
102526195adSJordan K. Hubbard static void
def_struct(definition * defp)103e390e3afSDavid Malone def_struct(definition *defp)
1044e115012SGarrett Wollman {
1054e115012SGarrett Wollman token tok;
1064e115012SGarrett Wollman declaration dec;
1074e115012SGarrett Wollman decl_list *decls;
1084e115012SGarrett Wollman decl_list **tailp;
1094e115012SGarrett Wollman
1104e115012SGarrett Wollman defp->def_kind = DEF_STRUCT;
1114e115012SGarrett Wollman
1124e115012SGarrett Wollman scan(TOK_IDENT, &tok);
1134e115012SGarrett Wollman defp->def_name = tok.str;
1144e115012SGarrett Wollman scan(TOK_LBRACE, &tok);
1154e115012SGarrett Wollman tailp = &defp->def.st.decls;
1164e115012SGarrett Wollman do {
1174e115012SGarrett Wollman get_declaration(&dec, DEF_STRUCT);
11875863a6dSPhilippe Charnier decls = XALLOC(decl_list);
1194e115012SGarrett Wollman decls->decl = dec;
1204e115012SGarrett Wollman *tailp = decls;
1214e115012SGarrett Wollman tailp = &decls->next;
1224e115012SGarrett Wollman scan(TOK_SEMICOLON, &tok);
1234e115012SGarrett Wollman peek(&tok);
1244e115012SGarrett Wollman } while (tok.kind != TOK_RBRACE);
1254e115012SGarrett Wollman get_token(&tok);
1264e115012SGarrett Wollman *tailp = NULL;
1274e115012SGarrett Wollman }
1284e115012SGarrett Wollman
129526195adSJordan K. Hubbard static void
def_program(definition * defp)130e390e3afSDavid Malone def_program(definition *defp)
1314e115012SGarrett Wollman {
1324e115012SGarrett Wollman token tok;
133ff49530fSBill Paul declaration dec;
134ff49530fSBill Paul decl_list *decls;
135ff49530fSBill Paul decl_list **tailp;
1364e115012SGarrett Wollman version_list *vlist;
1374e115012SGarrett Wollman version_list **vtailp;
1384e115012SGarrett Wollman proc_list *plist;
1394e115012SGarrett Wollman proc_list **ptailp;
140ff49530fSBill Paul int num_args;
141ff49530fSBill Paul bool_t isvoid = FALSE; /* whether first argument is void */
1424e115012SGarrett Wollman defp->def_kind = DEF_PROGRAM;
1434e115012SGarrett Wollman scan(TOK_IDENT, &tok);
1444e115012SGarrett Wollman defp->def_name = tok.str;
1454e115012SGarrett Wollman scan(TOK_LBRACE, &tok);
1464e115012SGarrett Wollman vtailp = &defp->def.pr.versions;
147ff49530fSBill Paul tailp = &defp->def.st.decls;
1484e115012SGarrett Wollman scan(TOK_VERSION, &tok);
1494e115012SGarrett Wollman do {
1504e115012SGarrett Wollman scan(TOK_IDENT, &tok);
15175863a6dSPhilippe Charnier vlist = XALLOC(version_list);
1524e115012SGarrett Wollman vlist->vers_name = tok.str;
1534e115012SGarrett Wollman scan(TOK_LBRACE, &tok);
1544e115012SGarrett Wollman ptailp = &vlist->procs;
1554e115012SGarrett Wollman do {
156ff49530fSBill Paul /* get result type */
15775863a6dSPhilippe Charnier plist = XALLOC(proc_list);
158ff49530fSBill Paul get_type(&plist->res_prefix, &plist->res_type,
159ff49530fSBill Paul DEF_PROGRAM);
1604e115012SGarrett Wollman if (streq(plist->res_type, "opaque")) {
1614e115012SGarrett Wollman error("illegal result type");
1624e115012SGarrett Wollman }
1634e115012SGarrett Wollman scan(TOK_IDENT, &tok);
1644e115012SGarrett Wollman plist->proc_name = tok.str;
1654e115012SGarrett Wollman scan(TOK_LPAREN, &tok);
166ff49530fSBill Paul /* get args - first one */
167ff49530fSBill Paul num_args = 1;
168ff49530fSBill Paul isvoid = FALSE;
169ff49530fSBill Paul /*
170ff49530fSBill Paul * type of DEF_PROGRAM in the first
171ff49530fSBill Paul * get_prog_declaration and DEF_STURCT in the next
172ff49530fSBill Paul * allows void as argument if it is the only argument
173ff49530fSBill Paul */
174ff49530fSBill Paul get_prog_declaration(&dec, DEF_PROGRAM, num_args);
175ff49530fSBill Paul if (streq(dec.type, "void"))
176ff49530fSBill Paul isvoid = TRUE;
17775863a6dSPhilippe Charnier decls = XALLOC(decl_list);
178ff49530fSBill Paul plist->args.decls = decls;
179ff49530fSBill Paul decls->decl = dec;
180ff49530fSBill Paul tailp = &decls->next;
181ff49530fSBill Paul /* get args */
182ff49530fSBill Paul while (peekscan(TOK_COMMA, &tok)) {
183ff49530fSBill Paul num_args++;
184ff49530fSBill Paul get_prog_declaration(&dec, DEF_STRUCT,
185ff49530fSBill Paul num_args);
18675863a6dSPhilippe Charnier decls = XALLOC(decl_list);
187ff49530fSBill Paul decls->decl = dec;
188ff49530fSBill Paul *tailp = decls;
189ff49530fSBill Paul if (streq(dec.type, "void"))
190ff49530fSBill Paul isvoid = TRUE;
191ff49530fSBill Paul tailp = &decls->next;
1924e115012SGarrett Wollman }
193ff49530fSBill Paul /* multiple arguments are only allowed in newstyle */
194ff49530fSBill Paul if (!newstyle && num_args > 1) {
195ff49530fSBill Paul error("only one argument is allowed");
196ff49530fSBill Paul }
197ff49530fSBill Paul if (isvoid && num_args > 1) {
198ff49530fSBill Paul error("illegal use of void in program definition");
199ff49530fSBill Paul }
200ff49530fSBill Paul *tailp = NULL;
2014e115012SGarrett Wollman scan(TOK_RPAREN, &tok);
2024e115012SGarrett Wollman scan(TOK_EQUAL, &tok);
2034e115012SGarrett Wollman scan_num(&tok);
2044e115012SGarrett Wollman scan(TOK_SEMICOLON, &tok);
2054e115012SGarrett Wollman plist->proc_num = tok.str;
206ff49530fSBill Paul plist->arg_num = num_args;
2074e115012SGarrett Wollman *ptailp = plist;
2084e115012SGarrett Wollman ptailp = &plist->next;
2094e115012SGarrett Wollman peek(&tok);
2104e115012SGarrett Wollman } while (tok.kind != TOK_RBRACE);
2110b455160SAndrey A. Chernov *ptailp = NULL;
2124e115012SGarrett Wollman *vtailp = vlist;
2134e115012SGarrett Wollman vtailp = &vlist->next;
2144e115012SGarrett Wollman scan(TOK_RBRACE, &tok);
2154e115012SGarrett Wollman scan(TOK_EQUAL, &tok);
2164e115012SGarrett Wollman scan_num(&tok);
2174e115012SGarrett Wollman vlist->vers_num = tok.str;
218ff49530fSBill Paul /* make the argument structure name for each arg */
219ff49530fSBill Paul for (plist = vlist->procs; plist != NULL;
220ff49530fSBill Paul plist = plist->next) {
221ff49530fSBill Paul plist->args.argname = make_argname(plist->proc_name,
222ff49530fSBill Paul vlist->vers_num);
223ff49530fSBill Paul /* free the memory ?? */
224ff49530fSBill Paul }
2254e115012SGarrett Wollman scan(TOK_SEMICOLON, &tok);
2264e115012SGarrett Wollman scan2(TOK_VERSION, TOK_RBRACE, &tok);
2274e115012SGarrett Wollman } while (tok.kind == TOK_VERSION);
2284e115012SGarrett Wollman scan(TOK_EQUAL, &tok);
2294e115012SGarrett Wollman scan_num(&tok);
2304e115012SGarrett Wollman defp->def.pr.prog_num = tok.str;
2314e115012SGarrett Wollman *vtailp = NULL;
2324e115012SGarrett Wollman }
2334e115012SGarrett Wollman
234ff49530fSBill Paul
235526195adSJordan K. Hubbard static void
def_enum(definition * defp)236e390e3afSDavid Malone def_enum(definition *defp)
2374e115012SGarrett Wollman {
2384e115012SGarrett Wollman token tok;
2394e115012SGarrett Wollman enumval_list *elist;
2404e115012SGarrett Wollman enumval_list **tailp;
2414e115012SGarrett Wollman
2424e115012SGarrett Wollman defp->def_kind = DEF_ENUM;
2434e115012SGarrett Wollman scan(TOK_IDENT, &tok);
2444e115012SGarrett Wollman defp->def_name = tok.str;
2454e115012SGarrett Wollman scan(TOK_LBRACE, &tok);
2464e115012SGarrett Wollman tailp = &defp->def.en.vals;
2474e115012SGarrett Wollman do {
2484e115012SGarrett Wollman scan(TOK_IDENT, &tok);
24975863a6dSPhilippe Charnier elist = XALLOC(enumval_list);
2504e115012SGarrett Wollman elist->name = tok.str;
2514e115012SGarrett Wollman elist->assignment = NULL;
2524e115012SGarrett Wollman scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
2534e115012SGarrett Wollman if (tok.kind == TOK_EQUAL) {
2544e115012SGarrett Wollman scan_num(&tok);
2554e115012SGarrett Wollman elist->assignment = tok.str;
2564e115012SGarrett Wollman scan2(TOK_COMMA, TOK_RBRACE, &tok);
2574e115012SGarrett Wollman }
2584e115012SGarrett Wollman *tailp = elist;
2594e115012SGarrett Wollman tailp = &elist->next;
2604e115012SGarrett Wollman } while (tok.kind != TOK_RBRACE);
2614e115012SGarrett Wollman *tailp = NULL;
2624e115012SGarrett Wollman }
2634e115012SGarrett Wollman
264526195adSJordan K. Hubbard static void
def_const(definition * defp)265e390e3afSDavid Malone def_const(definition *defp)
2664e115012SGarrett Wollman {
2674e115012SGarrett Wollman token tok;
2684e115012SGarrett Wollman
2694e115012SGarrett Wollman defp->def_kind = DEF_CONST;
2704e115012SGarrett Wollman scan(TOK_IDENT, &tok);
2714e115012SGarrett Wollman defp->def_name = tok.str;
2724e115012SGarrett Wollman scan(TOK_EQUAL, &tok);
2734e115012SGarrett Wollman scan2(TOK_IDENT, TOK_STRCONST, &tok);
2744e115012SGarrett Wollman defp->def.co = tok.str;
2754e115012SGarrett Wollman }
2764e115012SGarrett Wollman
277526195adSJordan K. Hubbard static void
def_union(definition * defp)278e390e3afSDavid Malone def_union(definition *defp)
2794e115012SGarrett Wollman {
2804e115012SGarrett Wollman token tok;
2814e115012SGarrett Wollman declaration dec;
282526195adSJordan K. Hubbard case_list *cases;
2834e115012SGarrett Wollman case_list **tailp;
2844e115012SGarrett Wollman
2854e115012SGarrett Wollman defp->def_kind = DEF_UNION;
2864e115012SGarrett Wollman scan(TOK_IDENT, &tok);
2874e115012SGarrett Wollman defp->def_name = tok.str;
2884e115012SGarrett Wollman scan(TOK_SWITCH, &tok);
2894e115012SGarrett Wollman scan(TOK_LPAREN, &tok);
2904e115012SGarrett Wollman get_declaration(&dec, DEF_UNION);
2914e115012SGarrett Wollman defp->def.un.enum_decl = dec;
2924e115012SGarrett Wollman tailp = &defp->def.un.cases;
2934e115012SGarrett Wollman scan(TOK_RPAREN, &tok);
2944e115012SGarrett Wollman scan(TOK_LBRACE, &tok);
2954e115012SGarrett Wollman scan(TOK_CASE, &tok);
2964e115012SGarrett Wollman while (tok.kind == TOK_CASE) {
297ff49530fSBill Paul scan2(TOK_IDENT, TOK_CHARCONST, &tok);
29875863a6dSPhilippe Charnier cases = XALLOC(case_list);
2994e115012SGarrett Wollman cases->case_name = tok.str;
3004e115012SGarrett Wollman scan(TOK_COLON, &tok);
301ff49530fSBill Paul /* now peek at next token */
302ff49530fSBill Paul if (peekscan(TOK_CASE, &tok)){
303ff49530fSBill Paul do {
304ff49530fSBill Paul scan2(TOK_IDENT, TOK_CHARCONST, &tok);
305ff49530fSBill Paul cases->contflag = 1;
306ff49530fSBill Paul /* continued case statement */
307ff49530fSBill Paul *tailp = cases;
308ff49530fSBill Paul tailp = &cases->next;
30975863a6dSPhilippe Charnier cases = XALLOC(case_list);
310ff49530fSBill Paul cases->case_name = tok.str;
311ff49530fSBill Paul scan(TOK_COLON, &tok);
312ff49530fSBill Paul } while (peekscan(TOK_CASE, &tok));
313ff49530fSBill Paul }
314ff49530fSBill Paul
3154e115012SGarrett Wollman get_declaration(&dec, DEF_UNION);
3164e115012SGarrett Wollman cases->case_decl = dec;
317ff49530fSBill Paul cases->contflag = 0; /* no continued case statement */
3184e115012SGarrett Wollman *tailp = cases;
3194e115012SGarrett Wollman tailp = &cases->next;
3204e115012SGarrett Wollman scan(TOK_SEMICOLON, &tok);
321ff49530fSBill Paul
3224e115012SGarrett Wollman scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
3234e115012SGarrett Wollman }
3244e115012SGarrett Wollman *tailp = NULL;
3254e115012SGarrett Wollman if (tok.kind == TOK_DEFAULT) {
3264e115012SGarrett Wollman scan(TOK_COLON, &tok);
3274e115012SGarrett Wollman get_declaration(&dec, DEF_UNION);
32875863a6dSPhilippe Charnier defp->def.un.default_decl = XALLOC(declaration);
3294e115012SGarrett Wollman *defp->def.un.default_decl = dec;
3304e115012SGarrett Wollman scan(TOK_SEMICOLON, &tok);
3314e115012SGarrett Wollman scan(TOK_RBRACE, &tok);
3324e115012SGarrett Wollman } else {
3334e115012SGarrett Wollman defp->def.un.default_decl = NULL;
3344e115012SGarrett Wollman }
3354e115012SGarrett Wollman }
3364e115012SGarrett Wollman
337e390e3afSDavid Malone static const char *reserved_words[] =
338ff49530fSBill Paul {
339ff49530fSBill Paul "array",
340ff49530fSBill Paul "bytes",
341ff49530fSBill Paul "destroy",
342ff49530fSBill Paul "free",
343ff49530fSBill Paul "getpos",
344ff49530fSBill Paul "inline",
345ff49530fSBill Paul "pointer",
346ff49530fSBill Paul "reference",
347ff49530fSBill Paul "setpos",
348ff49530fSBill Paul "sizeof",
349ff49530fSBill Paul "union",
350ff49530fSBill Paul "vector",
351ff49530fSBill Paul NULL
352ff49530fSBill Paul };
353ff49530fSBill Paul
354e390e3afSDavid Malone static const char *reserved_types[] =
355ff49530fSBill Paul {
356ff49530fSBill Paul "opaque",
357ff49530fSBill Paul "string",
358ff49530fSBill Paul NULL
359ff49530fSBill Paul };
360ff49530fSBill Paul
361ff49530fSBill Paul /*
362ff49530fSBill Paul * check that the given name is not one that would eventually result in
363ff49530fSBill Paul * xdr routines that would conflict with internal XDR routines.
364ff49530fSBill Paul */
365526195adSJordan K. Hubbard static void
check_type_name(const char * name,int new_type)366e390e3afSDavid Malone check_type_name(const char *name, int new_type)
367ff49530fSBill Paul {
368ff49530fSBill Paul int i;
369ff49530fSBill Paul char tmp[100];
370ff49530fSBill Paul
371ff49530fSBill Paul for (i = 0; reserved_words[i] != NULL; i++) {
372ff49530fSBill Paul if (strcmp(name, reserved_words[i]) == 0) {
373ff49530fSBill Paul sprintf(tmp,
374ff49530fSBill Paul "illegal (reserved) name :\'%s\' in type definition",
375ff49530fSBill Paul name);
376ff49530fSBill Paul error(tmp);
377ff49530fSBill Paul }
378ff49530fSBill Paul }
379ff49530fSBill Paul if (new_type) {
380ff49530fSBill Paul for (i = 0; reserved_types[i] != NULL; i++) {
381ff49530fSBill Paul if (strcmp(name, reserved_types[i]) == 0) {
382ff49530fSBill Paul sprintf(tmp,
383ff49530fSBill Paul "illegal (reserved) name :\'%s\' in type definition",
384ff49530fSBill Paul name);
385ff49530fSBill Paul error(tmp);
386ff49530fSBill Paul }
387ff49530fSBill Paul }
388ff49530fSBill Paul }
389ff49530fSBill Paul }
390ff49530fSBill Paul
391ff49530fSBill Paul
3924e115012SGarrett Wollman
393526195adSJordan K. Hubbard static void
def_typedef(definition * defp)394e390e3afSDavid Malone def_typedef(definition *defp)
3954e115012SGarrett Wollman {
3964e115012SGarrett Wollman declaration dec;
3974e115012SGarrett Wollman
3984e115012SGarrett Wollman defp->def_kind = DEF_TYPEDEF;
3994e115012SGarrett Wollman get_declaration(&dec, DEF_TYPEDEF);
4004e115012SGarrett Wollman defp->def_name = dec.name;
401ff49530fSBill Paul check_type_name(dec.name, 1);
4024e115012SGarrett Wollman defp->def.ty.old_prefix = dec.prefix;
4034e115012SGarrett Wollman defp->def.ty.old_type = dec.type;
4044e115012SGarrett Wollman defp->def.ty.rel = dec.rel;
4054e115012SGarrett Wollman defp->def.ty.array_max = dec.array_max;
4064e115012SGarrett Wollman }
4074e115012SGarrett Wollman
408526195adSJordan K. Hubbard static void
get_declaration(declaration * dec,defkind dkind)409e390e3afSDavid Malone get_declaration(declaration *dec, defkind dkind)
4104e115012SGarrett Wollman {
4114e115012SGarrett Wollman token tok;
4124e115012SGarrett Wollman
4134e115012SGarrett Wollman get_type(&dec->prefix, &dec->type, dkind);
4144e115012SGarrett Wollman dec->rel = REL_ALIAS;
4154e115012SGarrett Wollman if (streq(dec->type, "void")) {
4164e115012SGarrett Wollman return;
4174e115012SGarrett Wollman }
418ff49530fSBill Paul
419ff49530fSBill Paul check_type_name(dec->type, 0);
4204e115012SGarrett Wollman scan2(TOK_STAR, TOK_IDENT, &tok);
4214e115012SGarrett Wollman if (tok.kind == TOK_STAR) {
4224e115012SGarrett Wollman dec->rel = REL_POINTER;
4234e115012SGarrett Wollman scan(TOK_IDENT, &tok);
4244e115012SGarrett Wollman }
4254e115012SGarrett Wollman dec->name = tok.str;
4264e115012SGarrett Wollman if (peekscan(TOK_LBRACKET, &tok)) {
4274e115012SGarrett Wollman if (dec->rel == REL_POINTER) {
4284e115012SGarrett Wollman error("no array-of-pointer declarations -- use typedef");
4294e115012SGarrett Wollman }
4304e115012SGarrett Wollman dec->rel = REL_VECTOR;
4314e115012SGarrett Wollman scan_num(&tok);
4324e115012SGarrett Wollman dec->array_max = tok.str;
4334e115012SGarrett Wollman scan(TOK_RBRACKET, &tok);
4344e115012SGarrett Wollman } else if (peekscan(TOK_LANGLE, &tok)) {
4354e115012SGarrett Wollman if (dec->rel == REL_POINTER) {
4364e115012SGarrett Wollman error("no array-of-pointer declarations -- use typedef");
4374e115012SGarrett Wollman }
4384e115012SGarrett Wollman dec->rel = REL_ARRAY;
4394e115012SGarrett Wollman if (peekscan(TOK_RANGLE, &tok)) {
4404e115012SGarrett Wollman dec->array_max = "~0"; /* unspecified size, use max */
4414e115012SGarrett Wollman } else {
4424e115012SGarrett Wollman scan_num(&tok);
4434e115012SGarrett Wollman dec->array_max = tok.str;
4444e115012SGarrett Wollman scan(TOK_RANGLE, &tok);
4454e115012SGarrett Wollman }
4464e115012SGarrett Wollman }
4474e115012SGarrett Wollman if (streq(dec->type, "opaque")) {
4484e115012SGarrett Wollman if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
4494e115012SGarrett Wollman error("array declaration expected");
4504e115012SGarrett Wollman }
4514e115012SGarrett Wollman } else if (streq(dec->type, "string")) {
4524e115012SGarrett Wollman if (dec->rel != REL_ARRAY) {
4534e115012SGarrett Wollman error("variable-length array declaration expected");
4544e115012SGarrett Wollman }
4554e115012SGarrett Wollman }
4564e115012SGarrett Wollman }
4574e115012SGarrett Wollman
4584e115012SGarrett Wollman
459526195adSJordan K. Hubbard static void
get_prog_declaration(declaration * dec,defkind dkind,int num)460e390e3afSDavid Malone get_prog_declaration(declaration *dec, defkind dkind, int num)
461ff49530fSBill Paul {
462ff49530fSBill Paul token tok;
463ff49530fSBill Paul char name[10]; /* argument name */
464ff49530fSBill Paul
465ff49530fSBill Paul if (dkind == DEF_PROGRAM) {
466ff49530fSBill Paul peek(&tok);
467ff49530fSBill Paul if (tok.kind == TOK_RPAREN) { /* no arguments */
468ff49530fSBill Paul dec->rel = REL_ALIAS;
469ff49530fSBill Paul dec->type = "void";
470ff49530fSBill Paul dec->prefix = NULL;
471ff49530fSBill Paul dec->name = NULL;
472ff49530fSBill Paul return;
473ff49530fSBill Paul }
474ff49530fSBill Paul }
475ff49530fSBill Paul get_type(&dec->prefix, &dec->type, dkind);
476ff49530fSBill Paul dec->rel = REL_ALIAS;
477ff49530fSBill Paul if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
478ff49530fSBill Paul strcpy(name, tok.str);
479ff49530fSBill Paul else
480ff49530fSBill Paul sprintf(name, "%s%d", ARGNAME, num);
481ff49530fSBill Paul /* default name of argument */
482ff49530fSBill Paul
48375863a6dSPhilippe Charnier dec->name = (char *) xstrdup(name);
484ff49530fSBill Paul if (streq(dec->type, "void")) {
485ff49530fSBill Paul return;
486ff49530fSBill Paul }
487ff49530fSBill Paul
488ff49530fSBill Paul if (streq(dec->type, "opaque")) {
489ff49530fSBill Paul error("opaque -- illegal argument type");
490ff49530fSBill Paul }
491ff49530fSBill Paul if (peekscan(TOK_STAR, &tok)) {
492ff49530fSBill Paul if (streq(dec->type, "string")) {
49375863a6dSPhilippe Charnier error("pointer to string not allowed in program arguments");
494ff49530fSBill Paul }
495ff49530fSBill Paul dec->rel = REL_POINTER;
49675863a6dSPhilippe Charnier if (peekscan(TOK_IDENT, &tok)) {
497ff49530fSBill Paul /* optional name of argument */
49875863a6dSPhilippe Charnier dec->name = xstrdup(tok.str);
49975863a6dSPhilippe Charnier }
500ff49530fSBill Paul }
501ff49530fSBill Paul if (peekscan(TOK_LANGLE, &tok)) {
502ff49530fSBill Paul if (!streq(dec->type, "string")) {
503ff49530fSBill Paul error("arrays cannot be declared as arguments to procedures -- use typedef");
504ff49530fSBill Paul }
505ff49530fSBill Paul dec->rel = REL_ARRAY;
506ff49530fSBill Paul if (peekscan(TOK_RANGLE, &tok)) {
507ff49530fSBill Paul dec->array_max = "~0";
508ff49530fSBill Paul /* unspecified size, use max */
509ff49530fSBill Paul } else {
510ff49530fSBill Paul scan_num(&tok);
511ff49530fSBill Paul dec->array_max = tok.str;
512ff49530fSBill Paul scan(TOK_RANGLE, &tok);
513ff49530fSBill Paul }
514ff49530fSBill Paul }
515ff49530fSBill Paul if (streq(dec->type, "string")) {
516ff49530fSBill Paul if (dec->rel != REL_ARRAY) {
517ff49530fSBill Paul /*
518ff49530fSBill Paul * .x specifies just string as
519ff49530fSBill Paul * type of argument
520ff49530fSBill Paul * - make it string<>
521ff49530fSBill Paul */
522ff49530fSBill Paul dec->rel = REL_ARRAY;
523ff49530fSBill Paul dec->array_max = "~0"; /* unspecified size, use max */
524ff49530fSBill Paul }
525ff49530fSBill Paul }
526ff49530fSBill Paul }
527ff49530fSBill Paul
528ff49530fSBill Paul
529ff49530fSBill Paul
530526195adSJordan K. Hubbard static void
get_type(const char ** prefixp,const char ** typep,defkind dkind)531e390e3afSDavid Malone get_type(const char **prefixp, const char **typep, defkind dkind)
5324e115012SGarrett Wollman {
5334e115012SGarrett Wollman token tok;
5344e115012SGarrett Wollman
5354e115012SGarrett Wollman *prefixp = NULL;
5364e115012SGarrett Wollman get_token(&tok);
5374e115012SGarrett Wollman switch (tok.kind) {
5384e115012SGarrett Wollman case TOK_IDENT:
5394e115012SGarrett Wollman *typep = tok.str;
5404e115012SGarrett Wollman break;
5414e115012SGarrett Wollman case TOK_STRUCT:
5424e115012SGarrett Wollman case TOK_ENUM:
5434e115012SGarrett Wollman case TOK_UNION:
5444e115012SGarrett Wollman *prefixp = tok.str;
5454e115012SGarrett Wollman scan(TOK_IDENT, &tok);
5464e115012SGarrett Wollman *typep = tok.str;
5474e115012SGarrett Wollman break;
5484e115012SGarrett Wollman case TOK_UNSIGNED:
5494e115012SGarrett Wollman unsigned_dec(typep);
5504e115012SGarrett Wollman break;
5514e115012SGarrett Wollman case TOK_SHORT:
5524e115012SGarrett Wollman *typep = "short";
5534e115012SGarrett Wollman (void) peekscan(TOK_INT, &tok);
5544e115012SGarrett Wollman break;
5554e115012SGarrett Wollman case TOK_LONG:
5564e115012SGarrett Wollman *typep = "long";
5574e115012SGarrett Wollman (void) peekscan(TOK_INT, &tok);
5584e115012SGarrett Wollman break;
559ff49530fSBill Paul case TOK_HYPER:
560c304ad8aSDavid E. O'Brien *typep = "int64_t";
561ff49530fSBill Paul (void) peekscan(TOK_INT, &tok);
562ff49530fSBill Paul break;
563ff49530fSBill Paul
5644e115012SGarrett Wollman case TOK_VOID:
5654e115012SGarrett Wollman if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
566ff49530fSBill Paul error("voids allowed only inside union and program definitions with one argument");
5674e115012SGarrett Wollman }
5684e115012SGarrett Wollman *typep = tok.str;
5694e115012SGarrett Wollman break;
5704e115012SGarrett Wollman case TOK_STRING:
5714e115012SGarrett Wollman case TOK_OPAQUE:
5724e115012SGarrett Wollman case TOK_CHAR:
5734e115012SGarrett Wollman case TOK_INT:
5744e115012SGarrett Wollman case TOK_FLOAT:
5754e115012SGarrett Wollman case TOK_DOUBLE:
5764e115012SGarrett Wollman case TOK_BOOL:
577ff49530fSBill Paul case TOK_QUAD:
5784e115012SGarrett Wollman *typep = tok.str;
5794e115012SGarrett Wollman break;
5804e115012SGarrett Wollman default:
5814e115012SGarrett Wollman error("expected type specifier");
5824e115012SGarrett Wollman }
5834e115012SGarrett Wollman }
5844e115012SGarrett Wollman
585526195adSJordan K. Hubbard static void
unsigned_dec(const char ** typep)586e390e3afSDavid Malone unsigned_dec(const char **typep)
5874e115012SGarrett Wollman {
5884e115012SGarrett Wollman token tok;
5894e115012SGarrett Wollman
5904e115012SGarrett Wollman peek(&tok);
5914e115012SGarrett Wollman switch (tok.kind) {
5924e115012SGarrett Wollman case TOK_CHAR:
5934e115012SGarrett Wollman get_token(&tok);
5944e115012SGarrett Wollman *typep = "u_char";
5954e115012SGarrett Wollman break;
5964e115012SGarrett Wollman case TOK_SHORT:
5974e115012SGarrett Wollman get_token(&tok);
5984e115012SGarrett Wollman *typep = "u_short";
5994e115012SGarrett Wollman (void) peekscan(TOK_INT, &tok);
6004e115012SGarrett Wollman break;
6014e115012SGarrett Wollman case TOK_LONG:
6024e115012SGarrett Wollman get_token(&tok);
6034e115012SGarrett Wollman *typep = "u_long";
6044e115012SGarrett Wollman (void) peekscan(TOK_INT, &tok);
6054e115012SGarrett Wollman break;
606ff49530fSBill Paul case TOK_HYPER:
607ff49530fSBill Paul get_token(&tok);
608c304ad8aSDavid E. O'Brien *typep = "u_int64_t";
6098360efbdSAlfred Perlstein
610ff49530fSBill Paul (void) peekscan(TOK_INT, &tok);
611ff49530fSBill Paul break;
6124e115012SGarrett Wollman case TOK_INT:
6134e115012SGarrett Wollman get_token(&tok);
6144e115012SGarrett Wollman *typep = "u_int";
6154e115012SGarrett Wollman break;
6164e115012SGarrett Wollman default:
6174e115012SGarrett Wollman *typep = "u_int";
6184e115012SGarrett Wollman break;
6194e115012SGarrett Wollman }
6204e115012SGarrett Wollman }
621