2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part. Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user.
9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10 * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13 * Sun RPC is provided with no support and without any obligation on the
14 * part of Sun Microsystems, Inc. to assist in its use, correction,
15 * modification or enhancement.
17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19 * OR ANY PART THEREOF.
21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22 * or profits or other special, indirect and consequential damages, even if
23 * Sun has been advised of the possibility of such damages.
25 * Sun Microsystems, Inc.
27 * Mountain View, California 94043
29 * @(#)rpc_parse.c 1.12 93/07/05 SMI; 1.8 89/02/22 (C) 1987 SMI
30 * $FreeBSD: src/usr.bin/rpcgen/rpc_parse.c,v 1.12 2005/11/13 21:17:24 dwmalone Exp $
34 * rpc_parse.c, Parser for the RPC protocol compiler
35 * Copyright (C) 1987 Sun Microsystems, Inc.
39 #include "rpc/types.h"
40 #include "rpc_parse.h"
46 static void isdefined(definition
*);
47 static void def_struct(definition
*);
48 static void def_program(definition
*);
49 static void def_enum(definition
*);
50 static void def_const(definition
*);
51 static void def_union(definition
*);
52 static void def_typedef(definition
*);
53 static void get_declaration(declaration
*, defkind
);
54 static void get_prog_declaration(declaration
*, defkind
, int);
55 static void get_type(const char **, const char **, defkind
);
56 static void unsigned_dec(const char **);
59 * return the next definition you see
67 defp
= XALLOC(definition
);
91 error("definition keyword expected");
93 scan(TOK_SEMICOLON
, &tok
);
99 isdefined(definition
*defp
)
101 STOREVAL(&defined
, defp
);
105 def_struct(definition
*defp
)
112 defp
->def_kind
= DEF_STRUCT
;
114 scan(TOK_IDENT
, &tok
);
115 defp
->def_name
= tok
.str
;
116 scan(TOK_LBRACE
, &tok
);
117 tailp
= &defp
->def
.st
.decls
;
119 get_declaration(&dec
, DEF_STRUCT
);
120 decls
= XALLOC(decl_list
);
123 tailp
= &decls
->next
;
124 scan(TOK_SEMICOLON
, &tok
);
126 } while (tok
.kind
!= TOK_RBRACE
);
132 def_program(definition
*defp
)
139 version_list
**vtailp
;
143 bool_t isvoid
= FALSE
; /* whether first argument is void */
144 defp
->def_kind
= DEF_PROGRAM
;
145 scan(TOK_IDENT
, &tok
);
146 defp
->def_name
= tok
.str
;
147 scan(TOK_LBRACE
, &tok
);
148 vtailp
= &defp
->def
.pr
.versions
;
149 tailp
= &defp
->def
.st
.decls
;
150 scan(TOK_VERSION
, &tok
);
152 scan(TOK_IDENT
, &tok
);
153 vlist
= XALLOC(version_list
);
154 vlist
->vers_name
= tok
.str
;
155 scan(TOK_LBRACE
, &tok
);
156 ptailp
= &vlist
->procs
;
158 /* get result type */
159 plist
= XALLOC(proc_list
);
160 get_type(&plist
->res_prefix
, &plist
->res_type
,
162 if (streq(plist
->res_type
, "opaque"))
163 error("illegal result type");
164 scan(TOK_IDENT
, &tok
);
165 plist
->proc_name
= tok
.str
;
166 scan(TOK_LPAREN
, &tok
);
167 /* get args - first one */
171 * type of DEF_PROGRAM in the first
172 * get_prog_declaration and DEF_STURCT in the next
173 * allows void as argument if it is the only argument
175 get_prog_declaration(&dec
, DEF_PROGRAM
, num_args
);
176 if (streq(dec
.type
, "void"))
178 decls
= XALLOC(decl_list
);
179 plist
->args
.decls
= decls
;
181 tailp
= &decls
->next
;
183 while (peekscan(TOK_COMMA
, &tok
)) {
185 get_prog_declaration(&dec
, DEF_STRUCT
,
187 decls
= XALLOC(decl_list
);
190 if (streq(dec
.type
, "void"))
192 tailp
= &decls
->next
;
194 /* multiple arguments are only allowed in newstyle */
195 if (!newstyle
&& num_args
> 1)
196 error("only one argument is allowed");
197 if (isvoid
&& num_args
> 1)
198 error("illegal use of void in program definition");
200 scan(TOK_RPAREN
, &tok
);
201 scan(TOK_EQUAL
, &tok
);
203 scan(TOK_SEMICOLON
, &tok
);
204 plist
->proc_num
= tok
.str
;
205 plist
->arg_num
= num_args
;
207 ptailp
= &plist
->next
;
209 } while (tok
.kind
!= TOK_RBRACE
);
212 vtailp
= &vlist
->next
;
213 scan(TOK_RBRACE
, &tok
);
214 scan(TOK_EQUAL
, &tok
);
216 vlist
->vers_num
= tok
.str
;
217 /* make the argument structure name for each arg */
218 for (plist
= vlist
->procs
; plist
!= NULL
; plist
= plist
->next
) {
219 plist
->args
.argname
= make_argname(plist
->proc_name
,
221 /* free the memory ?? */
223 scan(TOK_SEMICOLON
, &tok
);
224 scan2(TOK_VERSION
, TOK_RBRACE
, &tok
);
225 } while (tok
.kind
== TOK_VERSION
);
226 scan(TOK_EQUAL
, &tok
);
228 defp
->def
.pr
.prog_num
= tok
.str
;
234 def_enum(definition
*defp
)
238 enumval_list
**tailp
;
240 defp
->def_kind
= DEF_ENUM
;
241 scan(TOK_IDENT
, &tok
);
242 defp
->def_name
= tok
.str
;
243 scan(TOK_LBRACE
, &tok
);
244 tailp
= &defp
->def
.en
.vals
;
246 scan(TOK_IDENT
, &tok
);
247 elist
= XALLOC(enumval_list
);
248 elist
->name
= tok
.str
;
249 elist
->assignment
= NULL
;
250 scan3(TOK_COMMA
, TOK_RBRACE
, TOK_EQUAL
, &tok
);
251 if (tok
.kind
== TOK_EQUAL
) {
253 elist
->assignment
= tok
.str
;
254 scan2(TOK_COMMA
, TOK_RBRACE
, &tok
);
257 tailp
= &elist
->next
;
258 } while (tok
.kind
!= TOK_RBRACE
);
263 def_const(definition
*defp
)
267 defp
->def_kind
= DEF_CONST
;
268 scan(TOK_IDENT
, &tok
);
269 defp
->def_name
= tok
.str
;
270 scan(TOK_EQUAL
, &tok
);
271 scan2(TOK_IDENT
, TOK_STRCONST
, &tok
);
272 defp
->def
.co
= tok
.str
;
276 def_union(definition
*defp
)
284 defp
->def_kind
= DEF_UNION
;
285 scan(TOK_IDENT
, &tok
);
286 defp
->def_name
= tok
.str
;
287 scan(TOK_SWITCH
, &tok
);
288 scan(TOK_LPAREN
, &tok
);
289 get_declaration(&dec
, DEF_UNION
);
290 defp
->def
.un
.enum_decl
= dec
;
291 tailp
= &defp
->def
.un
.cases
;
292 scan(TOK_RPAREN
, &tok
);
293 scan(TOK_LBRACE
, &tok
);
294 scan(TOK_CASE
, &tok
);
295 while (tok
.kind
== TOK_CASE
) {
296 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
297 cases
= XALLOC(case_list
);
298 cases
->case_name
= tok
.str
;
299 scan(TOK_COLON
, &tok
);
300 /* now peek at next token */
302 if (peekscan(TOK_CASE
, &tok
)){
304 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
306 /* continued case statement */
308 tailp
= &cases
->next
;
309 cases
= XALLOC(case_list
);
310 cases
->case_name
= tok
.str
;
311 scan(TOK_COLON
, &tok
);
312 } while (peekscan(TOK_CASE
, &tok
));
316 tailp
= &cases
->next
;
317 cases
= XALLOC(case_list
);
320 get_declaration(&dec
, DEF_UNION
);
321 cases
->case_decl
= dec
;
322 cases
->contflag
= 0; /* no continued case statement */
324 tailp
= &cases
->next
;
325 scan(TOK_SEMICOLON
, &tok
);
327 scan3(TOK_CASE
, TOK_DEFAULT
, TOK_RBRACE
, &tok
);
330 if (tok
.kind
== TOK_DEFAULT
) {
331 scan(TOK_COLON
, &tok
);
332 get_declaration(&dec
, DEF_UNION
);
333 defp
->def
.un
.default_decl
= XALLOC(declaration
);
334 *defp
->def
.un
.default_decl
= dec
;
335 scan(TOK_SEMICOLON
, &tok
);
336 scan(TOK_RBRACE
, &tok
);
338 defp
->def
.un
.default_decl
= NULL
;
342 static const char *reserved_words
[] =
359 static const char *reserved_types
[] =
367 * check that the given name is not one that would eventually result in
368 * xdr routines that would conflict with internal XDR routines.
371 check_type_name(const char *name
, int new_type
)
376 for (i
= 0; reserved_words
[i
] != NULL
; i
++) {
377 if (strcmp(name
, reserved_words
[i
]) == 0) {
379 "illegal (reserved) name :\'%s\' in type definition",
385 for (i
= 0; reserved_types
[i
] != NULL
; i
++) {
386 if (strcmp(name
, reserved_types
[i
]) == 0) {
388 "illegal (reserved) name :\'%s\' in type definition",
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"))
423 check_type_name(dec
->type
, 0);
424 scan2(TOK_STAR
, TOK_IDENT
, &tok
);
425 if (tok
.kind
== TOK_STAR
) {
426 dec
->rel
= REL_POINTER
;
427 scan(TOK_IDENT
, &tok
);
430 if (peekscan(TOK_LBRACKET
, &tok
)) {
431 if (dec
->rel
== REL_POINTER
)
432 error("no array-of-pointer declarations -- use typedef");
433 dec
->rel
= REL_VECTOR
;
435 dec
->array_max
= tok
.str
;
436 scan(TOK_RBRACKET
, &tok
);
437 } else if (peekscan(TOK_LANGLE
, &tok
)) {
438 if (dec
->rel
== REL_POINTER
)
439 error("no array-of-pointer declarations -- use typedef");
440 dec
->rel
= REL_ARRAY
;
441 if (peekscan(TOK_RANGLE
, &tok
)) {
442 dec
->array_max
= "~0"; /* unspecified size, use max */
445 dec
->array_max
= tok
.str
;
446 scan(TOK_RANGLE
, &tok
);
449 if (streq(dec
->type
, "opaque")) {
450 if (dec
->rel
!= REL_ARRAY
&& dec
->rel
!= REL_VECTOR
) {
451 error("array declaration expected");
453 } else if (streq(dec
->type
, "string")) {
454 if (dec
->rel
!= REL_ARRAY
) {
455 error("variable-length array declaration expected");
462 get_prog_declaration(declaration
*dec
, defkind dkind
, int num
)
465 char name
[10]; /* argument name */
467 if (dkind
== DEF_PROGRAM
) {
469 if (tok
.kind
== TOK_RPAREN
) { /* no arguments */
470 dec
->rel
= REL_ALIAS
;
477 get_type(&dec
->prefix
, &dec
->type
, dkind
);
478 dec
->rel
= REL_ALIAS
;
479 if (peekscan(TOK_IDENT
, &tok
)) /* optional name of argument */
480 strcpy(name
, tok
.str
);
482 sprintf(name
, "%s%d", ARGNAME
, num
);
483 /* default name of argument */
485 dec
->name
= (char *) xstrdup(name
);
486 if (streq(dec
->type
, "void")) {
490 if (streq(dec
->type
, "opaque"))
491 error("opaque -- illegal argument type");
492 if (peekscan(TOK_STAR
, &tok
)) {
493 if (streq(dec
->type
, "string"))
494 error("pointer to string not allowed in program arguments");
495 dec
->rel
= REL_POINTER
;
496 if (peekscan(TOK_IDENT
, &tok
)) {
497 /* optional name of argument */
498 dec
->name
= xstrdup(tok
.str
);
501 if (peekscan(TOK_LANGLE
, &tok
)) {
502 if (!streq(dec
->type
, "string"))
503 error("arrays cannot be declared as arguments to procedures -- use typedef");
504 dec
->rel
= REL_ARRAY
;
505 if (peekscan(TOK_RANGLE
, &tok
)) {
506 dec
->array_max
= "~0";
507 /* unspecified size, use max */
510 dec
->array_max
= tok
.str
;
511 scan(TOK_RANGLE
, &tok
);
514 if (streq(dec
->type
, "string")) {
515 if (dec
->rel
!= REL_ARRAY
) {
517 * .x specifies just string as
521 dec
->rel
= REL_ARRAY
;
522 dec
->array_max
= "~0"; /* unspecified size, use max */
528 get_type(const char **prefixp
, const char **typep
, defkind dkind
)
542 scan(TOK_IDENT
, &tok
);
550 peekscan(TOK_INT
, &tok
);
554 peekscan(TOK_INT
, &tok
);
558 peekscan(TOK_INT
, &tok
);
562 if (dkind
!= DEF_UNION
&& dkind
!= DEF_PROGRAM
)
563 error("voids allowed only inside union and program definitions with one argument");
577 error("expected type specifier");
582 unsigned_dec(const char **typep
)
595 peekscan(TOK_INT
, &tok
);
600 peekscan(TOK_INT
, &tok
);
604 *typep
= "u_int64_t";
605 peekscan(TOK_INT
, &tok
);