diff options
Diffstat (limited to 'sunrpc/rpc_parse.c')
-rw-r--r-- | sunrpc/rpc_parse.c | 395 |
1 files changed, 299 insertions, 96 deletions
diff --git a/sunrpc/rpc_parse.c b/sunrpc/rpc_parse.c index 325f75fbfc..92f365eeb0 100644 --- a/sunrpc/rpc_parse.c +++ b/sunrpc/rpc_parse.c @@ -1,11 +1,11 @@ -/* @(#)rpc_parse.c 2.1 88/08/01 4.0 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or - * program developed by the user. + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR @@ -27,24 +27,45 @@ * 2550 Garcia Avenue * Mountain View, California 94043 */ -#ifndef lint -static char sccsid[] = "@(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI"; -#endif /* - * rpc_parse.c, Parser for the RPC protocol compiler + * From: @(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI + */ +char parse_rcsid[] = + "$Id$"; + +/* + * rpc_parse.c, Parser for the RPC protocol compiler * Copyright (C) 1987 Sun Microsystems, Inc. */ #include <stdio.h> -#include "rpc_util.h" +#include <string.h> +#include "rpc/types.h" #include "rpc_scan.h" #include "rpc_parse.h" +#include "rpc_util.h" +#include "proto.h" + +#define ARGNAME "arg" + +static void isdefined(definition *defp); +static void def_struct(definition *defp); +static void def_program(definition *defp); +static void def_enum(definition *defp); +static void def_const(definition *defp); +static void def_union(definition *defp); +static void check_type_name(const char *name, int new_type); +static void def_typedef(definition *defp); +static void get_declaration(declaration *dec, defkind dkind); +static void get_prog_declaration(declaration *dec, defkind dkind, int num); +static void get_type(const char **prefixp, const char **typep, defkind dkind); +static void unsigned_dec(const char **typep); /* * return the next definition you see */ definition * -get_definition() +get_definition(void) { definition *defp; token tok; @@ -72,26 +93,22 @@ get_definition() break; case TOK_EOF: return (NULL); - break; default: - error(_("definition keyword expected")); + error("definition keyword expected"); } scan(TOK_SEMICOLON, &tok); isdefined(defp); return (defp); } -static -isdefined(defp) - definition *defp; +static void +isdefined(definition *defp) { STOREVAL(&defined, defp); } - -static -def_struct(defp) - definition *defp; +static void +def_struct(definition *defp) { token tok; declaration dec; @@ -117,21 +134,25 @@ def_struct(defp) *tailp = NULL; } -static -def_program(defp) - definition *defp; +static void +def_program(definition *defp) { token tok; + declaration dec; + decl_list *decls; + decl_list **tailp; version_list *vlist; version_list **vtailp; proc_list *plist; proc_list **ptailp; - + int num_args; + bool_t isvoid = FALSE; /* whether first argument is void */ defp->def_kind = DEF_PROGRAM; scan(TOK_IDENT, &tok); defp->def_name = tok.str; scan(TOK_LBRACE, &tok); vtailp = &defp->def.pr.versions; + tailp = &defp->def.st.decls; scan(TOK_VERSION, &tok); do { scan(TOK_IDENT, &tok); @@ -140,33 +161,74 @@ def_program(defp) scan(TOK_LBRACE, &tok); ptailp = &vlist->procs; do { + /* get result type */ plist = ALLOC(proc_list); - get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM); + get_type(&plist->res_prefix, &plist->res_type, + DEF_PROGRAM); if (streq(plist->res_type, "opaque")) { - error(_("illegal result type")); + error("illegal result type"); } scan(TOK_IDENT, &tok); plist->proc_name = tok.str; scan(TOK_LPAREN, &tok); - get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM); - if (streq(plist->arg_type, "opaque")) { - error("illegal argument type"); + /* get args - first one*/ + num_args = 1; + isvoid = FALSE; + /* type of DEF_PROGRAM in the first + * get_prog_declaration and DEF_STURCT in the next + * allows void as argument if it is the only argument + */ + get_prog_declaration(&dec, DEF_PROGRAM, num_args); + if (streq(dec.type, "void")) + isvoid = TRUE; + decls = ALLOC(decl_list); + plist->args.decls = decls; + decls->decl = dec; + tailp = &decls->next; + /* get args */ + while(peekscan(TOK_COMMA, &tok)) { + num_args++; + get_prog_declaration(&dec, DEF_STRUCT, + num_args); + decls = ALLOC(decl_list); + decls->decl = dec; + *tailp = decls; + if (streq(dec.type, "void")) + isvoid = TRUE; + tailp = &decls->next; + } + /* multiple arguments are only allowed in newstyle */ + if( !newstyle && num_args > 1 ) { + error("only one argument is allowed" ); + } + if (isvoid && num_args > 1) { + error("illegal use of void in program definition"); } + *tailp = NULL; scan(TOK_RPAREN, &tok); scan(TOK_EQUAL, &tok); scan_num(&tok); scan(TOK_SEMICOLON, &tok); plist->proc_num = tok.str; + plist->arg_num = num_args; *ptailp = plist; ptailp = &plist->next; peek(&tok); } while (tok.kind != TOK_RBRACE); + *ptailp = NULL; *vtailp = vlist; vtailp = &vlist->next; scan(TOK_RBRACE, &tok); scan(TOK_EQUAL, &tok); scan_num(&tok); vlist->vers_num = tok.str; + /* make the argument structure name for each arg*/ + for(plist = vlist->procs; plist != NULL; + plist = plist->next) { + plist->args.argname = make_argname(plist->proc_name, + vlist->vers_num); + /* free the memory ??*/ + } scan(TOK_SEMICOLON, &tok); scan2(TOK_VERSION, TOK_RBRACE, &tok); } while (tok.kind == TOK_VERSION); @@ -176,9 +238,9 @@ def_program(defp) *vtailp = NULL; } -static -def_enum(defp) - definition *defp; + +static void +def_enum(definition *defp) { token tok; enumval_list *elist; @@ -206,9 +268,8 @@ def_enum(defp) *tailp = NULL; } -static -def_const(defp) - definition *defp; +static void +def_const(definition *defp) { token tok; @@ -220,72 +281,150 @@ def_const(defp) defp->def.co = tok.str; } -static -def_union(defp) - definition *defp; +static void +def_union(definition *defp) { - token tok; - declaration dec; - case_list *cases; - case_list **tailp; + token tok; + declaration dec; + case_list *cases; +/* case_list *tcase; */ + case_list **tailp; + int flag; - defp->def_kind = DEF_UNION; - scan(TOK_IDENT, &tok); - defp->def_name = tok.str; - scan(TOK_SWITCH, &tok); - scan(TOK_LPAREN, &tok); - get_declaration(&dec, DEF_UNION); - defp->def.un.enum_decl = dec; - tailp = &defp->def.un.cases; - scan(TOK_RPAREN, &tok); - scan(TOK_LBRACE, &tok); - scan(TOK_CASE, &tok); - while (tok.kind == TOK_CASE) { - scan(TOK_IDENT, &tok); - cases = ALLOC(case_list); - cases->case_name = tok.str; - scan(TOK_COLON, &tok); - get_declaration(&dec, DEF_UNION); - cases->case_decl = dec; - *tailp = cases; - tailp = &cases->next; - scan(TOK_SEMICOLON, &tok); - scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); - } - *tailp = NULL; - if (tok.kind == TOK_DEFAULT) { - scan(TOK_COLON, &tok); - get_declaration(&dec, DEF_UNION); - defp->def.un.default_decl = ALLOC(declaration); - *defp->def.un.default_decl = dec; - scan(TOK_SEMICOLON, &tok); - scan(TOK_RBRACE, &tok); - } else { - defp->def.un.default_decl = NULL; - } + defp->def_kind = DEF_UNION; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_SWITCH, &tok); + scan(TOK_LPAREN, &tok); + get_declaration(&dec, DEF_UNION); + defp->def.un.enum_decl = dec; + tailp = &defp->def.un.cases; + scan(TOK_RPAREN, &tok); + scan(TOK_LBRACE, &tok); + scan(TOK_CASE, &tok); + while (tok.kind == TOK_CASE) { + scan2(TOK_IDENT, TOK_CHARCONST, &tok); + cases = ALLOC(case_list); + cases->case_name = tok.str; + scan(TOK_COLON, &tok); + /* now peek at next token */ + flag=0; + if(peekscan(TOK_CASE,&tok)) + { + + do + { + scan2(TOK_IDENT, TOK_CHARCONST, &tok); + cases->contflag=1; /* continued case statement */ + *tailp = cases; + tailp = &cases->next; + cases = ALLOC(case_list); + cases->case_name = tok.str; + scan(TOK_COLON, &tok); + + }while(peekscan(TOK_CASE,&tok)); + } + else + if(flag) + { + + *tailp = cases; + tailp = &cases->next; + cases = ALLOC(case_list); + }; + + get_declaration(&dec, DEF_UNION); + cases->case_decl = dec; + cases->contflag=0; /* no continued case statement */ + *tailp = cases; + tailp = &cases->next; + scan(TOK_SEMICOLON, &tok); + + scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); + } + *tailp = NULL; + if (tok.kind == TOK_DEFAULT) { + scan(TOK_COLON, &tok); + get_declaration(&dec, DEF_UNION); + defp->def.un.default_decl = ALLOC(declaration); + *defp->def.un.default_decl = dec; + scan(TOK_SEMICOLON, &tok); + scan(TOK_RBRACE, &tok); + } else { + defp->def.un.default_decl = NULL; + } } +static const char *reserved_words[] = +{ + "array", + "bytes", + "destroy", + "free", + "getpos", + "inline", + "pointer", + "reference", + "setpos", + "sizeof", + "union", + "vector", + NULL + }; -static -def_typedef(defp) - definition *defp; +static const char *reserved_types[] = +{ + "opaque", + "string", + NULL + }; + +/* + * check that the given name is not one that would eventually result in + * xdr routines that would conflict with internal XDR routines. + */ +static void check_type_name(const char *name, int new_type) +{ + int i; + char tmp[100]; + + for( i = 0; reserved_words[i] != NULL; i++ ) { + if( strcmp( name, reserved_words[i] ) == 0 ) { + sprintf(tmp, + "illegal (reserved) name :\'%s\' in type definition", name ); + error(tmp); + } + } + if( new_type ) { + for( i = 0; reserved_types[i] != NULL; i++ ) { + if( strcmp( name, reserved_types[i] ) == 0 ) { + sprintf(tmp, + "illegal (reserved) name :\'%s\' in type definition", name ); + error(tmp); + } + } + } +} + + + +static void +def_typedef(definition *defp) { declaration dec; defp->def_kind = DEF_TYPEDEF; get_declaration(&dec, DEF_TYPEDEF); defp->def_name = dec.name; + check_type_name(dec.name, 1); defp->def.ty.old_prefix = dec.prefix; defp->def.ty.old_type = dec.type; defp->def.ty.rel = dec.rel; defp->def.ty.array_max = dec.array_max; } - -static -get_declaration(dec, dkind) - declaration *dec; - defkind dkind; +static void +get_declaration(declaration *dec, defkind dkind) { token tok; @@ -294,6 +433,9 @@ get_declaration(dec, dkind) if (streq(dec->type, "void")) { return; } + + check_type_name(dec->type, 0); + scan2(TOK_STAR, TOK_IDENT, &tok); if (tok.kind == TOK_STAR) { dec->rel = REL_POINTER; @@ -302,7 +444,7 @@ get_declaration(dec, dkind) dec->name = tok.str; if (peekscan(TOK_LBRACKET, &tok)) { if (dec->rel == REL_POINTER) { - error(_("no array-of-pointer declarations -- use typedef")); + error("no array-of-pointer declarations -- use typedef"); } dec->rel = REL_VECTOR; scan_num(&tok); @@ -310,7 +452,7 @@ get_declaration(dec, dkind) scan(TOK_RBRACKET, &tok); } else if (peekscan(TOK_LANGLE, &tok)) { if (dec->rel == REL_POINTER) { - error(_("no array-of-pointer declarations -- use typedef")); + error("no array-of-pointer declarations -- use typedef"); } dec->rel = REL_ARRAY; if (peekscan(TOK_RANGLE, &tok)) { @@ -323,21 +465,84 @@ get_declaration(dec, dkind) } if (streq(dec->type, "opaque")) { if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { - error(_("array declaration expected")); + error("array declaration expected"); } } else if (streq(dec->type, "string")) { if (dec->rel != REL_ARRAY) { - error(_("variable-length array declaration expected")); + error("variable-length array declaration expected"); } } } -static -get_type(prefixp, typep, dkind) - char **prefixp; - char **typep; - defkind dkind; +static void +get_prog_declaration(declaration *dec, defkind dkind, int num /* arg number */) +{ + token tok; + char name[10]; /* argument name */ + + if (dkind == DEF_PROGRAM) { + peek(&tok); + if (tok.kind == TOK_RPAREN) { /* no arguments */ + dec->rel = REL_ALIAS; + dec->type = "void"; + dec->prefix = NULL; + dec->name = NULL; + return; + } + } + get_type(&dec->prefix, &dec->type, dkind); + dec->rel = REL_ALIAS; + if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */ + strcpy(name, tok.str); + else + sprintf(name, "%s%d", ARGNAME, num); /* default name of argument */ + + dec->name = (char *) strdup(name); + + if (streq(dec->type, "void")) { + return; + } + + if (streq(dec->type, "opaque")) { + error("opaque -- illegal argument type"); + } + if (peekscan(TOK_STAR, &tok)) { + if (streq(dec->type, "string")) { + error("pointer to string not allowed in program arguments\n"); + } + dec->rel = REL_POINTER; + if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */ + dec->name = strdup(tok.str); + } + if (peekscan(TOK_LANGLE, &tok)) { + if (!streq(dec->type, "string")) { + error("arrays cannot be declared as arguments to procedures -- use typedef"); + } + dec->rel = REL_ARRAY; + if (peekscan(TOK_RANGLE, &tok)) { + dec->array_max = "~0";/* unspecified size, use max */ + } else { + scan_num(&tok); + dec->array_max = tok.str; + scan(TOK_RANGLE, &tok); + } + } + if (streq(dec->type, "string")) { + if (dec->rel != REL_ARRAY) { /* .x specifies just string as + * type of argument + * - make it string<> + */ + dec->rel = REL_ARRAY; + dec->array_max = "~0";/* unspecified size, use max */ + } + } +} + + + +static void +get_type(const char **prefixp, const char **typep, defkind dkind) { token tok; @@ -367,7 +572,7 @@ get_type(prefixp, typep, dkind) break; case TOK_VOID: if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { - error(_("voids allowed only inside union and program definitions")); + error("voids allowed only inside union and program definitions with one argument"); } *typep = tok.str; break; @@ -381,14 +586,12 @@ get_type(prefixp, typep, dkind) *typep = tok.str; break; default: - error(_("expected type specifier")); + error("expected type specifier"); } } - -static -unsigned_dec(typep) - char **typep; +static void +unsigned_dec(const char **typep) { token tok; |