xref: /titanic_50/usr/src/cmd/rpcgen/rpc_parse.c (revision f3b88bd264fc74b4befab18c4ba4329a388ddcb7)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29 /*
30  * University Copyright- Copyright (c) 1982, 1986, 1988
31  * The Regents of the University of California
32  * All Rights Reserved
33  *
34  * University Acknowledgment- Portions of this document are derived from
35  * software developed by the University of California, Berkeley, and its
36  * contributors.
37  */
38 
39 #pragma ident	"%Z%%M%	%I%	%E% SMI"
40 
41 /*
42  * rpc_parse.c, Parser for the RPC protocol compiler
43  */
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include "rpc/types.h"
48 #include "rpc_scan.h"
49 #include "rpc_parse.h"
50 #include "rpc_util.h"
51 
52 #define	ARGNAME "arg"
53 
54 extern char *make_argname(char *, char *);
55 
56 static void isdefined(definition *);
57 static void def_struct(definition *);
58 static void def_program(definition *);
59 static void def_enum(definition *);
60 static void def_const(definition *);
61 static void def_union(definition *);
62 static void def_typedef(definition *);
63 static void get_declaration(declaration *, defkind);
64 static void get_prog_declaration(declaration *, defkind, int);
65 static void get_type(char **, char **, defkind);
66 static void unsigned_dec(char **);
67 
68 /*
69  * return the next definition you see
70  */
71 definition *
72 get_definition(void)
73 {
74 	definition *defp;
75 	token tok;
76 
77 	defp = calloc(1, sizeof (definition));
78 	get_token(&tok);
79 	switch (tok.kind) {
80 	case TOK_STRUCT:
81 		def_struct(defp);
82 		break;
83 	case TOK_UNION:
84 		def_union(defp);
85 		break;
86 	case TOK_TYPEDEF:
87 		def_typedef(defp);
88 		break;
89 	case TOK_ENUM:
90 		def_enum(defp);
91 		break;
92 	case TOK_PROGRAM:
93 		def_program(defp);
94 		break;
95 	case TOK_CONST:
96 		def_const(defp);
97 		break;
98 	case TOK_EOF:
99 		return (NULL);
100 	default:
101 		error("definition keyword expected");
102 	}
103 	scan(TOK_SEMICOLON, &tok);
104 	isdefined(defp);
105 	return (defp);
106 }
107 
108 static void
109 isdefined(definition *defp)
110 {
111 	STOREVAL(&defined, defp);
112 }
113 
114 /*
115  * We treat s == NULL the same as *s == '\0'
116  */
117 static int
118 streqn(const char *s1, const char *s2)
119 {
120 	if (s1 == NULL)
121 		s1 = "";
122 	if (s2 == NULL)
123 		s2 = "";
124 	if (s1 == s2)
125 		return (1);
126 
127 	return (strcmp(s1, s2) == 0);
128 }
129 
130 static int
131 cmptype(definition *defp, char *type)
132 {
133 	/* We only want typedef definitions */
134 	if (streq(defp->def_name, type) && defp->def_kind == DEF_TYPEDEF)
135 		return (1);
136 	return (0);
137 }
138 
139 static int
140 check_self_reference(const char *name, const declaration *decp, int first)
141 {
142 	/*
143 	 * Now check for the following special case if first is true:
144 	 *
145 	 * struct foo {
146 	 *	...
147 	 *	foo *next;
148 	 * };
149 	 *
150 	 *
151 	 * In the above cases foo has not yet been entered in the type list,
152 	 * defined. So there is no typedef entry. The prefix in that case
153 	 * could be empty.
154 	 */
155 	if (decp->rel == REL_POINTER &&
156 	    (streqn(decp->prefix, "struct") ||
157 	    (first && streqn(decp->prefix, ""))) &&
158 	    streqn(name, decp->type))
159 		return (1);
160 	return (0);
161 }
162 
163 static int
164 is_self_reference(definition *defp, declaration *decp)
165 {
166 	declaration current;
167 	definition *dp;
168 
169 	if (check_self_reference(defp->def_name, decp, 1))
170 		return (1);
171 
172 	/*
173 	 * Check for valid declaration:
174 	 * Only prefixes allowed are none and struct.
175 	 * Only relations allowed are pointer or alias.
176 	 */
177 	if (!streqn(decp->prefix, "struct") && !streqn(decp->prefix, ""))
178 		return (0);
179 	if (decp->rel != REL_POINTER && decp->rel != REL_ALIAS)
180 		return (0);
181 
182 	current.rel = decp->rel;
183 	current.prefix = decp->prefix;
184 	current.type = decp->type;
185 	current.name = decp->name;
186 	decp = &current;
187 	while (!check_self_reference(defp->def_name, decp, 0)) {
188 		dp = FINDVAL(defined, decp->type, cmptype);
189 
190 		/*
191 		 * Check if we found a definition.
192 		 */
193 		if (dp == NULL)
194 			return (0);
195 
196 		/*
197 		 * Check for valid prefix. We eventually need to see one
198 		 * and only one struct.
199 		 */
200 		if (streqn(decp->prefix, "")) {
201 			/*
202 			 * If the current declaration prefix in empty
203 			 * then the definition found must have an empty
204 			 * prefix or a struct prefix
205 			 */
206 			if (!streqn(dp->def.ty.old_prefix, "") &&
207 			    !streqn(dp->def.ty.old_prefix, "struct"))
208 				return (0);
209 		} else if (streqn(decp->prefix, "struct") &&
210 			!streqn(dp->def.ty.old_prefix, ""))
211 			/*
212 			 * if the current prefix is struct tne new prefix
213 			 * must be empty
214 			 */
215 			return (0);
216 		else if (!streqn(decp->prefix, "struct"))
217 			/* Should never get here */
218 			return (0);
219 
220 		/*
221 		 * Check for valid relation. We need to see one and
222 		 * only one REL_POINTER. The only valid relation types
223 		 * are REL_POINTER and REL_ALIAS.
224 		 */
225 		if (decp->rel == REL_POINTER && dp->def.ty.rel != REL_ALIAS)
226 			return (0);
227 		if (decp->rel == REL_ALIAS &&
228 			(dp->def.ty.rel != REL_ALIAS &&
229 			dp->def.ty.rel != REL_POINTER))
230 			return (0);
231 		if (decp->rel != REL_ALIAS && decp->rel != REL_POINTER)
232 			/* Should never get here */
233 			return (0);
234 
235 		/* Set up the current declaration */
236 		if (streqn(decp->prefix, ""))
237 			decp->prefix = dp->def.ty.old_prefix;
238 		decp->type = dp->def.ty.old_type;
239 		if (decp->rel == REL_ALIAS)
240 			decp->rel = dp->def.ty.rel;
241 	}
242 
243 	/* We have a self reference type */
244 	return (1);
245 }
246 
247 static void
248 def_struct(definition *defp)
249 {
250 	token tok;
251 	declaration dec;
252 	decl_list *decls;
253 	decl_list **tailp, *endp;
254 
255 	defp->def_kind = DEF_STRUCT;
256 
257 	scan(TOK_IDENT, &tok);
258 	defp->def_name = tok.str;
259 	scan(TOK_LBRACE, &tok);
260 	tailp = &defp->def.st.decls;
261 	defp->def.st.tail = NULL;
262 	do {
263 		get_declaration(&dec, DEF_STRUCT);
264 		decls = calloc(1, sizeof (decl_list));
265 		decls->decl = dec;
266 		/*
267 		 * Keep a referenct to the last declaration to check for
268 		 * tail recurrsion.
269 		 */
270 		endp = *tailp = decls;
271 		tailp = &decls->next;
272 		scan(TOK_SEMICOLON, &tok);
273 		peek(&tok);
274 	} while (tok.kind != TOK_RBRACE);
275 	*tailp = NULL;
276 	/*
277 	 * Check for tail recurse. If the last declaration refers to this
278 	 * structure then mark this stucture to convert the tail recursion
279 	 * to itteration.
280 	 */
281 	defp->def.st.self_pointer = is_self_reference(defp, &endp->decl);
282 	get_token(&tok);
283 	defp->def.st.tail = endp;
284 }
285 
286 static void
287 def_program(definition *defp)
288 {
289 	token tok;
290 	declaration dec;
291 	decl_list *decls;
292 	decl_list **tailp;
293 	version_list *vlist;
294 	version_list **vtailp;
295 	proc_list *plist;
296 	proc_list **ptailp;
297 	int num_args;
298 	bool_t isvoid = FALSE;	/* whether first argument is void */
299 	defp->def_kind = DEF_PROGRAM;
300 	scan(TOK_IDENT, &tok);
301 	defp->def_name = tok.str;
302 	scan(TOK_LBRACE, &tok);
303 	vtailp = &defp->def.pr.versions;
304 	tailp = &defp->def.st.decls;
305 	scan(TOK_VERSION, &tok);
306 	do {
307 		scan(TOK_IDENT, &tok);
308 		vlist = calloc(1, sizeof (version_list));
309 		vlist->vers_name = tok.str;
310 		scan(TOK_LBRACE, &tok);
311 		ptailp = &vlist->procs;
312 		do {
313 			/* get result type */
314 			plist = calloc(1, sizeof (proc_list));
315 			get_type(&plist->res_prefix, &plist->res_type,
316 			    DEF_RESULT);
317 			if (streq(plist->res_type, "opaque")) {
318 				error("illegal result type");
319 			}
320 			scan(TOK_IDENT, &tok);
321 			plist->proc_name = tok.str;
322 			scan(TOK_LPAREN, &tok);
323 			/* get args - first one */
324 			num_args = 1;
325 			isvoid = FALSE;
326 			/*
327 			 * type of DEF_PROGRAM in the first
328 			 * get_prog_declaration and DEF_STURCT in the next
329 			 * allows void as argument if it is the only argument
330 			 */
331 			get_prog_declaration(&dec, DEF_PROGRAM, num_args);
332 			if (streq(dec.type, "void"))
333 				isvoid = TRUE;
334 			decls = calloc(1, sizeof (decl_list));
335 			plist->args.decls = decls;
336 			decls->decl = dec;
337 			tailp = &decls->next;
338 			/* get args */
339 			while (peekscan(TOK_COMMA, &tok)) {
340 				num_args++;
341 				get_prog_declaration(&dec, DEF_STRUCT,
342 						    num_args);
343 				decls = calloc(1, sizeof (decl_list));
344 				decls->decl = dec;
345 				*tailp = decls;
346 				if (streq(dec.type, "void"))
347 					isvoid = TRUE;
348 				tailp = &decls->next;
349 			}
350 			/* multiple arguments are only allowed in newstyle */
351 			if (!newstyle && num_args > 1) {
352 				error("only one argument is allowed");
353 			}
354 			if (isvoid && num_args > 1) {
355 				error("illegal use of void "
356 				    "in program definition");
357 			}
358 			*tailp = NULL;
359 			scan(TOK_RPAREN, &tok);
360 			scan(TOK_EQUAL, &tok);
361 			scan_num(&tok);
362 			scan(TOK_SEMICOLON, &tok);
363 			plist->proc_num = tok.str;
364 			plist->arg_num = num_args;
365 			*ptailp = plist;
366 			ptailp = &plist->next;
367 			peek(&tok);
368 		} while (tok.kind != TOK_RBRACE);
369 		*ptailp = NULL;
370 		*vtailp = vlist;
371 		vtailp = &vlist->next;
372 		scan(TOK_RBRACE, &tok);
373 		scan(TOK_EQUAL, &tok);
374 		scan_num(&tok);
375 		vlist->vers_num = tok.str;
376 		/* make the argument structure name for each arg */
377 		for (plist = vlist->procs; plist != NULL; plist = plist->next) {
378 			plist->args.argname = make_argname(plist->proc_name,
379 							vlist->vers_num);
380 			/* free the memory ?? */
381 		}
382 		scan(TOK_SEMICOLON, &tok);
383 		scan2(TOK_VERSION, TOK_RBRACE, &tok);
384 	} while (tok.kind == TOK_VERSION);
385 	scan(TOK_EQUAL, &tok);
386 	scan_num(&tok);
387 	defp->def.pr.prog_num = tok.str;
388 	*vtailp = NULL;
389 }
390 
391 static void
392 def_enum(definition *defp)
393 {
394 	token tok;
395 	enumval_list *elist;
396 	enumval_list **tailp;
397 
398 	defp->def_kind = DEF_ENUM;
399 	scan(TOK_IDENT, &tok);
400 	defp->def_name = tok.str;
401 	scan(TOK_LBRACE, &tok);
402 	tailp = &defp->def.en.vals;
403 	do {
404 		scan(TOK_IDENT, &tok);
405 		elist = calloc(1, sizeof (enumval_list));
406 		elist->name = tok.str;
407 		elist->assignment = NULL;
408 		scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
409 		if (tok.kind == TOK_EQUAL) {
410 			scan_num(&tok);
411 			elist->assignment = tok.str;
412 			scan2(TOK_COMMA, TOK_RBRACE, &tok);
413 		}
414 		*tailp = elist;
415 		tailp = &elist->next;
416 	} while (tok.kind != TOK_RBRACE);
417 	*tailp = NULL;
418 }
419 
420 static void
421 def_const(definition *defp)
422 {
423 	token tok;
424 
425 	defp->def_kind = DEF_CONST;
426 	scan(TOK_IDENT, &tok);
427 	defp->def_name = tok.str;
428 	scan(TOK_EQUAL, &tok);
429 	scan2(TOK_IDENT, TOK_STRCONST, &tok);
430 	defp->def.co = tok.str;
431 }
432 
433 static void
434 def_union(definition *defp)
435 {
436 	token tok;
437 	declaration dec;
438 	case_list *cases;
439 	case_list **tailp;
440 	int flag;
441 
442 	defp->def_kind = DEF_UNION;
443 	scan(TOK_IDENT, &tok);
444 	defp->def_name = tok.str;
445 	scan(TOK_SWITCH, &tok);
446 	scan(TOK_LPAREN, &tok);
447 	get_declaration(&dec, DEF_UNION);
448 	defp->def.un.enum_decl = dec;
449 	tailp = &defp->def.un.cases;
450 	scan(TOK_RPAREN, &tok);
451 	scan(TOK_LBRACE, &tok);
452 	scan(TOK_CASE, &tok);
453 	while (tok.kind == TOK_CASE) {
454 		scan2(TOK_IDENT, TOK_CHARCONST, &tok);
455 		cases = calloc(1, sizeof (case_list));
456 		cases->case_name = tok.str;
457 		scan(TOK_COLON, &tok);
458 		/* now peek at next token */
459 		flag = 0;
460 		if (peekscan(TOK_CASE, &tok)) {
461 			do {
462 				scan2(TOK_IDENT, TOK_CHARCONST, &tok);
463 				cases->contflag = 1;
464 				/* continued case statement */
465 				*tailp = cases;
466 				tailp = &cases->next;
467 				cases = calloc(1, sizeof (case_list));
468 				cases->case_name = tok.str;
469 				scan(TOK_COLON, &tok);
470 			} while (peekscan(TOK_CASE, &tok));
471 		} else if (flag) {
472 			*tailp = cases;
473 			tailp = &cases->next;
474 			cases = calloc(1, sizeof (case_list));
475 		}
476 
477 		get_declaration(&dec, DEF_UNION);
478 		cases->case_decl = dec;
479 		cases->contflag = 0; /* no continued case statement */
480 		*tailp = cases;
481 		tailp = &cases->next;
482 		scan(TOK_SEMICOLON, &tok);
483 
484 		scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
485 	}
486 	*tailp = NULL;
487 	if (tok.kind == TOK_DEFAULT) {
488 		scan(TOK_COLON, &tok);
489 		get_declaration(&dec, DEF_UNION);
490 		defp->def.un.default_decl = calloc(1, sizeof (declaration));
491 		*defp->def.un.default_decl = dec;
492 		scan(TOK_SEMICOLON, &tok);
493 		scan(TOK_RBRACE, &tok);
494 	} else {
495 		defp->def.un.default_decl = NULL;
496 	}
497 }
498 
499 static char *reserved_words[] = {
500 	"array",
501 	"bytes",
502 	"destroy",
503 	"free",
504 	"getpos",
505 	"inline",
506 	"pointer",
507 	"reference",
508 	"setpos",
509 	"sizeof",
510 	"union",
511 	"vector",
512 	NULL
513 };
514 
515 static char *reserved_types[] = {
516 	"opaque",
517 	"string",
518 	NULL
519 };
520 
521 /*
522  * check that the given name is not one that would eventually result in
523  * xdr routines that would conflict with internal XDR routines.
524  */
525 static void
526 check_type_name(char *name, int new_type)
527 {
528 	int i;
529 	char tmp[100];
530 
531 	for (i = 0; reserved_words[i] != NULL; i++) {
532 		if (strcmp(name, reserved_words[i]) == 0) {
533 			(void) snprintf(tmp, sizeof (tmp),
534 				"illegal (reserved) name :\'%s\' "
535 				"in type definition",
536 				name);
537 			error(tmp);
538 		}
539 	}
540 	if (new_type) {
541 		for (i = 0; reserved_types[i] != NULL; i++) {
542 			if (strcmp(name, reserved_types[i]) == 0) {
543 				(void) snprintf(tmp, sizeof (tmp),
544 					"illegal (reserved) name :\'%s\' "
545 					"in type definition",
546 					name);
547 				error(tmp);
548 			}
549 		}
550 	}
551 }
552 
553 static void
554 def_typedef(definition *defp)
555 {
556 	declaration dec;
557 
558 	defp->def_kind = DEF_TYPEDEF;
559 	get_declaration(&dec, DEF_TYPEDEF);
560 	defp->def_name = dec.name;
561 	check_type_name(dec.name, 1);
562 	defp->def.ty.old_prefix = dec.prefix;
563 	defp->def.ty.old_type = dec.type;
564 	defp->def.ty.rel = dec.rel;
565 	defp->def.ty.array_max = dec.array_max;
566 }
567 
568 static void
569 get_declaration(declaration *dec, defkind dkind)
570 {
571 	token tok;
572 
573 	get_type(&dec->prefix, &dec->type, dkind);
574 	dec->rel = REL_ALIAS;
575 	if (streq(dec->type, "void"))
576 		return;
577 
578 	check_type_name(dec->type, 0);
579 	scan2(TOK_STAR, TOK_IDENT, &tok);
580 	if (tok.kind == TOK_STAR) {
581 		dec->rel = REL_POINTER;
582 		scan(TOK_IDENT, &tok);
583 	}
584 	dec->name = tok.str;
585 	if (peekscan(TOK_LBRACKET, &tok)) {
586 		if (dec->rel == REL_POINTER)
587 			error("no array-of-pointer declarations "
588 			    "-- use typedef");
589 		dec->rel = REL_VECTOR;
590 		scan_num(&tok);
591 		dec->array_max = tok.str;
592 		scan(TOK_RBRACKET, &tok);
593 	} else if (peekscan(TOK_LANGLE, &tok)) {
594 		if (dec->rel == REL_POINTER)
595 			error("no array-of-pointer declarations "
596 			    "-- use typedef");
597 		dec->rel = REL_ARRAY;
598 		if (peekscan(TOK_RANGLE, &tok)) {
599 			dec->array_max = "~0";	/* unspecified size, use max */
600 		} else {
601 			scan_num(&tok);
602 			dec->array_max = tok.str;
603 			scan(TOK_RANGLE, &tok);
604 		}
605 	}
606 	if (streq(dec->type, "opaque")) {
607 		if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
608 			error("array declaration expected");
609 		}
610 	} else if (streq(dec->type, "string")) {
611 		if (dec->rel != REL_ARRAY) {
612 			error("variable-length array declaration expected");
613 		}
614 	}
615 }
616 
617 static void
618 get_prog_declaration(declaration *dec, defkind dkind, int num)
619 {
620 	token tok;
621 	char name[sizeof (ARGNAME) + 10];
622 
623 	if (dkind == DEF_PROGRAM) {
624 		peek(&tok);
625 		if (tok.kind == TOK_RPAREN) { /* no arguments */
626 			dec->rel = REL_ALIAS;
627 			dec->type = "void";
628 			dec->prefix = NULL;
629 			dec->name = NULL;
630 			return;
631 		}
632 	}
633 	get_type(&dec->prefix, &dec->type, dkind);
634 	dec->rel = REL_ALIAS;
635 	if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
636 		dec->name = strdup(tok.str);
637 	else {
638 		/* default name of argument */
639 		(void) snprintf(name, sizeof (name), "%s%d", ARGNAME, num);
640 		dec->name = strdup(name);
641 	}
642 	if (dec->name == NULL)
643 		error("internal error -- out of memory");
644 
645 	if (streq(dec->type, "void"))
646 		return;
647 
648 	if (streq(dec->type, "opaque"))
649 		error("opaque -- illegal argument type");
650 	if (peekscan(TOK_STAR, &tok)) {
651 		if (streq(dec->type, "string")) {
652 			error("pointer to string not allowed "
653 			    "in program arguments\n");
654 		}
655 		dec->rel = REL_POINTER;
656 		if (peekscan(TOK_IDENT, &tok))
657 			/* optional name of argument */
658 			dec->name = strdup(tok.str);
659 	}
660 	if (peekscan(TOK_LANGLE, &tok)) {
661 		if (!streq(dec->type, "string")) {
662 			error("arrays cannot be declared as arguments "
663 			    "to procedures -- use typedef");
664 		}
665 		dec->rel = REL_ARRAY;
666 		if (peekscan(TOK_RANGLE, &tok)) {
667 			dec->array_max = "~0";
668 			/* unspecified size, use max */
669 		} else {
670 			scan_num(&tok);
671 			dec->array_max = tok.str;
672 			scan(TOK_RANGLE, &tok);
673 		}
674 	}
675 	if (streq(dec->type, "string")) {
676 		if (dec->rel != REL_ARRAY) {
677 			/*
678 			 * .x specifies just string as
679 			 * type of argument
680 			 * - make it string<>
681 			 */
682 			dec->rel = REL_ARRAY;
683 			dec->array_max = "~0"; /* unspecified size, use max */
684 		}
685 	}
686 }
687 
688 static void
689 get_type(char **prefixp, char **typep, defkind dkind)
690 {
691 	token tok;
692 
693 	*prefixp = NULL;
694 	get_token(&tok);
695 	switch (tok.kind) {
696 	case TOK_IDENT:
697 		*typep = tok.str;
698 		break;
699 	case TOK_STRUCT:
700 	case TOK_ENUM:
701 	case TOK_UNION:
702 		*prefixp = tok.str;
703 		scan(TOK_IDENT, &tok);
704 		*typep = tok.str;
705 		break;
706 	case TOK_UNSIGNED:
707 		unsigned_dec(typep);
708 		break;
709 	case TOK_SHORT:
710 		*typep = "short";
711 		(void) peekscan(TOK_INT, &tok);
712 		break;
713 	case TOK_LONG:
714 		*typep = "long";
715 		(void) peekscan(TOK_INT, &tok);
716 		break;
717 	case TOK_HYPER:
718 		*typep = "longlong_t";
719 		(void) peekscan(TOK_INT, &tok);
720 		break;
721 
722 	case TOK_VOID:
723 		if (dkind != DEF_UNION && dkind != DEF_PROGRAM &&
724 		    dkind != DEF_RESULT) {
725 			error("voids allowed only inside union and "
726 			    "program definitions with one argument");
727 		}
728 		*typep = tok.str;
729 		break;
730 	case TOK_ONEWAY:
731 		if (dkind != DEF_RESULT) {
732 			error("oneways allowed only inside result definitions");
733 		}
734 		*typep = tok.str;
735 		break;
736 	case TOK_STRING:
737 	case TOK_OPAQUE:
738 	case TOK_CHAR:
739 	case TOK_INT:
740 	case TOK_FLOAT:
741 	case TOK_DOUBLE:
742 	case TOK_BOOL:
743 	case TOK_QUAD:
744 		*typep = tok.str;
745 		break;
746 	default:
747 		error("expected type specifier");
748 	}
749 }
750 
751 static void
752 unsigned_dec(char **typep)
753 {
754 	token tok;
755 
756 	peek(&tok);
757 	switch (tok.kind) {
758 	case TOK_CHAR:
759 		get_token(&tok);
760 		*typep = "u_char";
761 		break;
762 	case TOK_SHORT:
763 		get_token(&tok);
764 		*typep = "u_short";
765 		(void) peekscan(TOK_INT, &tok);
766 		break;
767 	case TOK_LONG:
768 		get_token(&tok);
769 		*typep = "u_long";
770 		(void) peekscan(TOK_INT, &tok);
771 		break;
772 	case TOK_HYPER:
773 		get_token(&tok);
774 		*typep = "u_longlong_t";
775 		(void) peekscan(TOK_INT, &tok);
776 		break;
777 	case TOK_INT:
778 		get_token(&tok);
779 		*typep = "u_int";
780 		break;
781 	default:
782 		*typep = "u_int";
783 		break;
784 	}
785 }
786