diff options
Diffstat (limited to 'tools/rpcgen/rpc_hout.c')
-rw-r--r-- | tools/rpcgen/rpc_hout.c | 607 |
1 files changed, 607 insertions, 0 deletions
diff --git a/tools/rpcgen/rpc_hout.c b/tools/rpcgen/rpc_hout.c new file mode 100644 index 0000000..10f793d --- /dev/null +++ b/tools/rpcgen/rpc_hout.c @@ -0,0 +1,607 @@ +/* + * From: @(#)rpc_hout.c 1.12 89/02/22 + * + * Copyright (c) 2010, Oracle America, Inc. + * 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 the "Oracle America, 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. + */ + +/* + * rpc_hout.c, Header file outputter for the RPC protocol compiler + */ +#include <stdio.h> +#include <ctype.h> +#include "rpc_parse.h" +#include "rpc_util.h" +#include "proto.h" + +static void pconstdef (definition * def); +static void pargdef (definition * def); +static void pstructdef (definition * def); +static void puniondef (definition * def); +static void pdefine (const char *name, const char *num); +static int define_printed (proc_list * stop, version_list * start); +static void pprogramdef (definition * def); +static void parglist (proc_list * proc, const char *addargtype); +static void penumdef (definition * def); +static void ptypedef (definition * def); +static int undefined2 (const char *type, const char *stop); + +/* store away enough information to allow the XDR functions to be spat + out at the end of the file */ + +static void +storexdrfuncdecl (const char *name, int pointerp) +{ + xdrfunc * xdrptr; + + xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc)); + + xdrptr->name = (char *)name; + xdrptr->pointerp = pointerp; + xdrptr->next = NULL; + + if (xdrfunc_tail == NULL) + { + xdrfunc_head = xdrptr; + xdrfunc_tail = xdrptr; + } + else + { + xdrfunc_tail->next = xdrptr; + xdrfunc_tail = xdrptr; + } +} + +/* + * Print the C-version of an xdr definition + */ +void +print_datadef (definition *def) +{ + + if (def->def_kind == DEF_PROGRAM) /* handle data only */ + return; + + if (def->def_kind != DEF_CONST) + { + f_print (fout, "\n"); + } + switch (def->def_kind) + { + case DEF_STRUCT: + pstructdef (def); + break; + case DEF_UNION: + puniondef (def); + break; + case DEF_ENUM: + penumdef (def); + break; + case DEF_TYPEDEF: + ptypedef (def); + break; + case DEF_PROGRAM: + pprogramdef (def); + break; + case DEF_CONST: + pconstdef (def); + break; + } + if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) + { + storexdrfuncdecl(def->def_name, + def->def_kind != DEF_TYPEDEF || + !isvectordef(def->def.ty.old_type, + def->def.ty.rel)); + } +} + + +void +print_funcdef (definition *def) +{ + switch (def->def_kind) + { + case DEF_PROGRAM: + f_print (fout, "\n"); + pprogramdef (def); + break; + default: + break; + /* ?... shouldn't happen I guess */ + } +} + +void +print_xdr_func_def (char *name, int pointerp, int i) +{ + if (i == 2) + { + f_print (fout, "extern bool_t xdr_%s ();\n", name); + return; + } + else + f_print(fout, "extern bool_t xdr_%s (XDR *, %s%s);\n", name, + name, pointerp ? "*" : ""); +} + +static void +pconstdef (definition *def) +{ + pdefine (def->def_name, def->def.co); +} + +/* print out the definitions for the arguments of functions in the + header file + */ +static void +pargdef (definition * def) +{ + decl_list *l; + version_list *vers; + const char *name; + proc_list *plist; + + for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) + { + for (plist = vers->procs; plist != NULL; + plist = plist->next) + { + + if (!newstyle || plist->arg_num < 2) + { + continue; /* old style or single args */ + } + name = plist->args.argname; + f_print (fout, "struct %s {\n", name); + for (l = plist->args.decls; + l != NULL; l = l->next) + { + pdeclaration (name, &l->decl, 1, ";\n"); + } + f_print (fout, "};\n"); + f_print (fout, "typedef struct %s %s;\n", name, name); + storexdrfuncdecl (name, 1); + f_print (fout, "\n"); + } + } + +} + +static void +pstructdef (definition *def) +{ + decl_list *l; + const char *name = def->def_name; + + f_print (fout, "struct %s {\n", name); + for (l = def->def.st.decls; l != NULL; l = l->next) + { + pdeclaration (name, &l->decl, 1, ";\n"); + } + f_print (fout, "};\n"); + f_print (fout, "typedef struct %s %s;\n", name, name); +} + +static void +puniondef (definition *def) +{ + case_list *l; + const char *name = def->def_name; + declaration *decl; + + f_print (fout, "struct %s {\n", name); + decl = &def->def.un.enum_decl; + if (streq (decl->type, "bool")) + { + f_print (fout, "\tbool_t %s;\n", decl->name); + } + else + { + f_print (fout, "\t%s %s;\n", decl->type, decl->name); + } + f_print (fout, "\tunion {\n"); + for (l = def->def.un.cases; l != NULL; l = l->next) + { + if (l->contflag == 0) + pdeclaration (name, &l->case_decl, 2, ";\n"); + } + decl = def->def.un.default_decl; + if (decl && !streq (decl->type, "void")) + { + pdeclaration (name, decl, 2, ";\n"); + } + f_print (fout, "\t} %s_u;\n", name); + f_print (fout, "};\n"); + f_print (fout, "typedef struct %s %s;\n", name, name); +} + +static void +pdefine (const char *name, const char *num) +{ + f_print (fout, "#define %s %s\n", name, num); +} + +static int +define_printed (proc_list *stop, version_list *start) +{ + version_list *vers; + proc_list *proc; + + for (vers = start; vers != NULL; vers = vers->next) + { + for (proc = vers->procs; proc != NULL; proc = proc->next) + { + if (proc == stop) + { + return 0; + } + else if (streq (proc->proc_name, stop->proc_name)) + { + return 1; + } + } + } + abort (); + /* NOTREACHED */ +} + +static void +pfreeprocdef (const char *name, const char *vers, int mode) +{ + f_print (fout, "extern int "); + pvname (name, vers); + if (mode == 1) + f_print (fout,"_freeresult (SVCXPRT *, xdrproc_t, caddr_t);\n"); + else + f_print (fout,"_freeresult ();\n"); +} + +static void +pprogramdef (definition *def) +{ + version_list *vers; + proc_list *proc; + int i; + const char *ext; + + pargdef (def); + + pdefine (def->def_name, def->def.pr.prog_num); + for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) + { + if (tblflag) + { + f_print (fout, "extern struct rpcgen_table %s_%s_table[];\n", + locase (def->def_name), vers->vers_num); + f_print (fout, "extern %s_%s_nproc;\n", + locase (def->def_name), vers->vers_num); + } + pdefine (vers->vers_name, vers->vers_num); + + /* + * Print out 2 definitions, one for ANSI-C, another for + * old K & R C + */ + + if(!Cflag) + { + ext = "extern "; + for (proc = vers->procs; proc != NULL; + proc = proc->next) + { + if (!define_printed(proc, def->def.pr.versions)) + { + pdefine (proc->proc_name, proc->proc_num); + } + f_print (fout, "%s", ext); + pprocdef (proc, vers, NULL, 0, 2); + + if (mtflag) + { + f_print(fout, "%s", ext); + pprocdef (proc, vers, NULL, 1, 2); + } + } + pfreeprocdef (def->def_name, vers->vers_num, 2); + } + else + { + for (i = 1; i < 3; i++) + { + if (i == 1) + { + f_print (fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n"); + ext = "extern "; + } + else + { + f_print (fout, "\n#else /* K&R C */\n"); + ext = "extern "; + } + + for (proc = vers->procs; proc != NULL; proc = proc->next) + { + if (!define_printed(proc, def->def.pr.versions)) + { + pdefine(proc->proc_name, proc->proc_num); + } + f_print (fout, "%s", ext); + pprocdef (proc, vers, "CLIENT *", 0, i); + f_print (fout, "%s", ext); + pprocdef (proc, vers, "struct svc_req *", 1, i); + } + pfreeprocdef (def->def_name, vers->vers_num, i); + } + f_print (fout, "#endif /* K&R C */\n"); + } + } +} + +void +pprocdef (proc_list * proc, version_list * vp, + const char *addargtype, int server_p, int mode) +{ + if (mtflag) + {/* Print MT style stubs */ + if (server_p) + f_print (fout, "bool_t "); + else + f_print (fout, "enum clnt_stat "); + } + else + { + ptype (proc->res_prefix, proc->res_type, 1); + f_print (fout, "* "); + } + if (server_p) + pvname_svc (proc->proc_name, vp->vers_num); + else + pvname (proc->proc_name, vp->vers_num); + + /* + * mode 1 = ANSI-C, mode 2 = K&R C + */ + if (mode == 1) + parglist (proc, addargtype); + else + f_print (fout, "();\n"); +} + +/* print out argument list of procedure */ +static void +parglist (proc_list *proc, const char *addargtype) +{ + decl_list *dl; + + f_print(fout,"("); + if (proc->arg_num < 2 && newstyle && + streq (proc->args.decls->decl.type, "void")) + { + /* 0 argument in new style: do nothing */ + } + else + { + for (dl = proc->args.decls; dl != NULL; dl = dl->next) + { + ptype (dl->decl.prefix, dl->decl.type, 1); + if (!newstyle) + f_print (fout, "*"); /* old style passes by reference */ + + f_print (fout, ", "); + } + } + if (mtflag) + { + ptype(proc->res_prefix, proc->res_type, 1); + f_print(fout, "*, "); + } + + f_print (fout, "%s);\n", addargtype); +} + +static void +penumdef (definition *def) +{ + const char *name = def->def_name; + enumval_list *l; + const char *last = NULL; + int count = 0; + + f_print (fout, "enum %s {\n", name); + for (l = def->def.en.vals; l != NULL; l = l->next) + { + f_print (fout, "\t%s", l->name); + if (l->assignment) + { + f_print (fout, " = %s", l->assignment); + last = l->assignment; + count = 1; + } + else + { + if (last == NULL) + { + f_print (fout, " = %d", count++); + } + else + { + f_print (fout, " = %s + %d", last, count++); + } + } + f_print (fout, ",\n"); + } + f_print (fout, "};\n"); + f_print (fout, "typedef enum %s %s;\n", name, name); +} + +static void +ptypedef (definition *def) +{ + const char *name = def->def_name; + const char *old = def->def.ty.old_type; + char prefix[8]; /* enough to contain "struct ", including NUL */ + relation rel = def->def.ty.rel; + + if (!streq (name, old)) + { + if (streq (old, "string")) + { + old = "char"; + rel = REL_POINTER; + } + else if (streq (old, "opaque")) + { + old = "char"; + } + else if (streq (old, "bool")) + { + old = "bool_t"; + } + if (undefined2 (old, name) && def->def.ty.old_prefix) + { + s_print (prefix, "%s ", def->def.ty.old_prefix); + } + else + { + prefix[0] = 0; + } + f_print (fout, "typedef "); + switch (rel) + { + case REL_ARRAY: + f_print (fout, "struct {\n"); + f_print (fout, "\tu_int %s_len;\n", name); + f_print (fout, "\t%s%s *%s_val;\n", prefix, old, name); + f_print (fout, "} %s", name); + break; + case REL_POINTER: + f_print (fout, "%s%s *%s", prefix, old, name); + break; + case REL_VECTOR: + f_print (fout, "%s%s %s[%s]", prefix, old, name, + def->def.ty.array_max); + break; + case REL_ALIAS: + f_print (fout, "%s%s %s", prefix, old, name); + break; + } + f_print (fout, ";\n"); + } +} + +void +pdeclaration (const char *name, declaration * dec, int tab, + const char *separator) +{ + char buf[8]; /* enough to hold "struct ", include NUL */ + const char *prefix; + const char *type; + + if (streq (dec->type, "void")) + { + return; + } + tabify (fout, tab); + if (streq (dec->type, name) && !dec->prefix) + { + f_print (fout, "struct "); + } + if (streq (dec->type, "string")) + { + f_print (fout, "char *%s", dec->name); + } + else + { + prefix = ""; + if (streq (dec->type, "bool")) + { + type = "bool_t"; + } + else if (streq (dec->type, "opaque")) + { + type = "char"; + } + else + { + if (dec->prefix) + { + s_print (buf, "%s ", dec->prefix); + prefix = buf; + } + type = dec->type; + } + switch (dec->rel) + { + case REL_ALIAS: + f_print (fout, "%s%s %s", prefix, type, dec->name); + break; + case REL_VECTOR: + f_print (fout, "%s%s %s[%s]", prefix, type, dec->name, + dec->array_max); + break; + case REL_POINTER: + f_print (fout, "%s%s *%s", prefix, type, dec->name); + break; + case REL_ARRAY: + f_print (fout, "struct {\n"); + tabify (fout, tab); + f_print (fout, "\tu_int %s_len;\n", dec->name); + tabify (fout, tab); + f_print (fout, "\t%s%s *%s_val;\n", prefix, type, dec->name); + tabify (fout, tab); + f_print (fout, "} %s", dec->name); + break; + } + } + f_print (fout, "%s", separator); +} + +static int +undefined2 (const char *type, const char *stop) +{ + list *l; + definition *def; + + for (l = defined; l != NULL; l = l->next) + { + def = (definition *) l->val; + if (def->def_kind != DEF_PROGRAM) + { + if (streq (def->def_name, stop)) + { + return 1; + } + else if (streq (def->def_name, type)) + { + return 0; + } + } + } + return 1; +} |