xref: /netbsd-src/usr.bin/rpcgen/rpc_parse.c (revision ce63d6c20fc4ec8ddc95c84bb229e3c4ecf82b69)
1 /* @(#)rpc_parse.c	2.1 88/08/01 4.0 RPCSRC */
2 /*
3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4  * unrestricted use provided that this legend is included on all tape
5  * media and as a part of the software program in whole or part.  Users
6  * may copy or modify Sun RPC without charge, but are not authorized
7  * to license or distribute it to anyone else except as part of a product or
8  * program developed by the user.
9  *
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  *
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  *
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  *
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30 #ifndef lint
31 static char sccsid[] = "@(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI";
32 #endif
33 
34 /*
35  * rpc_parse.c, Parser for the RPC protocol compiler
36  * Copyright (C) 1987 Sun Microsystems, Inc.
37  */
38 #include <stdio.h>
39 #include "rpc_util.h"
40 #include "rpc_scan.h"
41 #include "rpc_parse.h"
42 
43 static int isdefined(), def_struct(), def_program(), def_enum(), def_const(),
44 	   def_union(), def_typedef(), get_declaration(), get_type(),
45 	   unsigned_dec();
46 /*
47  * return the next definition you see
48  */
49 definition *
50 get_definition()
51 {
52 	definition *defp;
53 	token tok;
54 
55 	defp = ALLOC(definition);
56 	get_token(&tok);
57 	switch (tok.kind) {
58 	case TOK_STRUCT:
59 		def_struct(defp);
60 		break;
61 	case TOK_UNION:
62 		def_union(defp);
63 		break;
64 	case TOK_TYPEDEF:
65 		def_typedef(defp);
66 		break;
67 	case TOK_ENUM:
68 		def_enum(defp);
69 		break;
70 	case TOK_PROGRAM:
71 		def_program(defp);
72 		break;
73 	case TOK_CONST:
74 		def_const(defp);
75 		break;
76 	case TOK_EOF:
77 		return (NULL);
78 		break;
79 	default:
80 		error("definition keyword expected");
81 	}
82 	scan(TOK_SEMICOLON, &tok);
83 	isdefined(defp);
84 	return (defp);
85 }
86 
87 static
88 isdefined(defp)
89 	definition *defp;
90 {
91 	STOREVAL(&defined, defp);
92 }
93 
94 
95 static
96 def_struct(defp)
97 	definition *defp;
98 {
99 	token tok;
100 	declaration dec;
101 	decl_list *decls;
102 	decl_list **tailp;
103 
104 	defp->def_kind = DEF_STRUCT;
105 
106 	scan(TOK_IDENT, &tok);
107 	defp->def_name = tok.str;
108 	scan(TOK_LBRACE, &tok);
109 	tailp = &defp->def.st.decls;
110 	do {
111 		get_declaration(&dec, DEF_STRUCT);
112 		decls = ALLOC(decl_list);
113 		decls->decl = dec;
114 		*tailp = decls;
115 		tailp = &decls->next;
116 		scan(TOK_SEMICOLON, &tok);
117 		peek(&tok);
118 	} while (tok.kind != TOK_RBRACE);
119 	get_token(&tok);
120 	*tailp = NULL;
121 }
122 
123 static
124 def_program(defp)
125 	definition *defp;
126 {
127 	token tok;
128 	version_list *vlist;
129 	version_list **vtailp;
130 	proc_list *plist;
131 	proc_list **ptailp;
132 
133 	defp->def_kind = DEF_PROGRAM;
134 	scan(TOK_IDENT, &tok);
135 	defp->def_name = tok.str;
136 	scan(TOK_LBRACE, &tok);
137 	vtailp = &defp->def.pr.versions;
138 	scan(TOK_VERSION, &tok);
139 	do {
140 		scan(TOK_IDENT, &tok);
141 		vlist = ALLOC(version_list);
142 		vlist->vers_name = tok.str;
143 		scan(TOK_LBRACE, &tok);
144 		ptailp = &vlist->procs;
145 		do {
146 			plist = ALLOC(proc_list);
147 			get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
148 			if (streq(plist->res_type, "opaque")) {
149 				error("illegal result type");
150 			}
151 			scan(TOK_IDENT, &tok);
152 			plist->proc_name = tok.str;
153 			scan(TOK_LPAREN, &tok);
154 			get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
155 			if (streq(plist->arg_type, "opaque")) {
156 				error("illegal argument type");
157 			}
158 			scan(TOK_RPAREN, &tok);
159 			scan(TOK_EQUAL, &tok);
160 			scan_num(&tok);
161 			scan(TOK_SEMICOLON, &tok);
162 			plist->proc_num = tok.str;
163 			*ptailp = plist;
164 			ptailp = &plist->next;
165 			peek(&tok);
166 		} while (tok.kind != TOK_RBRACE);
167 		*vtailp = vlist;
168 		vtailp = &vlist->next;
169 		scan(TOK_RBRACE, &tok);
170 		scan(TOK_EQUAL, &tok);
171 		scan_num(&tok);
172 		vlist->vers_num = tok.str;
173 		scan(TOK_SEMICOLON, &tok);
174 		scan2(TOK_VERSION, TOK_RBRACE, &tok);
175 	} while (tok.kind == TOK_VERSION);
176 	scan(TOK_EQUAL, &tok);
177 	scan_num(&tok);
178 	defp->def.pr.prog_num = tok.str;
179 	*vtailp = NULL;
180 }
181 
182 static
183 def_enum(defp)
184 	definition *defp;
185 {
186 	token tok;
187 	enumval_list *elist;
188 	enumval_list **tailp;
189 
190 	defp->def_kind = DEF_ENUM;
191 	scan(TOK_IDENT, &tok);
192 	defp->def_name = tok.str;
193 	scan(TOK_LBRACE, &tok);
194 	tailp = &defp->def.en.vals;
195 	do {
196 		scan(TOK_IDENT, &tok);
197 		elist = ALLOC(enumval_list);
198 		elist->name = tok.str;
199 		elist->assignment = NULL;
200 		scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
201 		if (tok.kind == TOK_EQUAL) {
202 			scan_num(&tok);
203 			elist->assignment = tok.str;
204 			scan2(TOK_COMMA, TOK_RBRACE, &tok);
205 		}
206 		*tailp = elist;
207 		tailp = &elist->next;
208 	} while (tok.kind != TOK_RBRACE);
209 	*tailp = NULL;
210 }
211 
212 static
213 def_const(defp)
214 	definition *defp;
215 {
216 	token tok;
217 
218 	defp->def_kind = DEF_CONST;
219 	scan(TOK_IDENT, &tok);
220 	defp->def_name = tok.str;
221 	scan(TOK_EQUAL, &tok);
222 	scan2(TOK_IDENT, TOK_STRCONST, &tok);
223 	defp->def.co = tok.str;
224 }
225 
226 static
227 def_union(defp)
228 	definition *defp;
229 {
230 	token tok;
231 	declaration dec;
232 	case_list *cases;
233 	case_list **tailp;
234 
235 	defp->def_kind = DEF_UNION;
236 	scan(TOK_IDENT, &tok);
237 	defp->def_name = tok.str;
238 	scan(TOK_SWITCH, &tok);
239 	scan(TOK_LPAREN, &tok);
240 	get_declaration(&dec, DEF_UNION);
241 	defp->def.un.enum_decl = dec;
242 	tailp = &defp->def.un.cases;
243 	scan(TOK_RPAREN, &tok);
244 	scan(TOK_LBRACE, &tok);
245 	scan(TOK_CASE, &tok);
246 	while (tok.kind == TOK_CASE) {
247 		scan(TOK_IDENT, &tok);
248 		cases = ALLOC(case_list);
249 		cases->case_name = tok.str;
250 		scan(TOK_COLON, &tok);
251 		get_declaration(&dec, DEF_UNION);
252 		cases->case_decl = dec;
253 		*tailp = cases;
254 		tailp = &cases->next;
255 		scan(TOK_SEMICOLON, &tok);
256 		scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
257 	}
258 	*tailp = NULL;
259 	if (tok.kind == TOK_DEFAULT) {
260 		scan(TOK_COLON, &tok);
261 		get_declaration(&dec, DEF_UNION);
262 		defp->def.un.default_decl = ALLOC(declaration);
263 		*defp->def.un.default_decl = dec;
264 		scan(TOK_SEMICOLON, &tok);
265 		scan(TOK_RBRACE, &tok);
266 	} else {
267 		defp->def.un.default_decl = NULL;
268 	}
269 }
270 
271 
272 static
273 def_typedef(defp)
274 	definition *defp;
275 {
276 	declaration dec;
277 
278 	defp->def_kind = DEF_TYPEDEF;
279 	get_declaration(&dec, DEF_TYPEDEF);
280 	defp->def_name = dec.name;
281 	defp->def.ty.old_prefix = dec.prefix;
282 	defp->def.ty.old_type = dec.type;
283 	defp->def.ty.rel = dec.rel;
284 	defp->def.ty.array_max = dec.array_max;
285 }
286 
287 
288 static
289 get_declaration(dec, dkind)
290 	declaration *dec;
291 	defkind dkind;
292 {
293 	token tok;
294 
295 	get_type(&dec->prefix, &dec->type, dkind);
296 	dec->rel = REL_ALIAS;
297 	if (streq(dec->type, "void")) {
298 		return;
299 	}
300 	scan2(TOK_STAR, TOK_IDENT, &tok);
301 	if (tok.kind == TOK_STAR) {
302 		dec->rel = REL_POINTER;
303 		scan(TOK_IDENT, &tok);
304 	}
305 	dec->name = tok.str;
306 	if (peekscan(TOK_LBRACKET, &tok)) {
307 		if (dec->rel == REL_POINTER) {
308 			error("no array-of-pointer declarations -- use typedef");
309 		}
310 		dec->rel = REL_VECTOR;
311 		scan_num(&tok);
312 		dec->array_max = tok.str;
313 		scan(TOK_RBRACKET, &tok);
314 	} else if (peekscan(TOK_LANGLE, &tok)) {
315 		if (dec->rel == REL_POINTER) {
316 			error("no array-of-pointer declarations -- use typedef");
317 		}
318 		dec->rel = REL_ARRAY;
319 		if (peekscan(TOK_RANGLE, &tok)) {
320 			dec->array_max = "~0";	/* unspecified size, use max */
321 		} else {
322 			scan_num(&tok);
323 			dec->array_max = tok.str;
324 			scan(TOK_RANGLE, &tok);
325 		}
326 	}
327 	if (streq(dec->type, "opaque")) {
328 		if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
329 			error("array declaration expected");
330 		}
331 	} else if (streq(dec->type, "string")) {
332 		if (dec->rel != REL_ARRAY) {
333 			error("variable-length array declaration expected");
334 		}
335 	}
336 }
337 
338 
339 static
340 get_type(prefixp, typep, dkind)
341 	char **prefixp;
342 	char **typep;
343 	defkind dkind;
344 {
345 	token tok;
346 
347 	*prefixp = NULL;
348 	get_token(&tok);
349 	switch (tok.kind) {
350 	case TOK_IDENT:
351 		*typep = tok.str;
352 		break;
353 	case TOK_STRUCT:
354 	case TOK_ENUM:
355 	case TOK_UNION:
356 		*prefixp = tok.str;
357 		scan(TOK_IDENT, &tok);
358 		*typep = tok.str;
359 		break;
360 	case TOK_UNSIGNED:
361 		unsigned_dec(typep);
362 		break;
363 	case TOK_SHORT:
364 		*typep = "short";
365 		(void) peekscan(TOK_INT, &tok);
366 		break;
367 	case TOK_LONG:
368 		*typep = "long";
369 		(void) peekscan(TOK_INT, &tok);
370 		break;
371 	case TOK_VOID:
372 		if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
373 			error("voids allowed only inside union and program definitions");
374 		}
375 		*typep = tok.str;
376 		break;
377 	case TOK_STRING:
378 	case TOK_OPAQUE:
379 	case TOK_CHAR:
380 	case TOK_INT:
381 	case TOK_FLOAT:
382 	case TOK_DOUBLE:
383 	case TOK_BOOL:
384 		*typep = tok.str;
385 		break;
386 	default:
387 		error("expected type specifier");
388 	}
389 }
390 
391 
392 static
393 unsigned_dec(typep)
394 	char **typep;
395 {
396 	token tok;
397 
398 	peek(&tok);
399 	switch (tok.kind) {
400 	case TOK_CHAR:
401 		get_token(&tok);
402 		*typep = "u_char";
403 		break;
404 	case TOK_SHORT:
405 		get_token(&tok);
406 		*typep = "u_short";
407 		(void) peekscan(TOK_INT, &tok);
408 		break;
409 	case TOK_LONG:
410 		get_token(&tok);
411 		*typep = "u_long";
412 		(void) peekscan(TOK_INT, &tok);
413 		break;
414 	case TOK_INT:
415 		get_token(&tok);
416 		*typep = "u_int";
417 		break;
418 	default:
419 		*typep = "u_int";
420 		break;
421 	}
422 }
423