From be49c58d77ce855f902728b0c68fc10bafee6257 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 6 Dec 2015 10:24:52 +0100 Subject: libtirpc: update to latest stable version --- package/libtirpc/src/rpcgen/rpc_parse.c | 609 ++++++++++++++++++++++++++++++++ 1 file changed, 609 insertions(+) create mode 100644 package/libtirpc/src/rpcgen/rpc_parse.c (limited to 'package/libtirpc/src/rpcgen/rpc_parse.c') diff --git a/package/libtirpc/src/rpcgen/rpc_parse.c b/package/libtirpc/src/rpcgen/rpc_parse.c new file mode 100644 index 000000000..b53a55332 --- /dev/null +++ b/package/libtirpc/src/rpcgen/rpc_parse.c @@ -0,0 +1,609 @@ +/* + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if 0 +static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI"; +#endif + +/* + * rpc_parse.c, Parser for the RPC protocol compiler + * Copyright (C) 1987 Sun Microsystems, Inc. + */ +#include +#include +#include "rpc/types.h" +#include "rpc_scan.h" +#include "rpc_parse.h" +#include "rpc_util.h" + +#define ARGNAME "arg" + +/* +extern char *make_argname(); +extern char *strdup(); + */ + +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(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(char **prefixp, char **typep, defkind dkind); +static void unsigned_dec(char **typep); + +/* + * return the next definition you see + */ +definition * +get_definition(void) +{ + definition *defp; + token tok; + + defp = ALLOC(definition); + get_token(&tok); + switch (tok.kind) { + case TOK_STRUCT: + def_struct(defp); + break; + case TOK_UNION: + def_union(defp); + break; + case TOK_TYPEDEF: + def_typedef(defp); + break; + case TOK_ENUM: + def_enum(defp); + break; + case TOK_PROGRAM: + def_program(defp); + break; + case TOK_CONST: + def_const(defp); + break; + case TOK_EOF: + free(defp); + return (NULL); + default: + error("definition keyword expected"); + } + scan(TOK_SEMICOLON, &tok); + isdefined(defp); + return (defp); +} + +static void +isdefined(definition *defp) +{ + STOREVAL(&defined, defp); +} + +static void +def_struct(definition *defp) +{ + token tok; + declaration dec; + decl_list *decls; + decl_list **tailp; + + defp->def_kind = DEF_STRUCT; + + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_LBRACE, &tok); + tailp = &defp->def.st.decls; + do { + get_declaration(&dec, DEF_STRUCT); + decls = ALLOC(decl_list); + decls->decl = dec; + *tailp = decls; + tailp = &decls->next; + scan(TOK_SEMICOLON, &tok); + peek(&tok); + } while (tok.kind != TOK_RBRACE); + get_token(&tok); + *tailp = NULL; +} + +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); + vlist = ALLOC(version_list); + vlist->vers_name = tok.str; + 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); + if (streq(plist->res_type, "opaque")) { + error("illegal result type"); + } + scan(TOK_IDENT, &tok); + plist->proc_name = tok.str; + scan(TOK_LPAREN, &tok); + /* 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); + scan(TOK_EQUAL, &tok); + scan_num(&tok); + defp->def.pr.prog_num = tok.str; + *vtailp = NULL; +} + + +static void +def_enum(definition *defp) +{ + token tok; + enumval_list *elist; + enumval_list **tailp; + + defp->def_kind = DEF_ENUM; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_LBRACE, &tok); + tailp = &defp->def.en.vals; + do { + scan(TOK_IDENT, &tok); + elist = ALLOC(enumval_list); + elist->name = tok.str; + elist->assignment = NULL; + scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); + if (tok.kind == TOK_EQUAL) { + scan_num(&tok); + elist->assignment = tok.str; + scan2(TOK_COMMA, TOK_RBRACE, &tok); + } + *tailp = elist; + tailp = &elist->next; + } while (tok.kind != TOK_RBRACE); + *tailp = NULL; +} + +static void +def_const(definition *defp) +{ + token tok; + + defp->def_kind = DEF_CONST; + scan(TOK_IDENT, &tok); + defp->def_name = tok.str; + scan(TOK_EQUAL, &tok); + scan2(TOK_IDENT, TOK_STRCONST, &tok); + defp->def.co = tok.str; +} + +static void +def_union(definition *defp) +{ + token tok; + declaration dec; + case_list *cases; + case_list **tailp; + + 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 */ + 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)); + } + + 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 char* reserved_words[] = +{ + "array", + "bytes", + "destroy", + "free", + "getpos", + "inline", + "pointer", + "reference", + "setpos", + "sizeof", + "union", + "vector", + NULL + }; + +static 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(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 void +get_declaration(declaration *dec, defkind dkind) +{ + token tok; + + get_type(&dec->prefix, &dec->type, dkind); + dec->rel = REL_ALIAS; + 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; + scan(TOK_IDENT, &tok); + } + dec->name = tok.str; + if (peekscan(TOK_LBRACKET, &tok)) { + if (dec->rel == REL_POINTER) { + error("no array-of-pointer declarations -- use typedef"); + } + dec->rel = REL_VECTOR; + scan_num(&tok); + dec->array_max = tok.str; + scan(TOK_RBRACKET, &tok); + } else if (peekscan(TOK_LANGLE, &tok)) { + if (dec->rel == REL_POINTER) { + error("no array-of-pointer declarations -- 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, "opaque")) { + if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { + error("array declaration expected"); + } + } else if (streq(dec->type, "string")) { + if (dec->rel != REL_ARRAY) { + error("variable-length array declaration expected"); + } + } +} + + +static void +get_prog_declaration(declaration *dec, defkind dkind, int num) +{ + 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(char **prefixp, char **typep, defkind dkind) +{ + token tok; + + *prefixp = NULL; + get_token(&tok); + switch (tok.kind) { + case TOK_IDENT: + *typep = tok.str; + break; + case TOK_STRUCT: + case TOK_ENUM: + case TOK_UNION: + *prefixp = tok.str; + scan(TOK_IDENT, &tok); + *typep = tok.str; + break; + case TOK_UNSIGNED: + unsigned_dec(typep); + break; + case TOK_SHORT: + *typep = "short"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_INT32: + *typep = "int32_t"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_VOID: + if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { + error("voids allowed only inside union and program definitions with one argument"); + } + *typep = tok.str; + break; + case TOK_STRING: + case TOK_OPAQUE: + case TOK_CHAR: + case TOK_INT: + case TOK_FLOAT: + case TOK_DOUBLE: + case TOK_BOOL: + *typep = tok.str; + break; + default: + error("expected type specifier"); + } +} + +static void +unsigned_dec(char **typep) +{ + token tok; + + peek(&tok); + switch (tok.kind) { + case TOK_CHAR: + get_token(&tok); + *typep = "u_char"; + break; + case TOK_SHORT: + get_token(&tok); + *typep = "u_short"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_INT32: + get_token(&tok); + *typep = "u_int32_"; + (void) peekscan(TOK_INT, &tok); + break; + case TOK_INT: + get_token(&tok); + *typep = "u_int"; + break; + default: + *typep = "u_int"; + break; + } +} -- cgit v1.2.3