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 or with the express written consent of
8 * Sun Microsystems, Inc.
10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 * Sun RPC is provided with no support and without any obligation on the
15 * part of Sun Microsystems, Inc. to assist in its use, correction,
16 * modification or enhancement.
18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20 * OR ANY PART THEREOF.
22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23 * or profits or other special, indirect and consequential damages, even if
24 * Sun has been advised of the possibility of such damages.
26 * Sun Microsystems, Inc.
28 * Mountain View, California 94043
32 * From: @(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI
38 * rpc_parse.c, Parser for the RPC protocol compiler
39 * Copyright (C) 1987 Sun Microsystems, Inc.
43 #include "rpc/types.h"
45 #include "rpc_parse.h"
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(const 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(const char **prefixp
, const char **typep
, defkind dkind
);
62 static void unsigned_dec(const char **typep
);
65 * return the next definition you see
73 defp
= ALLOC(definition
);
97 error("definition keyword expected");
99 scan(TOK_SEMICOLON
, &tok
);
105 isdefined(definition
*defp
)
107 STOREVAL(&defined
, defp
);
111 def_struct(definition
*defp
)
118 defp
->def_kind
= DEF_STRUCT
;
120 scan(TOK_IDENT
, &tok
);
121 defp
->def_name
= tok
.str
;
122 scan(TOK_LBRACE
, &tok
);
123 tailp
= &defp
->def
.st
.decls
;
125 get_declaration(&dec
, DEF_STRUCT
);
126 decls
= ALLOC(decl_list
);
129 tailp
= &decls
->next
;
130 scan(TOK_SEMICOLON
, &tok
);
132 } while (tok
.kind
!= TOK_RBRACE
);
138 def_program(definition
*defp
)
145 version_list
**vtailp
;
149 bool_t isvoid
= FALSE
; /* whether first argument is void */
150 defp
->def_kind
= DEF_PROGRAM
;
151 scan(TOK_IDENT
, &tok
);
152 defp
->def_name
= tok
.str
;
153 scan(TOK_LBRACE
, &tok
);
154 vtailp
= &defp
->def
.pr
.versions
;
155 tailp
= &defp
->def
.st
.decls
;
156 scan(TOK_VERSION
, &tok
);
158 scan(TOK_IDENT
, &tok
);
159 vlist
= ALLOC(version_list
);
160 vlist
->vers_name
= tok
.str
;
161 scan(TOK_LBRACE
, &tok
);
162 ptailp
= &vlist
->procs
;
164 /* get result type */
165 plist
= ALLOC(proc_list
);
166 get_type(&plist
->res_prefix
, &plist
->res_type
,
168 if (streq(plist
->res_type
, "opaque")) {
169 error("illegal result type");
171 scan(TOK_IDENT
, &tok
);
172 plist
->proc_name
= tok
.str
;
173 scan(TOK_LPAREN
, &tok
);
174 /* get args - first one*/
177 /* type of DEF_PROGRAM in the first
178 * get_prog_declaration and DEF_STURCT in the next
179 * allows void as argument if it is the only argument
181 get_prog_declaration(&dec
, DEF_PROGRAM
, num_args
);
182 if (streq(dec
.type
, "void"))
184 decls
= ALLOC(decl_list
);
185 plist
->args
.decls
= decls
;
187 tailp
= &decls
->next
;
189 while(peekscan(TOK_COMMA
, &tok
)) {
191 get_prog_declaration(&dec
, DEF_STRUCT
,
193 decls
= ALLOC(decl_list
);
196 if (streq(dec
.type
, "void"))
198 tailp
= &decls
->next
;
200 /* multiple arguments are only allowed in newstyle */
201 if( !newstyle
&& num_args
> 1 ) {
202 error("only one argument is allowed" );
204 if (isvoid
&& num_args
> 1) {
205 error("illegal use of void in program definition");
208 scan(TOK_RPAREN
, &tok
);
209 scan(TOK_EQUAL
, &tok
);
211 scan(TOK_SEMICOLON
, &tok
);
212 plist
->proc_num
= tok
.str
;
213 plist
->arg_num
= num_args
;
215 ptailp
= &plist
->next
;
217 } while (tok
.kind
!= TOK_RBRACE
);
220 vtailp
= &vlist
->next
;
221 scan(TOK_RBRACE
, &tok
);
222 scan(TOK_EQUAL
, &tok
);
224 vlist
->vers_num
= tok
.str
;
225 /* make the argument structure name for each arg*/
226 for(plist
= vlist
->procs
; plist
!= NULL
;
227 plist
= plist
->next
) {
228 plist
->args
.argname
= make_argname(plist
->proc_name
,
230 /* free the memory ??*/
232 scan(TOK_SEMICOLON
, &tok
);
233 scan2(TOK_VERSION
, TOK_RBRACE
, &tok
);
234 } while (tok
.kind
== TOK_VERSION
);
235 scan(TOK_EQUAL
, &tok
);
237 defp
->def
.pr
.prog_num
= tok
.str
;
243 def_enum(definition
*defp
)
247 enumval_list
**tailp
;
249 defp
->def_kind
= DEF_ENUM
;
250 scan(TOK_IDENT
, &tok
);
251 defp
->def_name
= tok
.str
;
252 scan(TOK_LBRACE
, &tok
);
253 tailp
= &defp
->def
.en
.vals
;
255 scan(TOK_IDENT
, &tok
);
256 elist
= ALLOC(enumval_list
);
257 elist
->name
= tok
.str
;
258 elist
->assignment
= NULL
;
259 scan3(TOK_COMMA
, TOK_RBRACE
, TOK_EQUAL
, &tok
);
260 if (tok
.kind
== TOK_EQUAL
) {
262 elist
->assignment
= tok
.str
;
263 scan2(TOK_COMMA
, TOK_RBRACE
, &tok
);
266 tailp
= &elist
->next
;
267 } while (tok
.kind
!= TOK_RBRACE
);
272 def_const(definition
*defp
)
276 defp
->def_kind
= DEF_CONST
;
277 scan(TOK_IDENT
, &tok
);
278 defp
->def_name
= tok
.str
;
279 scan(TOK_EQUAL
, &tok
);
280 scan2(TOK_IDENT
, TOK_STRCONST
, &tok
);
281 defp
->def
.co
= tok
.str
;
285 def_union(definition
*defp
)
290 /* case_list *tcase; */
294 defp
->def_kind
= DEF_UNION
;
295 scan(TOK_IDENT
, &tok
);
296 defp
->def_name
= tok
.str
;
297 scan(TOK_SWITCH
, &tok
);
298 scan(TOK_LPAREN
, &tok
);
299 get_declaration(&dec
, DEF_UNION
);
300 defp
->def
.un
.enum_decl
= dec
;
301 tailp
= &defp
->def
.un
.cases
;
302 scan(TOK_RPAREN
, &tok
);
303 scan(TOK_LBRACE
, &tok
);
304 scan(TOK_CASE
, &tok
);
305 while (tok
.kind
== TOK_CASE
) {
306 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
307 cases
= ALLOC(case_list
);
308 cases
->case_name
= tok
.str
;
309 scan(TOK_COLON
, &tok
);
310 /* now peek at next token */
312 if(peekscan(TOK_CASE
,&tok
))
317 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
318 cases
->contflag
=1; /* continued case statement */
320 tailp
= &cases
->next
;
321 cases
= ALLOC(case_list
);
322 cases
->case_name
= tok
.str
;
323 scan(TOK_COLON
, &tok
);
325 }while(peekscan(TOK_CASE
,&tok
));
332 tailp
= &cases
->next
;
333 cases
= ALLOC(case_list
);
336 get_declaration(&dec
, DEF_UNION
);
337 cases
->case_decl
= dec
;
338 cases
->contflag
=0; /* no continued case statement */
340 tailp
= &cases
->next
;
341 scan(TOK_SEMICOLON
, &tok
);
343 scan3(TOK_CASE
, TOK_DEFAULT
, TOK_RBRACE
, &tok
);
346 if (tok
.kind
== TOK_DEFAULT
) {
347 scan(TOK_COLON
, &tok
);
348 get_declaration(&dec
, DEF_UNION
);
349 defp
->def
.un
.default_decl
= ALLOC(declaration
);
350 *defp
->def
.un
.default_decl
= dec
;
351 scan(TOK_SEMICOLON
, &tok
);
352 scan(TOK_RBRACE
, &tok
);
354 defp
->def
.un
.default_decl
= NULL
;
358 static const char *reserved_words
[] =
375 static const char *reserved_types
[] =
383 * check that the given name is not one that would eventually result in
384 * xdr routines that would conflict with internal XDR routines.
386 static void check_type_name(const char *name
, int new_type
)
391 for( i
= 0; reserved_words
[i
] != NULL
; i
++ ) {
392 if( strcmp( name
, reserved_words
[i
] ) == 0 ) {
394 "illegal (reserved) name :\'%s\' in type definition", name
);
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", name
);
412 def_typedef(definition
*defp
)
416 defp
->def_kind
= DEF_TYPEDEF
;
417 get_declaration(&dec
, DEF_TYPEDEF
);
418 defp
->def_name
= dec
.name
;
419 check_type_name(dec
.name
, 1);
420 defp
->def
.ty
.old_prefix
= dec
.prefix
;
421 defp
->def
.ty
.old_type
= dec
.type
;
422 defp
->def
.ty
.rel
= dec
.rel
;
423 defp
->def
.ty
.array_max
= dec
.array_max
;
427 get_declaration(declaration
*dec
, defkind dkind
)
431 get_type(&dec
->prefix
, &dec
->type
, dkind
);
432 dec
->rel
= REL_ALIAS
;
433 if (streq(dec
->type
, "void")) {
437 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
/* arg number */)
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
); /* default name of argument */
501 dec
->name
= (char *) strdup(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\n");
514 dec
->rel
= REL_POINTER
;
515 if (peekscan(TOK_IDENT
, &tok
)) /* optional name of argument */
516 dec
->name
= strdup(tok
.str
);
518 if (peekscan(TOK_LANGLE
, &tok
)) {
519 if (!streq(dec
->type
, "string")) {
520 error("arrays cannot be declared as arguments to procedures -- use typedef");
522 dec
->rel
= REL_ARRAY
;
523 if (peekscan(TOK_RANGLE
, &tok
)) {
524 dec
->array_max
= "~0";/* unspecified size, use max */
527 dec
->array_max
= tok
.str
;
528 scan(TOK_RANGLE
, &tok
);
531 if (streq(dec
->type
, "string")) {
532 if (dec
->rel
!= REL_ARRAY
) { /* .x specifies just string as
536 dec
->rel
= REL_ARRAY
;
537 dec
->array_max
= "~0";/* unspecified size, use max */
545 get_type(const char **prefixp
, const char **typep
, defkind dkind
)
559 scan(TOK_IDENT
, &tok
);
567 (void) peekscan(TOK_INT
, &tok
);
571 (void) peekscan(TOK_INT
, &tok
);
574 if (dkind
!= DEF_UNION
&& dkind
!= DEF_PROGRAM
) {
575 error("voids allowed only inside union and program definitions with one argument");
589 error("expected type specifier");
594 unsigned_dec(const char **typep
)
607 (void) peekscan(TOK_INT
, &tok
);
612 (void) peekscan(TOK_INT
, &tok
);