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, MERCHANTIBILITY 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
32 #ident "@(#)rpc_parse.c 1.12 93/07/05 SMI"
33 static char sccsid
[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
41 * rpc_parse.c, Parser for the RPC protocol compiler
42 * Copyright (C) 1987 Sun Microsystems, Inc.
46 #include "rpc/types.h"
47 #include "rpc_parse.h"
53 static void isdefined( definition
* );
54 static void def_struct( definition
* );
55 static void def_program( definition
* );
56 static void def_enum( definition
* );
57 static void def_const( definition
* );
58 static void def_union( definition
* );
59 static void def_typedef( definition
* );
60 static void get_declaration( declaration
*, defkind
);
61 static void get_prog_declaration( declaration
*, defkind
, int );
62 static void get_type(const char **, const char **, defkind
);
63 static void unsigned_dec(const char ** );
66 * return the next definition you see
74 defp
= XALLOC(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
= XALLOC(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
= XALLOC(version_list
);
161 vlist
->vers_name
= tok
.str
;
162 scan(TOK_LBRACE
, &tok
);
163 ptailp
= &vlist
->procs
;
165 /* get result type */
166 plist
= XALLOC(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 */
179 * type of DEF_PROGRAM in the first
180 * get_prog_declaration and DEF_STURCT in the next
181 * allows void as argument if it is the only argument
183 get_prog_declaration(&dec
, DEF_PROGRAM
, num_args
);
184 if (streq(dec
.type
, "void"))
186 decls
= XALLOC(decl_list
);
187 plist
->args
.decls
= decls
;
189 tailp
= &decls
->next
;
191 while (peekscan(TOK_COMMA
, &tok
)) {
193 get_prog_declaration(&dec
, DEF_STRUCT
,
195 decls
= XALLOC(decl_list
);
198 if (streq(dec
.type
, "void"))
200 tailp
= &decls
->next
;
202 /* multiple arguments are only allowed in newstyle */
203 if (!newstyle
&& num_args
> 1) {
204 error("only one argument is allowed");
206 if (isvoid
&& num_args
> 1) {
207 error("illegal use of void in program definition");
210 scan(TOK_RPAREN
, &tok
);
211 scan(TOK_EQUAL
, &tok
);
213 scan(TOK_SEMICOLON
, &tok
);
214 plist
->proc_num
= tok
.str
;
215 plist
->arg_num
= num_args
;
217 ptailp
= &plist
->next
;
219 } while (tok
.kind
!= TOK_RBRACE
);
222 vtailp
= &vlist
->next
;
223 scan(TOK_RBRACE
, &tok
);
224 scan(TOK_EQUAL
, &tok
);
226 vlist
->vers_num
= tok
.str
;
227 /* make the argument structure name for each arg */
228 for (plist
= vlist
->procs
; plist
!= NULL
;
229 plist
= plist
->next
) {
230 plist
->args
.argname
= make_argname(plist
->proc_name
,
232 /* free the memory ?? */
234 scan(TOK_SEMICOLON
, &tok
);
235 scan2(TOK_VERSION
, TOK_RBRACE
, &tok
);
236 } while (tok
.kind
== TOK_VERSION
);
237 scan(TOK_EQUAL
, &tok
);
239 defp
->def
.pr
.prog_num
= tok
.str
;
245 def_enum(definition
*defp
)
249 enumval_list
**tailp
;
251 defp
->def_kind
= DEF_ENUM
;
252 scan(TOK_IDENT
, &tok
);
253 defp
->def_name
= tok
.str
;
254 scan(TOK_LBRACE
, &tok
);
255 tailp
= &defp
->def
.en
.vals
;
257 scan(TOK_IDENT
, &tok
);
258 elist
= XALLOC(enumval_list
);
259 elist
->name
= tok
.str
;
260 elist
->assignment
= NULL
;
261 scan3(TOK_COMMA
, TOK_RBRACE
, TOK_EQUAL
, &tok
);
262 if (tok
.kind
== TOK_EQUAL
) {
264 elist
->assignment
= tok
.str
;
265 scan2(TOK_COMMA
, TOK_RBRACE
, &tok
);
268 tailp
= &elist
->next
;
269 } while (tok
.kind
!= TOK_RBRACE
);
274 def_const(definition
*defp
)
278 defp
->def_kind
= DEF_CONST
;
279 scan(TOK_IDENT
, &tok
);
280 defp
->def_name
= tok
.str
;
281 scan(TOK_EQUAL
, &tok
);
282 scan2(TOK_IDENT
, TOK_STRCONST
, &tok
);
283 defp
->def
.co
= tok
.str
;
287 def_union(definition
*defp
)
295 defp
->def_kind
= DEF_UNION
;
296 scan(TOK_IDENT
, &tok
);
297 defp
->def_name
= tok
.str
;
298 scan(TOK_SWITCH
, &tok
);
299 scan(TOK_LPAREN
, &tok
);
300 get_declaration(&dec
, DEF_UNION
);
301 defp
->def
.un
.enum_decl
= dec
;
302 tailp
= &defp
->def
.un
.cases
;
303 scan(TOK_RPAREN
, &tok
);
304 scan(TOK_LBRACE
, &tok
);
305 scan(TOK_CASE
, &tok
);
306 while (tok
.kind
== TOK_CASE
) {
307 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
308 cases
= XALLOC(case_list
);
309 cases
->case_name
= tok
.str
;
310 scan(TOK_COLON
, &tok
);
311 /* now peek at next token */
313 if (peekscan(TOK_CASE
, &tok
)){
315 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
317 /* continued case statement */
319 tailp
= &cases
->next
;
320 cases
= XALLOC(case_list
);
321 cases
->case_name
= tok
.str
;
322 scan(TOK_COLON
, &tok
);
323 } while (peekscan(TOK_CASE
, &tok
));
330 tailp
= &cases
->next
;
331 cases
= XALLOC(case_list
);
334 get_declaration(&dec
, DEF_UNION
);
335 cases
->case_decl
= dec
;
336 cases
->contflag
= 0; /* no continued case statement */
338 tailp
= &cases
->next
;
339 scan(TOK_SEMICOLON
, &tok
);
341 scan3(TOK_CASE
, TOK_DEFAULT
, TOK_RBRACE
, &tok
);
344 if (tok
.kind
== TOK_DEFAULT
) {
345 scan(TOK_COLON
, &tok
);
346 get_declaration(&dec
, DEF_UNION
);
347 defp
->def
.un
.default_decl
= XALLOC(declaration
);
348 *defp
->def
.un
.default_decl
= dec
;
349 scan(TOK_SEMICOLON
, &tok
);
350 scan(TOK_RBRACE
, &tok
);
352 defp
->def
.un
.default_decl
= NULL
;
356 static const char *reserved_words
[] =
373 static const char *reserved_types
[] =
381 * check that the given name is not one that would eventually result in
382 * xdr routines that would conflict with internal XDR routines.
385 check_type_name(const char *name
, int 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",
399 for (i
= 0; reserved_types
[i
] != NULL
; i
++) {
400 if (strcmp(name
, reserved_types
[i
]) == 0) {
402 "illegal (reserved) name :\'%s\' in type definition",
413 def_typedef(definition
*defp
)
417 defp
->def_kind
= DEF_TYPEDEF
;
418 get_declaration(&dec
, DEF_TYPEDEF
);
419 defp
->def_name
= dec
.name
;
420 check_type_name(dec
.name
, 1);
421 defp
->def
.ty
.old_prefix
= dec
.prefix
;
422 defp
->def
.ty
.old_type
= dec
.type
;
423 defp
->def
.ty
.rel
= dec
.rel
;
424 defp
->def
.ty
.array_max
= dec
.array_max
;
428 get_declaration(declaration
*dec
, defkind dkind
)
432 get_type(&dec
->prefix
, &dec
->type
, dkind
);
433 dec
->rel
= REL_ALIAS
;
434 if (streq(dec
->type
, "void")) {
438 check_type_name(dec
->type
, 0);
439 scan2(TOK_STAR
, TOK_IDENT
, &tok
);
440 if (tok
.kind
== TOK_STAR
) {
441 dec
->rel
= REL_POINTER
;
442 scan(TOK_IDENT
, &tok
);
445 if (peekscan(TOK_LBRACKET
, &tok
)) {
446 if (dec
->rel
== REL_POINTER
) {
447 error("no array-of-pointer declarations -- use typedef");
449 dec
->rel
= REL_VECTOR
;
451 dec
->array_max
= tok
.str
;
452 scan(TOK_RBRACKET
, &tok
);
453 } else 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
= "~0"; /* unspecified size, use max */
462 dec
->array_max
= tok
.str
;
463 scan(TOK_RANGLE
, &tok
);
466 if (streq(dec
->type
, "opaque")) {
467 if (dec
->rel
!= REL_ARRAY
&& dec
->rel
!= REL_VECTOR
) {
468 error("array declaration expected");
470 } else if (streq(dec
->type
, "string")) {
471 if (dec
->rel
!= REL_ARRAY
) {
472 error("variable-length array declaration expected");
479 get_prog_declaration(declaration
*dec
, defkind dkind
, int num
)
482 char name
[10]; /* argument name */
484 if (dkind
== DEF_PROGRAM
) {
486 if (tok
.kind
== TOK_RPAREN
) { /* no arguments */
487 dec
->rel
= REL_ALIAS
;
494 get_type(&dec
->prefix
, &dec
->type
, dkind
);
495 dec
->rel
= REL_ALIAS
;
496 if (peekscan(TOK_IDENT
, &tok
)) /* optional name of argument */
497 strcpy(name
, tok
.str
);
499 sprintf(name
, "%s%d", ARGNAME
, num
);
500 /* default name of argument */
502 dec
->name
= (char *) xstrdup(name
);
503 if (streq(dec
->type
, "void")) {
507 if (streq(dec
->type
, "opaque")) {
508 error("opaque -- illegal argument type");
510 if (peekscan(TOK_STAR
, &tok
)) {
511 if (streq(dec
->type
, "string")) {
512 error("pointer to string not allowed in program arguments");
514 dec
->rel
= REL_POINTER
;
515 if (peekscan(TOK_IDENT
, &tok
)) {
516 /* optional name of argument */
517 dec
->name
= xstrdup(tok
.str
);
520 if (peekscan(TOK_LANGLE
, &tok
)) {
521 if (!streq(dec
->type
, "string")) {
522 error("arrays cannot be declared as arguments to procedures -- use typedef");
524 dec
->rel
= REL_ARRAY
;
525 if (peekscan(TOK_RANGLE
, &tok
)) {
526 dec
->array_max
= "~0";
527 /* unspecified size, use max */
530 dec
->array_max
= tok
.str
;
531 scan(TOK_RANGLE
, &tok
);
534 if (streq(dec
->type
, "string")) {
535 if (dec
->rel
!= REL_ARRAY
) {
537 * .x specifies just string as
541 dec
->rel
= REL_ARRAY
;
542 dec
->array_max
= "~0"; /* unspecified size, use max */
550 get_type(const char **prefixp
, const char **typep
, defkind dkind
)
564 scan(TOK_IDENT
, &tok
);
572 (void) peekscan(TOK_INT
, &tok
);
576 (void) peekscan(TOK_INT
, &tok
);
580 (void) peekscan(TOK_INT
, &tok
);
584 if (dkind
!= DEF_UNION
&& dkind
!= DEF_PROGRAM
) {
585 error("voids allowed only inside union and program definitions with one argument");
600 error("expected type specifier");
605 unsigned_dec(const char **typep
)
618 (void) peekscan(TOK_INT
, &tok
);
623 (void) peekscan(TOK_INT
, &tok
);
627 *typep
= "u_int64_t";
629 (void) peekscan(TOK_INT
, &tok
);