2 * Copyright (c) 2009, Sun Microsystems, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of Sun Microsystems, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
30 static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
34 * rpc_parse.c, Parser for the RPC protocol compiler
35 * Copyright (C) 1987 Sun Microsystems, Inc.
39 #include "rpc/types.h"
41 #include "rpc_parse.h"
47 extern char *make_argname();
48 extern char *strdup();
51 static void isdefined(definition *defp);
52 static void def_struct(definition *defp);
53 static void def_program(definition *defp);
54 static void def_enum(definition *defp);
55 static void def_const(definition *defp);
56 static void def_union(definition *defp);
57 static void check_type_name(char *name, int new_type);
58 static void def_typedef(definition *defp);
59 static void get_declaration(declaration *dec, defkind dkind);
60 static void get_prog_declaration(declaration *dec, defkind dkind, int num);
61 static void get_type(char **prefixp, char **typep, defkind dkind);
62 static void unsigned_dec(char **typep);
65 * return the next definition you see
73 defp = ALLOC(definition);
98 error("definition keyword expected");
100 scan(TOK_SEMICOLON, &tok);
106 isdefined(definition *defp)
108 STOREVAL(&defined, defp);
112 def_struct(definition *defp)
119 defp->def_kind = DEF_STRUCT;
121 scan(TOK_IDENT, &tok);
122 defp->def_name = tok.str;
123 scan(TOK_LBRACE, &tok);
124 tailp = &defp->def.st.decls;
126 get_declaration(&dec, DEF_STRUCT);
127 decls = ALLOC(decl_list);
130 tailp = &decls->next;
131 scan(TOK_SEMICOLON, &tok);
133 } while (tok.kind != TOK_RBRACE);
139 def_program(definition *defp)
146 version_list **vtailp;
150 bool_t isvoid = FALSE; /* whether first argument is void */
151 defp->def_kind = DEF_PROGRAM;
152 scan(TOK_IDENT, &tok);
153 defp->def_name = tok.str;
154 scan(TOK_LBRACE, &tok);
155 vtailp = &defp->def.pr.versions;
156 tailp = &defp->def.st.decls;
157 scan(TOK_VERSION, &tok);
159 scan(TOK_IDENT, &tok);
160 vlist = ALLOC(version_list);
161 vlist->vers_name = tok.str;
162 scan(TOK_LBRACE, &tok);
163 ptailp = &vlist->procs;
165 /* get result type */
166 plist = ALLOC(proc_list);
167 get_type(&plist->res_prefix, &plist->res_type,
169 if (streq(plist->res_type, "opaque")) {
170 error("illegal result type");
172 scan(TOK_IDENT, &tok);
173 plist->proc_name = tok.str;
174 scan(TOK_LPAREN, &tok);
175 /* get args - first one*/
178 /* type of DEF_PROGRAM in the first
179 * get_prog_declaration and DEF_STURCT in the next
180 * allows void as argument if it is the only argument
182 get_prog_declaration(&dec, DEF_PROGRAM, num_args);
183 if (streq(dec.type, "void"))
185 decls = ALLOC(decl_list);
186 plist->args.decls = decls;
188 tailp = &decls->next;
190 while(peekscan(TOK_COMMA, &tok)) {
192 get_prog_declaration(&dec, DEF_STRUCT,
194 decls = ALLOC(decl_list);
197 if (streq(dec.type, "void"))
199 tailp = &decls->next;
201 /* multiple arguments are only allowed in newstyle */
202 if( !newstyle && num_args > 1 ) {
203 error("only one argument is allowed" );
205 if (isvoid && num_args > 1) {
206 error("illegal use of void in program definition");
209 scan(TOK_RPAREN, &tok);
210 scan(TOK_EQUAL, &tok);
212 scan(TOK_SEMICOLON, &tok);
213 plist->proc_num = tok.str;
214 plist->arg_num = num_args;
216 ptailp = &plist->next;
218 } while (tok.kind != TOK_RBRACE);
221 vtailp = &vlist->next;
222 scan(TOK_RBRACE, &tok);
223 scan(TOK_EQUAL, &tok);
225 vlist->vers_num = tok.str;
226 /* make the argument structure name for each arg*/
227 for(plist = vlist->procs; plist != NULL;
228 plist = plist->next) {
229 plist->args.argname = make_argname(plist->proc_name,
231 /* free the memory ??*/
233 scan(TOK_SEMICOLON, &tok);
234 scan2(TOK_VERSION, TOK_RBRACE, &tok);
235 } while (tok.kind == TOK_VERSION);
236 scan(TOK_EQUAL, &tok);
238 defp->def.pr.prog_num = tok.str;
244 def_enum(definition *defp)
248 enumval_list **tailp;
250 defp->def_kind = DEF_ENUM;
251 scan(TOK_IDENT, &tok);
252 defp->def_name = tok.str;
253 scan(TOK_LBRACE, &tok);
254 tailp = &defp->def.en.vals;
256 scan(TOK_IDENT, &tok);
257 elist = ALLOC(enumval_list);
258 elist->name = tok.str;
259 elist->assignment = NULL;
260 scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
261 if (tok.kind == TOK_EQUAL) {
263 elist->assignment = tok.str;
264 scan2(TOK_COMMA, TOK_RBRACE, &tok);
267 tailp = &elist->next;
268 } while (tok.kind != TOK_RBRACE);
273 def_const(definition *defp)
277 defp->def_kind = DEF_CONST;
278 scan(TOK_IDENT, &tok);
279 defp->def_name = tok.str;
280 scan(TOK_EQUAL, &tok);
281 scan2(TOK_IDENT, TOK_STRCONST, &tok);
282 defp->def.co = tok.str;
286 def_union(definition *defp)
293 defp->def_kind = DEF_UNION;
294 scan(TOK_IDENT, &tok);
295 defp->def_name = tok.str;
296 scan(TOK_SWITCH, &tok);
297 scan(TOK_LPAREN, &tok);
298 get_declaration(&dec, DEF_UNION);
299 defp->def.un.enum_decl = dec;
300 tailp = &defp->def.un.cases;
301 scan(TOK_RPAREN, &tok);
302 scan(TOK_LBRACE, &tok);
303 scan(TOK_CASE, &tok);
304 while (tok.kind == TOK_CASE) {
305 scan2(TOK_IDENT, TOK_CHARCONST, &tok);
306 cases = ALLOC(case_list);
307 cases->case_name = tok.str;
308 scan(TOK_COLON, &tok);
309 /* now peek at next token */
310 if(peekscan(TOK_CASE,&tok))
315 scan2(TOK_IDENT, TOK_CHARCONST, &tok);
316 cases->contflag=1; /* continued case statement */
318 tailp = &cases->next;
319 cases = ALLOC(case_list);
320 cases->case_name = tok.str;
321 scan(TOK_COLON, &tok);
323 }while(peekscan(TOK_CASE,&tok));
326 get_declaration(&dec, DEF_UNION);
327 cases->case_decl = dec;
328 cases->contflag=0; /* no continued case statement */
330 tailp = &cases->next;
331 scan(TOK_SEMICOLON, &tok);
333 scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
336 if (tok.kind == TOK_DEFAULT) {
337 scan(TOK_COLON, &tok);
338 get_declaration(&dec, DEF_UNION);
339 defp->def.un.default_decl = ALLOC(declaration);
340 *defp->def.un.default_decl = dec;
341 scan(TOK_SEMICOLON, &tok);
342 scan(TOK_RBRACE, &tok);
344 defp->def.un.default_decl = NULL;
348 static char* reserved_words[] =
365 static char* reserved_types[] =
372 /* check that the given name is not one that would eventually result in
373 xdr routines that would conflict with internal XDR routines. */
375 check_type_name(char *name, int new_type)
380 for( i = 0; reserved_words[i] != NULL; i++ ) {
381 if( strcmp( name, reserved_words[i] ) == 0 ) {
383 "illegal (reserved) name :\'%s\' in type definition", name );
388 for( i = 0; reserved_types[i] != NULL; i++ ) {
389 if( strcmp( name, reserved_types[i] ) == 0 ) {
391 "illegal (reserved) name :\'%s\' in type definition", name );
399 def_typedef(definition *defp)
403 defp->def_kind = DEF_TYPEDEF;
404 get_declaration(&dec, DEF_TYPEDEF);
405 defp->def_name = dec.name;
406 check_type_name( dec.name, 1 );
407 defp->def.ty.old_prefix = dec.prefix;
408 defp->def.ty.old_type = dec.type;
409 defp->def.ty.rel = dec.rel;
410 defp->def.ty.array_max = dec.array_max;
414 get_declaration(declaration *dec, defkind dkind)
418 get_type(&dec->prefix, &dec->type, dkind);
419 dec->rel = REL_ALIAS;
420 if (streq(dec->type, "void")) {
424 check_type_name( dec->type, 0 );
426 scan2(TOK_STAR, TOK_IDENT, &tok);
427 if (tok.kind == TOK_STAR) {
428 dec->rel = REL_POINTER;
429 scan(TOK_IDENT, &tok);
432 if (peekscan(TOK_LBRACKET, &tok)) {
433 if (dec->rel == REL_POINTER) {
434 error("no array-of-pointer declarations -- use typedef");
436 dec->rel = REL_VECTOR;
438 dec->array_max = tok.str;
439 scan(TOK_RBRACKET, &tok);
440 } else if (peekscan(TOK_LANGLE, &tok)) {
441 if (dec->rel == REL_POINTER) {
442 error("no array-of-pointer declarations -- use typedef");
444 dec->rel = REL_ARRAY;
445 if (peekscan(TOK_RANGLE, &tok)) {
446 dec->array_max = "~0"; /* unspecified size, use max */
449 dec->array_max = tok.str;
450 scan(TOK_RANGLE, &tok);
453 if (streq(dec->type, "opaque")) {
454 if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
455 error("array declaration expected");
457 } else if (streq(dec->type, "string")) {
458 if (dec->rel != REL_ARRAY) {
459 error("variable-length array declaration expected");
466 get_prog_declaration(declaration *dec, defkind dkind, int num)
469 char name[10]; /* argument name */
471 if (dkind == DEF_PROGRAM) {
473 if (tok.kind == TOK_RPAREN) { /* no arguments */
474 dec->rel = REL_ALIAS;
481 get_type(&dec->prefix, &dec->type, dkind);
482 dec->rel = REL_ALIAS;
483 if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
484 strcpy(name, tok.str);
486 sprintf(name, "%s%d", ARGNAME, num); /* default name of argument */
488 dec->name = (char *) strdup(name);
490 if (streq(dec->type, "void")) {
494 if (streq(dec->type, "opaque")) {
495 error("opaque -- illegal argument type");
497 if (peekscan(TOK_STAR, &tok)) {
498 if (streq(dec->type, "string")) {
499 error("pointer to string not allowed in program arguments\n");
501 dec->rel = REL_POINTER;
502 if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
503 dec->name = strdup(tok.str);
505 if (peekscan(TOK_LANGLE, &tok)) {
506 if (!streq(dec->type, "string")) {
507 error("arrays cannot be declared as arguments to procedures -- use typedef");
509 dec->rel = REL_ARRAY;
510 if (peekscan(TOK_RANGLE, &tok)) {
511 dec->array_max = "~0";/* unspecified size, use max */
514 dec->array_max = tok.str;
515 scan(TOK_RANGLE, &tok);
518 if (streq(dec->type, "string")) {
519 if (dec->rel != REL_ARRAY) { /* .x specifies just string as
523 dec->rel = REL_ARRAY;
524 dec->array_max = "~0";/* unspecified size, use max */
532 get_type(char **prefixp, char **typep, defkind dkind)
546 scan(TOK_IDENT, &tok);
554 (void) peekscan(TOK_INT, &tok);
558 (void) peekscan(TOK_INT, &tok);
561 if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
562 error("voids allowed only inside union and program definitions with one argument");
576 error("expected type specifier");
581 unsigned_dec(char **typep)
594 (void) peekscan(TOK_INT, &tok);
599 (void) peekscan(TOK_INT, &tok);