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
29 * @(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI
30 * $DragonFly: src/usr.bin/rpcgen/rpc_parse.c,v 1.7 2004/06/19 18:40:36 joerg Exp $
33 #ident "@(#)rpc_parse.c 1.12 93/07/05 SMI"
36 * rpc_parse.c, Parser for the RPC protocol compiler
37 * Copyright (C) 1987 Sun Microsystems, Inc.
41 #include "rpc/types.h"
43 #include "rpc_parse.h"
48 extern char *make_argname(char *, char *);
49 static void isdefined(definition
*);
50 static void def_struct(definition
*);
51 static void def_program(definition
*);
52 static void def_enum(definition
*);
53 static void def_const(definition
*);
54 static void def_union(definition
*);
55 static void def_typedef( definition
*);
56 static void get_declaration( declaration
*, defkind
);
57 static void get_prog_declaration( declaration
*, defkind
, int);
58 static void get_type(char **, char **, defkind
);
59 static void unsigned_dec(char **);
62 * return the next definition you see
70 defp
= ALLOC(definition
);
94 error("definition keyword expected");
96 scan(TOK_SEMICOLON
, &tok
);
102 isdefined(definition
*defp
)
104 STOREVAL(&defined
, defp
);
108 def_struct(definition
*defp
)
115 defp
->def_kind
= DEF_STRUCT
;
117 scan(TOK_IDENT
, &tok
);
118 defp
->def_name
= tok
.str
;
119 scan(TOK_LBRACE
, &tok
);
120 tailp
= &defp
->def
.st
.decls
;
122 get_declaration(&dec
, DEF_STRUCT
);
123 decls
= ALLOC(decl_list
);
126 tailp
= &decls
->next
;
127 scan(TOK_SEMICOLON
, &tok
);
129 } while (tok
.kind
!= TOK_RBRACE
);
135 def_program(definition
*defp
)
142 version_list
**vtailp
;
146 bool_t isvoid
= FALSE
; /* whether first argument is void */
147 defp
->def_kind
= DEF_PROGRAM
;
148 scan(TOK_IDENT
, &tok
);
149 defp
->def_name
= tok
.str
;
150 scan(TOK_LBRACE
, &tok
);
151 vtailp
= &defp
->def
.pr
.versions
;
152 tailp
= &defp
->def
.st
.decls
;
153 scan(TOK_VERSION
, &tok
);
155 scan(TOK_IDENT
, &tok
);
156 vlist
= ALLOC(version_list
);
157 vlist
->vers_name
= tok
.str
;
158 scan(TOK_LBRACE
, &tok
);
159 ptailp
= &vlist
->procs
;
161 /* get result type */
162 plist
= ALLOC(proc_list
);
163 get_type(&plist
->res_prefix
, &plist
->res_type
,
165 if (streq(plist
->res_type
, "opaque"))
166 error("illegal result type");
167 scan(TOK_IDENT
, &tok
);
168 plist
->proc_name
= tok
.str
;
169 scan(TOK_LPAREN
, &tok
);
170 /* get args - first one */
174 * type of DEF_PROGRAM in the first
175 * get_prog_declaration and DEF_STURCT in the next
176 * allows void as argument if it is the only argument
178 get_prog_declaration(&dec
, DEF_PROGRAM
, num_args
);
179 if (streq(dec
.type
, "void"))
181 decls
= ALLOC(decl_list
);
182 plist
->args
.decls
= decls
;
184 tailp
= &decls
->next
;
186 while (peekscan(TOK_COMMA
, &tok
)) {
188 get_prog_declaration(&dec
, DEF_STRUCT
,
190 decls
= ALLOC(decl_list
);
193 if (streq(dec
.type
, "void"))
195 tailp
= &decls
->next
;
197 /* multiple arguments are only allowed in newstyle */
198 if (!newstyle
&& num_args
> 1)
199 error("only one argument is allowed");
200 if (isvoid
&& num_args
> 1)
201 error("illegal use of void in program definition");
203 scan(TOK_RPAREN
, &tok
);
204 scan(TOK_EQUAL
, &tok
);
206 scan(TOK_SEMICOLON
, &tok
);
207 plist
->proc_num
= tok
.str
;
208 plist
->arg_num
= num_args
;
210 ptailp
= &plist
->next
;
212 } while (tok
.kind
!= TOK_RBRACE
);
215 vtailp
= &vlist
->next
;
216 scan(TOK_RBRACE
, &tok
);
217 scan(TOK_EQUAL
, &tok
);
219 vlist
->vers_num
= tok
.str
;
220 /* make the argument structure name for each arg */
221 for (plist
= vlist
->procs
; plist
!= NULL
; plist
= plist
->next
) {
222 plist
->args
.argname
= make_argname(plist
->proc_name
,
224 /* free the memory ?? */
226 scan(TOK_SEMICOLON
, &tok
);
227 scan2(TOK_VERSION
, TOK_RBRACE
, &tok
);
228 } while (tok
.kind
== TOK_VERSION
);
229 scan(TOK_EQUAL
, &tok
);
231 defp
->def
.pr
.prog_num
= tok
.str
;
237 def_enum(definition
*defp
)
241 enumval_list
**tailp
;
243 defp
->def_kind
= DEF_ENUM
;
244 scan(TOK_IDENT
, &tok
);
245 defp
->def_name
= tok
.str
;
246 scan(TOK_LBRACE
, &tok
);
247 tailp
= &defp
->def
.en
.vals
;
249 scan(TOK_IDENT
, &tok
);
250 elist
= ALLOC(enumval_list
);
251 elist
->name
= tok
.str
;
252 elist
->assignment
= NULL
;
253 scan3(TOK_COMMA
, TOK_RBRACE
, TOK_EQUAL
, &tok
);
254 if (tok
.kind
== TOK_EQUAL
) {
256 elist
->assignment
= tok
.str
;
257 scan2(TOK_COMMA
, TOK_RBRACE
, &tok
);
260 tailp
= &elist
->next
;
261 } while (tok
.kind
!= TOK_RBRACE
);
266 def_const(definition
*defp
)
270 defp
->def_kind
= DEF_CONST
;
271 scan(TOK_IDENT
, &tok
);
272 defp
->def_name
= tok
.str
;
273 scan(TOK_EQUAL
, &tok
);
274 scan2(TOK_IDENT
, TOK_STRCONST
, &tok
);
275 defp
->def
.co
= tok
.str
;
279 def_union(definition
*defp
)
287 defp
->def_kind
= DEF_UNION
;
288 scan(TOK_IDENT
, &tok
);
289 defp
->def_name
= tok
.str
;
290 scan(TOK_SWITCH
, &tok
);
291 scan(TOK_LPAREN
, &tok
);
292 get_declaration(&dec
, DEF_UNION
);
293 defp
->def
.un
.enum_decl
= dec
;
294 tailp
= &defp
->def
.un
.cases
;
295 scan(TOK_RPAREN
, &tok
);
296 scan(TOK_LBRACE
, &tok
);
297 scan(TOK_CASE
, &tok
);
298 while (tok
.kind
== TOK_CASE
) {
299 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
300 cases
= ALLOC(case_list
);
301 cases
->case_name
= tok
.str
;
302 scan(TOK_COLON
, &tok
);
303 /* now peek at next token */
305 if (peekscan(TOK_CASE
, &tok
)){
307 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
309 /* continued case statement */
311 tailp
= &cases
->next
;
312 cases
= ALLOC(case_list
);
313 cases
->case_name
= tok
.str
;
314 scan(TOK_COLON
, &tok
);
315 } while (peekscan(TOK_CASE
, &tok
));
319 tailp
= &cases
->next
;
320 cases
= ALLOC(case_list
);
323 get_declaration(&dec
, DEF_UNION
);
324 cases
->case_decl
= dec
;
325 cases
->contflag
= 0; /* no continued case statement */
327 tailp
= &cases
->next
;
328 scan(TOK_SEMICOLON
, &tok
);
330 scan3(TOK_CASE
, TOK_DEFAULT
, TOK_RBRACE
, &tok
);
333 if (tok
.kind
== TOK_DEFAULT
) {
334 scan(TOK_COLON
, &tok
);
335 get_declaration(&dec
, DEF_UNION
);
336 defp
->def
.un
.default_decl
= ALLOC(declaration
);
337 *defp
->def
.un
.default_decl
= dec
;
338 scan(TOK_SEMICOLON
, &tok
);
339 scan(TOK_RBRACE
, &tok
);
341 defp
->def
.un
.default_decl
= NULL
;
345 static char* reserved_words
[] =
362 static char* reserved_types
[] =
370 * check that the given name is not one that would eventually result in
371 * xdr routines that would conflict with internal XDR routines.
374 check_type_name(char* name
, int new_type
)
379 for (i
= 0; reserved_words
[i
] != NULL
; i
++) {
380 if (strcmp(name
, reserved_words
[i
]) == 0) {
382 "illegal (reserved) name :\'%s\' in type definition",
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",
402 def_typedef(definition
*defp
)
406 defp
->def_kind
= DEF_TYPEDEF
;
407 get_declaration(&dec
, DEF_TYPEDEF
);
408 defp
->def_name
= dec
.name
;
409 check_type_name(dec
.name
, 1);
410 defp
->def
.ty
.old_prefix
= dec
.prefix
;
411 defp
->def
.ty
.old_type
= dec
.type
;
412 defp
->def
.ty
.rel
= dec
.rel
;
413 defp
->def
.ty
.array_max
= dec
.array_max
;
417 get_declaration(declaration
*dec
, defkind dkind
)
421 get_type(&dec
->prefix
, &dec
->type
, dkind
);
422 dec
->rel
= REL_ALIAS
;
423 if (streq(dec
->type
, "void"))
426 check_type_name(dec
->type
, 0);
427 scan2(TOK_STAR
, TOK_IDENT
, &tok
);
428 if (tok
.kind
== TOK_STAR
) {
429 dec
->rel
= REL_POINTER
;
430 scan(TOK_IDENT
, &tok
);
433 if (peekscan(TOK_LBRACKET
, &tok
)) {
434 if (dec
->rel
== REL_POINTER
)
435 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");
443 dec
->rel
= REL_ARRAY
;
444 if (peekscan(TOK_RANGLE
, &tok
)) {
445 dec
->array_max
= "~0"; /* unspecified size, use max */
448 dec
->array_max
= tok
.str
;
449 scan(TOK_RANGLE
, &tok
);
452 if (streq(dec
->type
, "opaque")) {
453 if (dec
->rel
!= REL_ARRAY
&& dec
->rel
!= REL_VECTOR
) {
454 error("array declaration expected");
456 } else if (streq(dec
->type
, "string")) {
457 if (dec
->rel
!= REL_ARRAY
) {
458 error("variable-length array declaration expected");
465 get_prog_declaration(declaration
*dec
, defkind dkind
, int num
)
468 char name
[10]; /* argument name */
470 if (dkind
== DEF_PROGRAM
) {
472 if (tok
.kind
== TOK_RPAREN
) { /* no arguments */
473 dec
->rel
= REL_ALIAS
;
480 get_type(&dec
->prefix
, &dec
->type
, dkind
);
481 dec
->rel
= REL_ALIAS
;
482 if (peekscan(TOK_IDENT
, &tok
)) /* optional name of argument */
483 strcpy(name
, tok
.str
);
485 sprintf(name
, "%s%d", ARGNAME
, num
);
486 /* default name of argument */
488 dec
->name
= (char *) strdup(name
);
489 if (streq(dec
->type
, "void")) {
493 if (streq(dec
->type
, "opaque"))
494 error("opaque -- illegal argument type");
495 if (peekscan(TOK_STAR
, &tok
)) {
496 if (streq(dec
->type
, "string"))
497 error("pointer to string not allowed in program arguments\n");
498 dec
->rel
= REL_POINTER
;
499 if (peekscan(TOK_IDENT
, &tok
)) {
500 /* optional name of argument */
501 dec
->name
= strdup(tok
.str
);
504 if (peekscan(TOK_LANGLE
, &tok
)) {
505 if (!streq(dec
->type
, "string"))
506 error("arrays cannot be declared as arguments to procedures -- use typedef");
507 dec
->rel
= REL_ARRAY
;
508 if (peekscan(TOK_RANGLE
, &tok
)) {
509 dec
->array_max
= "~0";
510 /* unspecified size, use max */
513 dec
->array_max
= tok
.str
;
514 scan(TOK_RANGLE
, &tok
);
517 if (streq(dec
->type
, "string")) {
518 if (dec
->rel
!= REL_ARRAY
) {
520 * .x specifies just string as
524 dec
->rel
= REL_ARRAY
;
525 dec
->array_max
= "~0"; /* unspecified size, use max */
531 get_type(char **prefixp
, char **typep
, defkind dkind
)
545 scan(TOK_IDENT
, &tok
);
553 peekscan(TOK_INT
, &tok
);
557 peekscan(TOK_INT
, &tok
);
561 peekscan(TOK_INT
, &tok
);
565 if (dkind
!= DEF_UNION
&& dkind
!= DEF_PROGRAM
)
566 error("voids allowed only inside union and program definitions with one argument");
580 error("expected type specifier");
585 unsigned_dec(char **typep
)
598 peekscan(TOK_INT
, &tok
);
603 peekscan(TOK_INT
, &tok
);
607 *typep
= "u_int64_t";
608 peekscan(TOK_INT
, &tok
);