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