2 * From: @(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 * * Neither the name of Sun Microsystems, Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * rpc_parse.c, Parser for the RPC protocol compiler
34 * Copyright (C) 1987 Sun Microsystems, Inc.
38 #include "rpc/types.h"
40 #include "rpc_parse.h"
46 static void isdefined (definition
* defp
);
47 static void def_struct (definition
* defp
);
48 static void def_program (definition
* defp
);
49 static void def_enum (definition
* defp
);
50 static void def_const (definition
* defp
);
51 static void def_union (definition
* defp
);
52 static void check_type_name (const char *name
, int new_type
);
53 static void def_typedef (definition
* defp
);
54 static void get_declaration (declaration
* dec
, defkind dkind
);
55 static void get_prog_declaration (declaration
* dec
, defkind dkind
, int num
);
56 static void get_type (const char **prefixp
, const char **typep
, defkind dkind
);
57 static void unsigned_dec (const char **typep
);
60 * return the next definition you see
68 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
;
123 get_declaration (&dec
, DEF_STRUCT
);
124 decls
= ALLOC (decl_list
);
127 tailp
= &decls
->next
;
128 scan (TOK_SEMICOLON
, &tok
);
131 while (tok
.kind
!= TOK_RBRACE
);
137 def_program (definition
* defp
)
144 version_list
**vtailp
;
148 bool_t isvoid
= FALSE
; /* whether first argument is void */
149 defp
->def_kind
= DEF_PROGRAM
;
150 scan (TOK_IDENT
, &tok
);
151 defp
->def_name
= tok
.str
;
152 scan (TOK_LBRACE
, &tok
);
153 vtailp
= &defp
->def
.pr
.versions
;
154 tailp
= &defp
->def
.st
.decls
;
155 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
;
165 /* get result type */
166 plist
= ALLOC (proc_list
);
167 get_type (&plist
->res_prefix
, &plist
->res_type
,
169 if (streq (plist
->res_type
, "opaque"))
171 error ("illegal result type");
173 scan (TOK_IDENT
, &tok
);
174 plist
->proc_name
= tok
.str
;
175 scan (TOK_LPAREN
, &tok
);
176 /* 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
= ALLOC (decl_list
);
187 plist
->args
.decls
= decls
;
189 tailp
= &decls
->next
;
191 while (peekscan (TOK_COMMA
, &tok
))
194 get_prog_declaration (&dec
, DEF_STRUCT
,
196 decls
= ALLOC (decl_list
);
199 if (streq (dec
.type
, "void"))
201 tailp
= &decls
->next
;
203 /* multiple arguments are only allowed in newstyle */
204 if (!newstyle
&& num_args
> 1)
206 error ("only one argument is allowed");
208 if (isvoid
&& num_args
> 1)
210 error ("illegal use of void in program definition");
213 scan (TOK_RPAREN
, &tok
);
214 scan (TOK_EQUAL
, &tok
);
216 scan (TOK_SEMICOLON
, &tok
);
217 plist
->proc_num
= tok
.str
;
218 plist
->arg_num
= num_args
;
220 ptailp
= &plist
->next
;
223 while (tok
.kind
!= TOK_RBRACE
);
226 vtailp
= &vlist
->next
;
227 scan (TOK_RBRACE
, &tok
);
228 scan (TOK_EQUAL
, &tok
);
230 vlist
->vers_num
= tok
.str
;
231 /* make the argument structure name for each arg */
232 for (plist
= vlist
->procs
; plist
!= NULL
;
235 plist
->args
.argname
= make_argname (plist
->proc_name
,
237 /* free the memory ?? */
239 scan (TOK_SEMICOLON
, &tok
);
240 scan2 (TOK_VERSION
, TOK_RBRACE
, &tok
);
242 while (tok
.kind
== TOK_VERSION
);
243 scan (TOK_EQUAL
, &tok
);
245 defp
->def
.pr
.prog_num
= tok
.str
;
251 def_enum (definition
* defp
)
255 enumval_list
**tailp
;
257 defp
->def_kind
= DEF_ENUM
;
258 scan (TOK_IDENT
, &tok
);
259 defp
->def_name
= tok
.str
;
260 scan (TOK_LBRACE
, &tok
);
261 tailp
= &defp
->def
.en
.vals
;
264 scan (TOK_IDENT
, &tok
);
265 elist
= ALLOC (enumval_list
);
266 elist
->name
= tok
.str
;
267 elist
->assignment
= NULL
;
268 scan3 (TOK_COMMA
, TOK_RBRACE
, TOK_EQUAL
, &tok
);
269 if (tok
.kind
== TOK_EQUAL
)
272 elist
->assignment
= tok
.str
;
273 scan2 (TOK_COMMA
, TOK_RBRACE
, &tok
);
276 tailp
= &elist
->next
;
278 while (tok
.kind
!= TOK_RBRACE
);
283 def_const (definition
* defp
)
287 defp
->def_kind
= DEF_CONST
;
288 scan (TOK_IDENT
, &tok
);
289 defp
->def_name
= tok
.str
;
290 scan (TOK_EQUAL
, &tok
);
291 scan2 (TOK_IDENT
, TOK_STRCONST
, &tok
);
292 defp
->def
.co
= tok
.str
;
296 def_union (definition
*defp
)
301 /* case_list *tcase; */
307 defp
->def_kind
= DEF_UNION
;
308 scan (TOK_IDENT
, &tok
);
309 defp
->def_name
= tok
.str
;
310 scan (TOK_SWITCH
, &tok
);
311 scan (TOK_LPAREN
, &tok
);
312 get_declaration (&dec
, DEF_UNION
);
313 defp
->def
.un
.enum_decl
= dec
;
314 tailp
= &defp
->def
.un
.cases
;
315 scan (TOK_RPAREN
, &tok
);
316 scan (TOK_LBRACE
, &tok
);
317 scan (TOK_CASE
, &tok
);
318 while (tok
.kind
== TOK_CASE
)
320 scan2 (TOK_IDENT
, TOK_CHARCONST
, &tok
);
321 cases
= ALLOC (case_list
);
322 cases
->case_name
= tok
.str
;
323 scan (TOK_COLON
, &tok
);
324 /* now peek at next token */
328 if (peekscan (TOK_CASE
, &tok
))
333 scan2 (TOK_IDENT
, TOK_CHARCONST
, &tok
);
334 cases
->contflag
= 1; /* continued case statement */
336 tailp
= &cases
->next
;
337 cases
= ALLOC (case_list
);
338 cases
->case_name
= tok
.str
;
339 scan (TOK_COLON
, &tok
);
342 while (peekscan (TOK_CASE
, &tok
));
349 tailp
= &cases
->next
;
350 cases
= ALLOC (case_list
);
354 get_declaration (&dec
, DEF_UNION
);
355 cases
->case_decl
= dec
;
356 cases
->contflag
= 0; /* no continued case statement */
358 tailp
= &cases
->next
;
359 scan (TOK_SEMICOLON
, &tok
);
361 scan3 (TOK_CASE
, TOK_DEFAULT
, TOK_RBRACE
, &tok
);
364 if (tok
.kind
== TOK_DEFAULT
)
366 scan (TOK_COLON
, &tok
);
367 get_declaration (&dec
, DEF_UNION
);
368 defp
->def
.un
.default_decl
= ALLOC (declaration
);
369 *defp
->def
.un
.default_decl
= dec
;
370 scan (TOK_SEMICOLON
, &tok
);
371 scan (TOK_RBRACE
, &tok
);
375 defp
->def
.un
.default_decl
= NULL
;
379 static const char *reserved_words
[] =
396 static const char *reserved_types
[] =
404 * check that the given name is not one that would eventually result in
405 * xdr routines that would conflict with internal XDR routines.
408 check_type_name (const char *name
, int new_type
)
413 for (i
= 0; reserved_words
[i
] != NULL
; i
++)
415 if (strcmp (name
, reserved_words
[i
]) == 0)
418 "illegal (reserved) name :\'%s\' in type definition", name
);
424 for (i
= 0; reserved_types
[i
] != NULL
; i
++)
426 if (strcmp (name
, reserved_types
[i
]) == 0)
429 "illegal (reserved) name :\'%s\' in type definition", name
);
439 def_typedef (definition
* defp
)
443 defp
->def_kind
= DEF_TYPEDEF
;
444 get_declaration (&dec
, DEF_TYPEDEF
);
445 defp
->def_name
= dec
.name
;
446 check_type_name (dec
.name
, 1);
447 defp
->def
.ty
.old_prefix
= dec
.prefix
;
448 defp
->def
.ty
.old_type
= dec
.type
;
449 defp
->def
.ty
.rel
= dec
.rel
;
450 defp
->def
.ty
.array_max
= dec
.array_max
;
454 get_declaration (declaration
* dec
, defkind dkind
)
458 get_type (&dec
->prefix
, &dec
->type
, dkind
);
459 dec
->rel
= REL_ALIAS
;
460 if (streq (dec
->type
, "void"))
465 check_type_name (dec
->type
, 0);
467 scan2 (TOK_STAR
, TOK_IDENT
, &tok
);
468 if (tok
.kind
== TOK_STAR
)
470 dec
->rel
= REL_POINTER
;
471 scan (TOK_IDENT
, &tok
);
474 if (peekscan (TOK_LBRACKET
, &tok
))
476 if (dec
->rel
== REL_POINTER
)
478 error ("no array-of-pointer declarations -- use typedef");
480 dec
->rel
= REL_VECTOR
;
482 dec
->array_max
= tok
.str
;
483 scan (TOK_RBRACKET
, &tok
);
485 else if (peekscan (TOK_LANGLE
, &tok
))
487 if (dec
->rel
== REL_POINTER
)
489 error ("no array-of-pointer declarations -- use typedef");
491 dec
->rel
= REL_ARRAY
;
492 if (peekscan (TOK_RANGLE
, &tok
))
494 dec
->array_max
= "~0"; /* unspecified size, use max */
499 dec
->array_max
= tok
.str
;
500 scan (TOK_RANGLE
, &tok
);
503 if (streq (dec
->type
, "opaque"))
505 if (dec
->rel
!= REL_ARRAY
&& dec
->rel
!= REL_VECTOR
)
507 error ("array declaration expected");
510 else if (streq (dec
->type
, "string"))
512 if (dec
->rel
!= REL_ARRAY
)
514 error ("variable-length array declaration expected");
520 get_prog_declaration (declaration
* dec
, defkind dkind
, int num
/* arg number */ )
523 char name
[10]; /* argument name */
525 if (dkind
== DEF_PROGRAM
)
528 if (tok
.kind
== TOK_RPAREN
)
530 dec
->rel
= REL_ALIAS
;
537 get_type (&dec
->prefix
, &dec
->type
, dkind
);
538 dec
->rel
= REL_ALIAS
;
539 if (peekscan (TOK_IDENT
, &tok
)) /* optional name of argument */
540 strcpy (name
, tok
.str
);
542 sprintf (name
, "%s%d", ARGNAME
, num
); /* default name of argument */
544 dec
->name
= (char *) strdup (name
);
546 if (streq (dec
->type
, "void"))
551 if (streq (dec
->type
, "opaque"))
553 error ("opaque -- illegal argument type");
555 if (peekscan (TOK_STAR
, &tok
))
557 if (streq (dec
->type
, "string"))
559 error ("pointer to string not allowed in program arguments\n");
561 dec
->rel
= REL_POINTER
;
562 if (peekscan (TOK_IDENT
, &tok
)) /* optional name of argument */
563 dec
->name
= strdup (tok
.str
);
565 if (peekscan (TOK_LANGLE
, &tok
))
567 if (!streq (dec
->type
, "string"))
569 error ("arrays cannot be declared as arguments to procedures -- use typedef");
571 dec
->rel
= REL_ARRAY
;
572 if (peekscan (TOK_RANGLE
, &tok
))
574 dec
->array_max
= "~0"; /* unspecified size, use max */
579 dec
->array_max
= tok
.str
;
580 scan (TOK_RANGLE
, &tok
);
583 if (streq (dec
->type
, "string"))
585 if (dec
->rel
!= REL_ARRAY
)
586 { /* .x specifies just string as
590 dec
->rel
= REL_ARRAY
;
591 dec
->array_max
= "~0"; /* unspecified size, use max */
597 get_type (const char **prefixp
, const char **typep
, defkind dkind
)
612 scan (TOK_IDENT
, &tok
);
616 unsigned_dec (typep
);
620 (void) peekscan (TOK_INT
, &tok
);
624 (void) peekscan (TOK_INT
, &tok
);
628 (void) peekscan(TOK_INT
, &tok
);
631 if (dkind
!= DEF_UNION
&& dkind
!= DEF_PROGRAM
)
633 error ("voids allowed only inside union and program definitions with one argument");
647 error ("expected type specifier");
652 unsigned_dec (const char **typep
)
666 (void) peekscan (TOK_INT
, &tok
);
671 (void) peekscan (TOK_INT
, &tok
);
676 (void) peekscan(TOK_INT
, &tok
);