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