4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
29 * University Copyright- Copyright (c) 1982, 1986, 1988
30 * The Regents of the University of California
33 * University Acknowledgment- Portions of this document are derived from
34 * software developed by the University of California, Berkeley, and its
39 * rpc_parse.c, Parser for the RPC protocol compiler
44 #include "rpc/types.h"
46 #include "rpc_parse.h"
51 extern char *make_argname(char *, char *);
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(char **, char **, defkind
);
63 static void unsigned_dec(char **);
66 * return the next definition you see
74 defp
= calloc(1, sizeof (definition
));
98 error("definition keyword expected");
100 scan(TOK_SEMICOLON
, &tok
);
106 isdefined(definition
*defp
)
108 STOREVAL(&defined
, defp
);
112 * We treat s == NULL the same as *s == '\0'
115 streqn(const char *s1
, const char *s2
)
124 return (strcmp(s1
, s2
) == 0);
128 cmptype(definition
*defp
, char *type
)
130 /* We only want typedef definitions */
131 if (streq(defp
->def_name
, type
) && defp
->def_kind
== DEF_TYPEDEF
)
137 check_self_reference(const char *name
, const declaration
*decp
, int first
)
140 * Now check for the following special case if first is true:
148 * In the above cases foo has not yet been entered in the type list,
149 * defined. So there is no typedef entry. The prefix in that case
152 if (decp
->rel
== REL_POINTER
&&
153 (streqn(decp
->prefix
, "struct") ||
154 (first
&& streqn(decp
->prefix
, ""))) &&
155 streqn(name
, decp
->type
))
161 is_self_reference(definition
*defp
, declaration
*decp
)
166 if (check_self_reference(defp
->def_name
, decp
, 1))
170 * Check for valid declaration:
171 * Only prefixes allowed are none and struct.
172 * Only relations allowed are pointer or alias.
174 if (!streqn(decp
->prefix
, "struct") && !streqn(decp
->prefix
, ""))
176 if (decp
->rel
!= REL_POINTER
&& decp
->rel
!= REL_ALIAS
)
179 current
.rel
= decp
->rel
;
180 current
.prefix
= decp
->prefix
;
181 current
.type
= decp
->type
;
182 current
.name
= decp
->name
;
184 while (!check_self_reference(defp
->def_name
, decp
, 0)) {
185 dp
= FINDVAL(defined
, decp
->type
, cmptype
);
188 * Check if we found a definition.
194 * Check for valid prefix. We eventually need to see one
195 * and only one struct.
197 if (streqn(decp
->prefix
, "")) {
199 * If the current declaration prefix in empty
200 * then the definition found must have an empty
201 * prefix or a struct prefix
203 if (!streqn(dp
->def
.ty
.old_prefix
, "") &&
204 !streqn(dp
->def
.ty
.old_prefix
, "struct"))
206 } else if (streqn(decp
->prefix
, "struct") &&
207 !streqn(dp
->def
.ty
.old_prefix
, ""))
209 * if the current prefix is struct tne new prefix
213 else if (!streqn(decp
->prefix
, "struct"))
214 /* Should never get here */
218 * Check for valid relation. We need to see one and
219 * only one REL_POINTER. The only valid relation types
220 * are REL_POINTER and REL_ALIAS.
222 if (decp
->rel
== REL_POINTER
&& dp
->def
.ty
.rel
!= REL_ALIAS
)
224 if (decp
->rel
== REL_ALIAS
&&
225 (dp
->def
.ty
.rel
!= REL_ALIAS
&&
226 dp
->def
.ty
.rel
!= REL_POINTER
))
228 if (decp
->rel
!= REL_ALIAS
&& decp
->rel
!= REL_POINTER
)
229 /* Should never get here */
232 /* Set up the current declaration */
233 if (streqn(decp
->prefix
, ""))
234 decp
->prefix
= dp
->def
.ty
.old_prefix
;
235 decp
->type
= dp
->def
.ty
.old_type
;
236 if (decp
->rel
== REL_ALIAS
)
237 decp
->rel
= dp
->def
.ty
.rel
;
240 /* We have a self reference type */
245 def_struct(definition
*defp
)
250 decl_list
**tailp
, *endp
;
252 defp
->def_kind
= DEF_STRUCT
;
254 scan(TOK_IDENT
, &tok
);
255 defp
->def_name
= tok
.str
;
256 scan(TOK_LBRACE
, &tok
);
257 tailp
= &defp
->def
.st
.decls
;
258 defp
->def
.st
.tail
= NULL
;
260 get_declaration(&dec
, DEF_STRUCT
);
261 decls
= calloc(1, sizeof (decl_list
));
264 * Keep a referenct to the last declaration to check for
267 endp
= *tailp
= decls
;
268 tailp
= &decls
->next
;
269 scan(TOK_SEMICOLON
, &tok
);
271 } while (tok
.kind
!= TOK_RBRACE
);
274 * Check for tail recurse. If the last declaration refers to this
275 * structure then mark this stucture to convert the tail recursion
278 defp
->def
.st
.self_pointer
= is_self_reference(defp
, &endp
->decl
);
280 defp
->def
.st
.tail
= endp
;
284 def_program(definition
*defp
)
291 version_list
**vtailp
;
295 bool_t isvoid
= FALSE
; /* whether first argument is void */
296 defp
->def_kind
= DEF_PROGRAM
;
297 scan(TOK_IDENT
, &tok
);
298 defp
->def_name
= tok
.str
;
299 scan(TOK_LBRACE
, &tok
);
300 vtailp
= &defp
->def
.pr
.versions
;
301 tailp
= &defp
->def
.st
.decls
;
302 scan(TOK_VERSION
, &tok
);
304 scan(TOK_IDENT
, &tok
);
305 vlist
= calloc(1, sizeof (version_list
));
306 vlist
->vers_name
= tok
.str
;
307 scan(TOK_LBRACE
, &tok
);
308 ptailp
= &vlist
->procs
;
310 /* get result type */
311 plist
= calloc(1, sizeof (proc_list
));
312 get_type(&plist
->res_prefix
, &plist
->res_type
,
314 if (streq(plist
->res_type
, "opaque")) {
315 error("illegal result type");
317 scan(TOK_IDENT
, &tok
);
318 plist
->proc_name
= tok
.str
;
319 scan(TOK_LPAREN
, &tok
);
320 /* get args - first one */
324 * type of DEF_PROGRAM in the first
325 * get_prog_declaration and DEF_STURCT in the next
326 * allows void as argument if it is the only argument
328 get_prog_declaration(&dec
, DEF_PROGRAM
, num_args
);
329 if (streq(dec
.type
, "void"))
331 decls
= calloc(1, sizeof (decl_list
));
332 plist
->args
.decls
= decls
;
334 tailp
= &decls
->next
;
336 while (peekscan(TOK_COMMA
, &tok
)) {
338 get_prog_declaration(&dec
, DEF_STRUCT
,
340 decls
= calloc(1, sizeof (decl_list
));
343 if (streq(dec
.type
, "void"))
345 tailp
= &decls
->next
;
347 /* multiple arguments are only allowed in newstyle */
348 if (!newstyle
&& num_args
> 1) {
349 error("only one argument is allowed");
351 if (isvoid
&& num_args
> 1) {
352 error("illegal use of void "
353 "in program definition");
356 scan(TOK_RPAREN
, &tok
);
357 scan(TOK_EQUAL
, &tok
);
359 scan(TOK_SEMICOLON
, &tok
);
360 plist
->proc_num
= tok
.str
;
361 plist
->arg_num
= num_args
;
363 ptailp
= &plist
->next
;
365 } while (tok
.kind
!= TOK_RBRACE
);
368 vtailp
= &vlist
->next
;
369 scan(TOK_RBRACE
, &tok
);
370 scan(TOK_EQUAL
, &tok
);
372 vlist
->vers_num
= tok
.str
;
373 /* make the argument structure name for each arg */
374 for (plist
= vlist
->procs
; plist
!= NULL
; plist
= plist
->next
) {
375 plist
->args
.argname
= make_argname(plist
->proc_name
,
377 /* free the memory ?? */
379 scan(TOK_SEMICOLON
, &tok
);
380 scan2(TOK_VERSION
, TOK_RBRACE
, &tok
);
381 } while (tok
.kind
== TOK_VERSION
);
382 scan(TOK_EQUAL
, &tok
);
384 defp
->def
.pr
.prog_num
= tok
.str
;
389 def_enum(definition
*defp
)
393 enumval_list
**tailp
;
395 defp
->def_kind
= DEF_ENUM
;
396 scan(TOK_IDENT
, &tok
);
397 defp
->def_name
= tok
.str
;
398 scan(TOK_LBRACE
, &tok
);
399 tailp
= &defp
->def
.en
.vals
;
401 scan(TOK_IDENT
, &tok
);
402 elist
= calloc(1, sizeof (enumval_list
));
403 elist
->name
= tok
.str
;
404 elist
->assignment
= NULL
;
405 scan3(TOK_COMMA
, TOK_RBRACE
, TOK_EQUAL
, &tok
);
406 if (tok
.kind
== TOK_EQUAL
) {
408 elist
->assignment
= tok
.str
;
409 scan2(TOK_COMMA
, TOK_RBRACE
, &tok
);
412 tailp
= &elist
->next
;
413 } while (tok
.kind
!= TOK_RBRACE
);
418 def_const(definition
*defp
)
422 defp
->def_kind
= DEF_CONST
;
423 scan(TOK_IDENT
, &tok
);
424 defp
->def_name
= tok
.str
;
425 scan(TOK_EQUAL
, &tok
);
426 scan2(TOK_IDENT
, TOK_STRCONST
, &tok
);
427 defp
->def
.co
= tok
.str
;
431 def_union(definition
*defp
)
439 defp
->def_kind
= DEF_UNION
;
440 scan(TOK_IDENT
, &tok
);
441 defp
->def_name
= tok
.str
;
442 scan(TOK_SWITCH
, &tok
);
443 scan(TOK_LPAREN
, &tok
);
444 get_declaration(&dec
, DEF_UNION
);
445 defp
->def
.un
.enum_decl
= dec
;
446 tailp
= &defp
->def
.un
.cases
;
447 scan(TOK_RPAREN
, &tok
);
448 scan(TOK_LBRACE
, &tok
);
449 scan(TOK_CASE
, &tok
);
450 while (tok
.kind
== TOK_CASE
) {
451 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
452 cases
= calloc(1, sizeof (case_list
));
453 cases
->case_name
= tok
.str
;
454 scan(TOK_COLON
, &tok
);
455 /* now peek at next token */
457 if (peekscan(TOK_CASE
, &tok
)) {
459 scan2(TOK_IDENT
, TOK_CHARCONST
, &tok
);
461 /* continued case statement */
463 tailp
= &cases
->next
;
464 cases
= calloc(1, sizeof (case_list
));
465 cases
->case_name
= tok
.str
;
466 scan(TOK_COLON
, &tok
);
467 } while (peekscan(TOK_CASE
, &tok
));
470 tailp
= &cases
->next
;
471 cases
= calloc(1, sizeof (case_list
));
474 get_declaration(&dec
, DEF_UNION
);
475 cases
->case_decl
= dec
;
476 cases
->contflag
= 0; /* no continued case statement */
478 tailp
= &cases
->next
;
479 scan(TOK_SEMICOLON
, &tok
);
481 scan3(TOK_CASE
, TOK_DEFAULT
, TOK_RBRACE
, &tok
);
484 if (tok
.kind
== TOK_DEFAULT
) {
485 scan(TOK_COLON
, &tok
);
486 get_declaration(&dec
, DEF_UNION
);
487 defp
->def
.un
.default_decl
= calloc(1, sizeof (declaration
));
488 *defp
->def
.un
.default_decl
= dec
;
489 scan(TOK_SEMICOLON
, &tok
);
490 scan(TOK_RBRACE
, &tok
);
492 defp
->def
.un
.default_decl
= NULL
;
496 static char *reserved_words
[] = {
512 static char *reserved_types
[] = {
519 * check that the given name is not one that would eventually result in
520 * xdr routines that would conflict with internal XDR routines.
523 check_type_name(char *name
, int new_type
)
528 for (i
= 0; reserved_words
[i
] != NULL
; i
++) {
529 if (strcmp(name
, reserved_words
[i
]) == 0) {
530 (void) snprintf(tmp
, sizeof (tmp
),
531 "illegal (reserved) name :\'%s\' "
532 "in type definition",
538 for (i
= 0; reserved_types
[i
] != NULL
; i
++) {
539 if (strcmp(name
, reserved_types
[i
]) == 0) {
540 (void) snprintf(tmp
, sizeof (tmp
),
541 "illegal (reserved) name :\'%s\' "
542 "in type definition",
551 def_typedef(definition
*defp
)
555 defp
->def_kind
= DEF_TYPEDEF
;
556 get_declaration(&dec
, DEF_TYPEDEF
);
557 defp
->def_name
= dec
.name
;
558 check_type_name(dec
.name
, 1);
559 defp
->def
.ty
.old_prefix
= dec
.prefix
;
560 defp
->def
.ty
.old_type
= dec
.type
;
561 defp
->def
.ty
.rel
= dec
.rel
;
562 defp
->def
.ty
.array_max
= dec
.array_max
;
566 get_declaration(declaration
*dec
, defkind dkind
)
570 get_type(&dec
->prefix
, &dec
->type
, dkind
);
571 dec
->rel
= REL_ALIAS
;
572 if (streq(dec
->type
, "void"))
575 check_type_name(dec
->type
, 0);
576 scan2(TOK_STAR
, TOK_IDENT
, &tok
);
577 if (tok
.kind
== TOK_STAR
) {
578 dec
->rel
= REL_POINTER
;
579 scan(TOK_IDENT
, &tok
);
582 if (peekscan(TOK_LBRACKET
, &tok
)) {
583 if (dec
->rel
== REL_POINTER
)
584 error("no array-of-pointer declarations "
586 dec
->rel
= REL_VECTOR
;
588 dec
->array_max
= tok
.str
;
589 scan(TOK_RBRACKET
, &tok
);
590 } else if (peekscan(TOK_LANGLE
, &tok
)) {
591 if (dec
->rel
== REL_POINTER
)
592 error("no array-of-pointer declarations "
594 dec
->rel
= REL_ARRAY
;
595 if (peekscan(TOK_RANGLE
, &tok
)) {
596 dec
->array_max
= "~0"; /* unspecified size, use max */
599 dec
->array_max
= tok
.str
;
600 scan(TOK_RANGLE
, &tok
);
603 if (streq(dec
->type
, "opaque")) {
604 if (dec
->rel
!= REL_ARRAY
&& dec
->rel
!= REL_VECTOR
) {
605 error("array declaration expected");
607 } else if (streq(dec
->type
, "string")) {
608 if (dec
->rel
!= REL_ARRAY
) {
609 error("variable-length array declaration expected");
615 get_prog_declaration(declaration
*dec
, defkind dkind
, int num
)
618 char name
[sizeof (ARGNAME
) + 10];
620 if (dkind
== DEF_PROGRAM
) {
622 if (tok
.kind
== TOK_RPAREN
) { /* no arguments */
623 dec
->rel
= REL_ALIAS
;
630 get_type(&dec
->prefix
, &dec
->type
, dkind
);
631 dec
->rel
= REL_ALIAS
;
632 if (peekscan(TOK_IDENT
, &tok
)) /* optional name of argument */
633 dec
->name
= strdup(tok
.str
);
635 /* default name of argument */
636 (void) snprintf(name
, sizeof (name
), "%s%d", ARGNAME
, num
);
637 dec
->name
= strdup(name
);
639 if (dec
->name
== NULL
)
640 error("internal error -- out of memory");
642 if (streq(dec
->type
, "void"))
645 if (streq(dec
->type
, "opaque"))
646 error("opaque -- illegal argument type");
647 if (peekscan(TOK_STAR
, &tok
)) {
648 if (streq(dec
->type
, "string")) {
649 error("pointer to string not allowed "
650 "in program arguments\n");
652 dec
->rel
= REL_POINTER
;
653 if (peekscan(TOK_IDENT
, &tok
))
654 /* optional name of argument */
655 dec
->name
= strdup(tok
.str
);
657 if (peekscan(TOK_LANGLE
, &tok
)) {
658 if (!streq(dec
->type
, "string")) {
659 error("arrays cannot be declared as arguments "
660 "to procedures -- use typedef");
662 dec
->rel
= REL_ARRAY
;
663 if (peekscan(TOK_RANGLE
, &tok
)) {
664 dec
->array_max
= "~0";
665 /* unspecified size, use max */
668 dec
->array_max
= tok
.str
;
669 scan(TOK_RANGLE
, &tok
);
672 if (streq(dec
->type
, "string")) {
673 if (dec
->rel
!= REL_ARRAY
) {
675 * .x specifies just string as
679 dec
->rel
= REL_ARRAY
;
680 dec
->array_max
= "~0"; /* unspecified size, use max */
686 get_type(char **prefixp
, char **typep
, defkind dkind
)
700 scan(TOK_IDENT
, &tok
);
708 (void) peekscan(TOK_INT
, &tok
);
712 (void) peekscan(TOK_INT
, &tok
);
715 *typep
= "longlong_t";
716 (void) peekscan(TOK_INT
, &tok
);
720 if (dkind
!= DEF_UNION
&& dkind
!= DEF_PROGRAM
&&
721 dkind
!= DEF_RESULT
) {
722 error("voids allowed only inside union and "
723 "program definitions with one argument");
728 if (dkind
!= DEF_RESULT
) {
729 error("oneways allowed only inside result definitions");
744 error("expected type specifier");
749 unsigned_dec(char **typep
)
762 (void) peekscan(TOK_INT
, &tok
);
767 (void) peekscan(TOK_INT
, &tok
);
771 *typep
= "u_longlong_t";
772 (void) peekscan(TOK_INT
, &tok
);