1 /* $NetBSD: rpc_parse.c,v 1.15 2006/04/04 21:27:42 christos Exp $ */
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 or with the express written consent of
9 * Sun Microsystems, Inc.
11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
15 * Sun RPC is provided with no support and without any obligation on the
16 * part of Sun Microsystems, Inc. to assist in its use, correction,
17 * modification or enhancement.
19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 * OR ANY PART THEREOF.
23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 * or profits or other special, indirect and consequential damages, even if
25 * Sun has been advised of the possibility of such damages.
27 * Sun Microsystems, Inc.
29 * Mountain View, California 94043
32 #if HAVE_NBTOOL_CONFIG_H
33 #include "nbtool_config.h"
36 #include <sys/cdefs.h>
37 #if defined(__RCSID) && !defined(lint)
39 static char sccsid
[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
41 __RCSID("$NetBSD: rpc_parse.c,v 1.15 2006/04/04 21:27:42 christos Exp $");
46 * rpc_parse.c, Parser for the RPC protocol compiler
47 * Copyright (C) 1987 Sun Microsystems, Inc.
52 #include "rpc/types.h"
54 #include "rpc_parse.h"
59 static void isdefined
__P((definition
*));
60 static void def_struct
__P((definition
*));
61 static void def_program
__P((definition
*));
62 static void def_enum
__P((definition
*));
63 static void def_const
__P((definition
*));
64 static void def_union
__P((definition
*));
65 static void check_type_name
__P((char *, int));
66 static void def_typedef
__P((definition
*));
67 static void get_declaration
__P((declaration
*, defkind
));
68 static void get_prog_declaration
__P((declaration
*, defkind
, int));
69 static void get_type
__P((char **, char **, defkind
));
70 static void unsigned_dec
__P((char **));
73 * return the next definition you see
81 defp
= ALLOC(definition
);
106 error("definition keyword expected");
108 scan(TOK_SEMICOLON
, &tok
);
117 STOREVAL(&defined
, defp
);
129 defp
->def_kind
= DEF_STRUCT
;
131 scan(TOK_IDENT
, &tok
);
132 defp
->def_name
= tok
.str
;
133 scan(TOK_LBRACE
, &tok
);
134 tailp
= &defp
->def
.st
.decls
;
136 get_declaration(&dec
, DEF_STRUCT
);
137 decls
= ALLOC(decl_list
);
140 tailp
= &decls
->next
;
141 scan(TOK_SEMICOLON
, &tok
);
143 } while (tok
.kind
!= TOK_RBRACE
);
157 version_list
**vtailp
;
161 bool_t isvoid
= FALSE
; /* whether first argument is void */
162 defp
->def_kind
= DEF_PROGRAM
;
163 scan(TOK_IDENT
, &tok
);
164 defp
->def_name
= tok
.str
;
165 scan(TOK_LBRACE
, &tok
);
166 vtailp
= &defp
->def
.pr
.versions
;
167 tailp
= &defp
->def
.st
.decls
;
168 scan(TOK_VERSION
, &tok
);
170 scan(TOK_IDENT
, &tok
);
171 vlist
= ALLOC(version_list
);
172 vlist
->vers_name
= tok
.str
;
173 scan(TOK_LBRACE
, &tok
);
174 ptailp
= &vlist
->procs
;
176 /* get result type */
177 plist
= ALLOC(proc_list
);
178 get_type(&plist
->res_prefix
, &plist
->res_type
,
180 if (streq(plist
->res_type
, "opaque")) {
181 error("illegal result type");
183 scan(TOK_IDENT
, &tok
);
184 plist
->proc_name
= tok
.str
;
185 scan(TOK_LPAREN
, &tok
);
186 /* get args - first one */
189 /* type of DEF_PROGRAM in the first
190 * get_prog_declaration and DEF_STURCT in the next
191 * allows void as argument if it is the only argument */
192 get_prog_declaration(&dec
, DEF_PROGRAM
, num_args
);
193 if (streq(dec
.type
, "void"))
195 decls
= ALLOC(decl_list
);
196 plist
->args
.decls
= decls
;
198 tailp
= &decls
->next
;
200 while (peekscan(TOK_COMMA
, &tok
)) {
202 get_prog_declaration(&dec
, DEF_STRUCT
,
204 decls
= ALLOC(decl_list
);
207 if (streq(dec
.type
, "void"))
209 tailp
= &decls
->next
;
211 /* multiple arguments are only allowed in newstyle */
212 if (!newstyle
&& num_args
> 1) {
213 error("only one argument is allowed");
215 if (isvoid
&& num_args
> 1) {
216 error("illegal use of void in program definition");
219 scan(TOK_RPAREN
, &tok
);
220 scan(TOK_EQUAL
, &tok
);
222 scan(TOK_SEMICOLON
, &tok
);
223 plist
->proc_num
= tok
.str
;
224 plist
->arg_num
= num_args
;
226 ptailp
= &plist
->next
;
228 } while (tok
.kind
!= TOK_RBRACE
);
231 vtailp
= &vlist
->next
;
232 scan(TOK_RBRACE
, &tok
);
233 scan(TOK_EQUAL
, &tok
);
235 vlist
->vers_num
= tok
.str
;
236 /* make the argument structure name for each arg */
237 for (plist
= vlist
->procs
; plist
!= NULL
;
238 plist
= plist
->next
) {
239 plist
->args
.argname
= make_argname(plist
->proc_name
,
241 /* free the memory ?? */
243 scan(TOK_SEMICOLON
, &tok
);
244 scan2(TOK_VERSION
, TOK_RBRACE
, &tok
);
245 } while (tok
.kind
== TOK_VERSION
);
246 scan(TOK_EQUAL
, &tok
);
248 defp
->def
.pr
.prog_num
= tok
.str
;
259 enumval_list
**tailp
;
261 defp
->def_kind
= DEF_ENUM
;
262 scan(TOK_IDENT
, &tok
);
263 defp
->def_name
= tok
.str
;
264 scan(TOK_LBRACE
, &tok
);
265 tailp
= &defp
->def
.en
.vals
;
267 scan(TOK_IDENT
, &tok
);
268 elist
= ALLOC(enumval_list
);
269 elist
->name
= tok
.str
;
270 elist
->assignment
= NULL
;
271 scan3(TOK_COMMA
, TOK_RBRACE
, TOK_EQUAL
, &tok
);
272 if (tok
.kind
== TOK_EQUAL
) {
274 elist
->assignment
= tok
.str
;
275 scan2(TOK_COMMA
, TOK_RBRACE
, &tok
);
278 tailp
= &elist
->next
;
279 } while (tok
.kind
!= TOK_RBRACE
);
289 defp
->def_kind
= DEF_CONST
;
290 scan(TOK_IDENT
, &tok
);
291 defp
->def_name
= tok
.str
;
292 scan(TOK_EQUAL
, &tok
);
293 scan2(TOK_IDENT
, TOK_STRCONST
, &tok
);
294 defp
->def
.co
= tok
.str
;
306 defp
->def_kind
= DEF_UNION
;
307 scan(TOK_IDENT
, &tok
);
308 defp
->def_name
= tok
.str
;
309 scan(TOK_SWITCH
, &tok
);
310 scan(TOK_LPAREN
, &tok
);
311 get_declaration(&dec
, DEF_UNION
);
312 defp
->def
.un
.enum_decl
= dec
;
313 tailp
= &defp
->def
.un
.cases
;
314 scan(TOK_RPAREN
, &tok
);
315 scan(TOK_LBRACE
, &tok
);
316 scan(TOK_CASE
, &tok
);
317 while (tok
.kind
== TOK_CASE
) {
318 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
319 cases
= ALLOC(case_list
);
320 cases
->case_name
= tok
.str
;
321 scan(TOK_COLON
, &tok
);
322 /* now peek at next token */
323 if (peekscan(TOK_CASE
, &tok
)) {
326 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
327 cases
->contflag
= 1; /* continued case
330 tailp
= &cases
->next
;
331 cases
= ALLOC(case_list
);
332 cases
->case_name
= tok
.str
;
333 scan(TOK_COLON
, &tok
);
335 } while (peekscan(TOK_CASE
, &tok
));
337 get_declaration(&dec
, DEF_UNION
);
338 cases
->case_decl
= dec
;
339 cases
->contflag
= 0; /* no continued case statement */
341 tailp
= &cases
->next
;
342 scan(TOK_SEMICOLON
, &tok
);
344 scan3(TOK_CASE
, TOK_DEFAULT
, TOK_RBRACE
, &tok
);
347 if (tok
.kind
== TOK_DEFAULT
) {
348 scan(TOK_COLON
, &tok
);
349 get_declaration(&dec
, DEF_UNION
);
350 defp
->def
.un
.default_decl
= ALLOC(declaration
);
351 *defp
->def
.un
.default_decl
= dec
;
352 scan(TOK_SEMICOLON
, &tok
);
353 scan(TOK_RBRACE
, &tok
);
355 defp
->def
.un
.default_decl
= NULL
;
359 static char *reserved_words
[] = {
375 static char *reserved_types
[] = {
380 /* check that the given name is not one that would eventually result in
381 xdr routines that would conflict with internal XDR routines. */
383 check_type_name(name
, new_type
)
390 for (i
= 0; reserved_words
[i
] != NULL
; i
++) {
391 if (strcmp(name
, reserved_words
[i
]) == 0) {
393 "illegal (reserved) name :\'%s\' in type definition", name
);
398 for (i
= 0; reserved_types
[i
] != NULL
; i
++) {
399 if (strcmp(name
, reserved_types
[i
]) == 0) {
401 "illegal (reserved) name :\'%s\' in type definition", name
);
414 defp
->def_kind
= DEF_TYPEDEF
;
415 get_declaration(&dec
, DEF_TYPEDEF
);
416 defp
->def_name
= dec
.name
;
417 check_type_name(dec
.name
, 1);
418 defp
->def
.ty
.old_prefix
= dec
.prefix
;
419 defp
->def
.ty
.old_type
= dec
.type
;
420 defp
->def
.ty
.rel
= dec
.rel
;
421 defp
->def
.ty
.array_max
= dec
.array_max
;
425 get_declaration(dec
, dkind
)
431 get_type(&dec
->prefix
, &dec
->type
, dkind
);
432 dec
->rel
= REL_ALIAS
;
433 if (streq(dec
->type
, "void")) {
436 check_type_name(dec
->type
, 0);
438 scan2(TOK_STAR
, TOK_IDENT
, &tok
);
439 if (tok
.kind
== TOK_STAR
) {
440 dec
->rel
= REL_POINTER
;
441 scan(TOK_IDENT
, &tok
);
444 if (peekscan(TOK_LBRACKET
, &tok
)) {
445 if (dec
->rel
== REL_POINTER
) {
446 error("no array-of-pointer declarations -- use typedef");
448 dec
->rel
= REL_VECTOR
;
450 dec
->array_max
= tok
.str
;
451 scan(TOK_RBRACKET
, &tok
);
453 if (peekscan(TOK_LANGLE
, &tok
)) {
454 if (dec
->rel
== REL_POINTER
) {
455 error("no array-of-pointer declarations -- use typedef");
457 dec
->rel
= REL_ARRAY
;
458 if (peekscan(TOK_RANGLE
, &tok
)) {
459 dec
->array_max
= "(u_int)~0";
460 /* unspecified size, use * max */
463 dec
->array_max
= tok
.str
;
464 scan(TOK_RANGLE
, &tok
);
467 if (streq(dec
->type
, "opaque")) {
468 if (dec
->rel
!= REL_ARRAY
&& dec
->rel
!= REL_VECTOR
) {
469 error("array declaration expected");
472 if (streq(dec
->type
, "string")) {
473 if (dec
->rel
!= REL_ARRAY
) {
474 error("variable-length array declaration expected");
480 get_prog_declaration(dec
, dkind
, num
)
483 int num
; /* arg number */
486 char name
[255]; /* argument name */
488 if (dkind
== DEF_PROGRAM
) {
490 if (tok
.kind
== TOK_RPAREN
) { /* no arguments */
491 dec
->rel
= REL_ALIAS
;
498 get_type(&dec
->prefix
, &dec
->type
, dkind
);
499 dec
->rel
= REL_ALIAS
;
500 if (peekscan(TOK_IDENT
, &tok
)) /* optional name of argument */
501 strcpy(name
, tok
.str
);
503 sprintf(name
, "%s%d", ARGNAME
, num
); /* default name of
506 dec
->name
= (char *) strdup(name
);
508 if (streq(dec
->type
, "void")) {
511 if (streq(dec
->type
, "opaque")) {
512 error("opaque -- illegal argument type");
514 if (peekscan(TOK_STAR
, &tok
)) {
515 if (streq(dec
->type
, "string")) {
516 error("pointer to string not allowed in program arguments\n");
518 dec
->rel
= REL_POINTER
;
519 if (peekscan(TOK_IDENT
, &tok
)) /* optional name of argument */
520 dec
->name
= (char *) strdup(tok
.str
);
522 if (peekscan(TOK_LANGLE
, &tok
)) {
523 if (!streq(dec
->type
, "string")) {
524 error("arrays cannot be declared as arguments to procedures -- use typedef");
526 dec
->rel
= REL_ARRAY
;
527 if (peekscan(TOK_RANGLE
, &tok
)) {
528 dec
->array_max
= "(u_int)~0";
529 /* unspecified size, use max */
532 dec
->array_max
= tok
.str
;
533 scan(TOK_RANGLE
, &tok
);
536 if (streq(dec
->type
, "string")) {
537 if (dec
->rel
!= REL_ARRAY
) { /* .x specifies just string as
538 * type of argument - make it
540 dec
->rel
= REL_ARRAY
;
541 dec
->array_max
= "(u_int)~0";
542 /* unspecified size, use max */
550 get_type(prefixp
, typep
, dkind
)
567 scan(TOK_IDENT
, &tok
);
575 (void) peekscan(TOK_INT
, &tok
);
579 (void) peekscan(TOK_INT
, &tok
);
582 *typep
= "longlong_t";
583 (void) peekscan(TOK_INT
, &tok
);
586 if (dkind
!= DEF_UNION
&& dkind
!= DEF_PROGRAM
) {
587 error("voids allowed only inside union and program definitions with one argument");
602 error("expected type specifier");
621 (void) peekscan(TOK_INT
, &tok
);
626 (void) peekscan(TOK_INT
, &tok
);
630 *typep
= "u_longlong_t";
631 (void) peekscan(TOK_INT
, &tok
);