|  | /* | 
|  | * From: @(#)rpc_cout.c 1.13 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_cout.c, XDR routine outputter for the RPC protocol compiler | 
|  | */ | 
|  | #include <ctype.h> | 
|  | #include <stdio.h> | 
|  | #include <string.h> | 
|  | #include "rpc_parse.h" | 
|  | #include "rpc_util.h" | 
|  | #include "proto.h" | 
|  |  | 
|  | static void emit_enum (definition * def); | 
|  | static void emit_program (const definition * def); | 
|  | static void emit_union (const definition * def); | 
|  | static void emit_struct (definition * def); | 
|  | static void emit_typedef (const definition * def); | 
|  | static void emit_inline (int indent, declaration * decl, int flag); | 
|  | static void emit_single_in_line (int indent, declaration *decl, int flag, | 
|  | relation rel); | 
|  | static int findtype (const definition * def, const char *type); | 
|  | static int undefined (const char *type); | 
|  | static void print_generic_header (const char *procname, int pointerp); | 
|  | static void print_ifopen (int indent, const char *name); | 
|  | static void print_ifarg (const char *arg); | 
|  | static void print_ifsizeof (int indent, const char *prefix, const char *type); | 
|  | static void print_ifclose (int indent); | 
|  | static void print_ifstat (int indent, const char *prefix, const char *type, | 
|  | relation rel, const char *amax, | 
|  | const char *objname, const char *name); | 
|  | static void print_stat (int indent, const declaration * dec); | 
|  | static void print_header (const definition * def); | 
|  | static void print_trailer (void); | 
|  | static char *upcase (const char *str); | 
|  |  | 
|  | /* | 
|  | * Emit the C-routine for the given definition | 
|  | */ | 
|  | void | 
|  | emit (definition * def) | 
|  | { | 
|  | if (def->def_kind == DEF_CONST) | 
|  | { | 
|  | return; | 
|  | } | 
|  | if (def->def_kind == DEF_PROGRAM) | 
|  | { | 
|  | emit_program (def); | 
|  | return; | 
|  | } | 
|  | if (def->def_kind == DEF_TYPEDEF) | 
|  | { | 
|  | /* now we need to handle declarations like | 
|  | struct typedef foo foo; | 
|  | since we don't want this to be expanded | 
|  | into 2 calls to xdr_foo */ | 
|  |  | 
|  | if (strcmp (def->def.ty.old_type, def->def_name) == 0) | 
|  | return; | 
|  | }; | 
|  |  | 
|  | print_header (def); | 
|  | switch (def->def_kind) | 
|  | { | 
|  | case DEF_UNION: | 
|  | emit_union (def); | 
|  | break; | 
|  | case DEF_ENUM: | 
|  | emit_enum (def); | 
|  | break; | 
|  | case DEF_STRUCT: | 
|  | emit_struct (def); | 
|  | break; | 
|  | case DEF_TYPEDEF: | 
|  | emit_typedef (def); | 
|  | break; | 
|  | default: | 
|  | /* can't happen */ | 
|  | break; | 
|  | } | 
|  | print_trailer (); | 
|  | } | 
|  |  | 
|  | static int | 
|  | findtype (const definition * def, const char *type) | 
|  | { | 
|  | if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) | 
|  | { | 
|  | return 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | return (streq (def->def_name, type)); | 
|  | } | 
|  | } | 
|  |  | 
|  | static int | 
|  | undefined (const char *type) | 
|  | { | 
|  | definition *def; | 
|  | def = (definition *) FINDVAL (defined, type, findtype); | 
|  | return (def == NULL); | 
|  | } | 
|  |  | 
|  |  | 
|  | static void | 
|  | print_generic_header (const char *procname, int pointerp) | 
|  | { | 
|  | f_print (fout, "\n"); | 
|  | f_print (fout, "bool_t\n"); | 
|  | if (Cflag) | 
|  | { | 
|  | f_print (fout, "xdr_%s (", procname); | 
|  | f_print (fout, "XDR *xdrs, "); | 
|  | f_print (fout, "%s ", procname); | 
|  | if (pointerp) | 
|  | f_print (fout, "*"); | 
|  | f_print (fout, "objp)\n{\n"); | 
|  | } | 
|  | else | 
|  | { | 
|  | f_print (fout, "xdr_%s (xdrs, objp)\n", procname); | 
|  | f_print (fout, "\tXDR *xdrs;\n"); | 
|  | f_print (fout, "\t%s ", procname); | 
|  | if (pointerp) | 
|  | f_print (fout, "*"); | 
|  | f_print (fout, "objp;\n{\n"); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void | 
|  | print_header (const definition * def) | 
|  | { | 
|  | print_generic_header (def->def_name, | 
|  | def->def_kind != DEF_TYPEDEF || | 
|  | !isvectordef (def->def.ty.old_type, | 
|  | def->def.ty.rel)); | 
|  |  | 
|  | /* Now add Inline support */ | 
|  |  | 
|  | if (inlineflag == 0) | 
|  | return; | 
|  | /*May cause lint to complain. but  ... */ | 
|  | f_print (fout, "\tregister int32_t *buf;\n\n"); | 
|  | } | 
|  |  | 
|  | static void | 
|  | print_prog_header (const proc_list * plist) | 
|  | { | 
|  | print_generic_header (plist->args.argname, 1); | 
|  | } | 
|  |  | 
|  | static void | 
|  | print_trailer (void) | 
|  | { | 
|  | f_print (fout, "\treturn TRUE;\n"); | 
|  | f_print (fout, "}\n"); | 
|  | } | 
|  |  | 
|  |  | 
|  | static void | 
|  | print_ifopen (int indent, const char *name) | 
|  | { | 
|  | tabify (fout, indent); | 
|  | f_print (fout, " if (!xdr_%s (xdrs", name); | 
|  | } | 
|  |  | 
|  | static void | 
|  | print_ifarg (const char *arg) | 
|  | { | 
|  | f_print (fout, ", %s", arg); | 
|  | } | 
|  |  | 
|  | static void | 
|  | print_ifsizeof (int indent, const char *prefix, const char *type) | 
|  | { | 
|  | if (indent) | 
|  | { | 
|  | fprintf (fout, ",\n"); | 
|  | tabify (fout, indent); | 
|  | } | 
|  | else | 
|  | fprintf (fout, ", "); | 
|  |  | 
|  | if (streq (type, "bool")) | 
|  | fprintf (fout, "sizeof (bool_t), (xdrproc_t) xdr_bool"); | 
|  | else | 
|  | { | 
|  | fprintf (fout, "sizeof ("); | 
|  | if (undefined (type) && prefix) | 
|  | { | 
|  | f_print (fout, "%s ", prefix); | 
|  | } | 
|  | fprintf (fout, "%s), (xdrproc_t) xdr_%s", type, type); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void | 
|  | print_ifclose (int indent) | 
|  | { | 
|  | f_print (fout, "))\n"); | 
|  | tabify (fout, indent); | 
|  | f_print (fout, "\t return FALSE;\n"); | 
|  | } | 
|  |  | 
|  | static void | 
|  | print_ifstat (int indent, const char *prefix, const char *type, relation rel, | 
|  | const char *amax, const char *objname, const char *name) | 
|  | { | 
|  | const char *alt = NULL; | 
|  |  | 
|  | switch (rel) | 
|  | { | 
|  | case REL_POINTER: | 
|  | print_ifopen (indent, "pointer"); | 
|  | print_ifarg ("(char **)"); | 
|  | f_print (fout, "%s", objname); | 
|  | print_ifsizeof (0, prefix, type); | 
|  | break; | 
|  | case REL_VECTOR: | 
|  | if (streq (type, "string")) | 
|  | { | 
|  | alt = "string"; | 
|  | } | 
|  | else if (streq (type, "opaque")) | 
|  | { | 
|  | alt = "opaque"; | 
|  | } | 
|  | if (alt) | 
|  | { | 
|  | print_ifopen (indent, alt); | 
|  | print_ifarg (objname); | 
|  | } | 
|  | else | 
|  | { | 
|  | print_ifopen (indent, "vector"); | 
|  | print_ifarg ("(char *)"); | 
|  | f_print (fout, "%s", objname); | 
|  | } | 
|  | print_ifarg (amax); | 
|  | if (!alt) | 
|  | { | 
|  | print_ifsizeof (indent + 1, prefix, type); | 
|  | } | 
|  | break; | 
|  | case REL_ARRAY: | 
|  | if (streq (type, "string")) | 
|  | { | 
|  | alt = "string"; | 
|  | } | 
|  | else if (streq (type, "opaque")) | 
|  | { | 
|  | alt = "bytes"; | 
|  | } | 
|  | if (streq (type, "string")) | 
|  | { | 
|  | print_ifopen (indent, alt); | 
|  | print_ifarg (objname); | 
|  | } | 
|  | else | 
|  | { | 
|  | if (alt) | 
|  | { | 
|  | print_ifopen (indent, alt); | 
|  | } | 
|  | else | 
|  | { | 
|  | print_ifopen (indent, "array"); | 
|  | } | 
|  | print_ifarg ("(char **)"); | 
|  | if (*objname == '&') | 
|  | { | 
|  | f_print (fout, "%s.%s_val, (u_int *) %s.%s_len", | 
|  | objname, name, objname, name); | 
|  | } | 
|  | else | 
|  | { | 
|  | f_print (fout, "&%s->%s_val, (u_int *) &%s->%s_len", | 
|  | objname, name, objname, name); | 
|  | } | 
|  | } | 
|  | print_ifarg (amax); | 
|  | if (!alt) | 
|  | { | 
|  | print_ifsizeof (indent + 1, prefix, type); | 
|  | } | 
|  | break; | 
|  | case REL_ALIAS: | 
|  | print_ifopen (indent, type); | 
|  | print_ifarg (objname); | 
|  | break; | 
|  | } | 
|  | print_ifclose (indent); | 
|  | } | 
|  |  | 
|  | static void | 
|  | emit_enum (definition * def) | 
|  | { | 
|  | (void) def; | 
|  |  | 
|  | print_ifopen (1, "enum"); | 
|  | print_ifarg ("(enum_t *) objp"); | 
|  | print_ifclose (1); | 
|  | } | 
|  |  | 
|  | static void | 
|  | emit_program (const definition * def) | 
|  | { | 
|  | decl_list *dl; | 
|  | version_list *vlist; | 
|  | proc_list *plist; | 
|  |  | 
|  | for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next) | 
|  | for (plist = vlist->procs; plist != NULL; plist = plist->next) | 
|  | { | 
|  | if (!newstyle || plist->arg_num < 2) | 
|  | continue;		/* old style, or single argument */ | 
|  | print_prog_header (plist); | 
|  | for (dl = plist->args.decls; dl != NULL; | 
|  | dl = dl->next) | 
|  | print_stat (1, &dl->decl); | 
|  | print_trailer (); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void | 
|  | emit_union (const definition * def) | 
|  | { | 
|  | declaration *dflt; | 
|  | case_list *cl; | 
|  | declaration *cs; | 
|  | char *object; | 
|  | const char *vecformat = "objp->%s_u.%s"; | 
|  | const char *format = "&objp->%s_u.%s"; | 
|  |  | 
|  | print_stat (1, &def->def.un.enum_decl); | 
|  | f_print (fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name); | 
|  | for (cl = def->def.un.cases; cl != NULL; cl = cl->next) | 
|  | { | 
|  |  | 
|  | f_print (fout, "\tcase %s:\n", cl->case_name); | 
|  | if (cl->contflag == 1)	/* a continued case statement */ | 
|  | continue; | 
|  | cs = &cl->case_decl; | 
|  | if (!streq (cs->type, "void")) | 
|  | { | 
|  | object = alloc (strlen (def->def_name) + strlen (format) + | 
|  | strlen (cs->name) + 1); | 
|  | if (isvectordef (cs->type, cs->rel)) | 
|  | { | 
|  | s_print (object, vecformat, def->def_name, | 
|  | cs->name); | 
|  | } | 
|  | else | 
|  | { | 
|  | s_print (object, format, def->def_name, | 
|  | cs->name); | 
|  | } | 
|  | print_ifstat (2, cs->prefix, cs->type, cs->rel, cs->array_max, | 
|  | object, cs->name); | 
|  | free (object); | 
|  | } | 
|  | f_print (fout, "\t\tbreak;\n"); | 
|  | } | 
|  | dflt = def->def.un.default_decl; | 
|  | if (dflt != NULL) | 
|  | { | 
|  | if (!streq (dflt->type, "void")) | 
|  | { | 
|  | f_print (fout, "\tdefault:\n"); | 
|  | object = alloc (strlen (def->def_name) + strlen (format) + | 
|  | strlen (dflt->name) + 1); | 
|  | if (isvectordef (dflt->type, dflt->rel)) | 
|  | { | 
|  | s_print (object, vecformat, def->def_name, | 
|  | dflt->name); | 
|  | } | 
|  | else | 
|  | { | 
|  | s_print (object, format, def->def_name, | 
|  | dflt->name); | 
|  | } | 
|  |  | 
|  | print_ifstat (2, dflt->prefix, dflt->type, dflt->rel, | 
|  | dflt->array_max, object, dflt->name); | 
|  | free (object); | 
|  | f_print (fout, "\t\tbreak;\n"); | 
|  | } | 
|  | else | 
|  | { | 
|  | f_print (fout, "\tdefault:\n"); | 
|  | f_print (fout, "\t\tbreak;\n"); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | f_print (fout, "\tdefault:\n"); | 
|  | f_print (fout, "\t\treturn FALSE;\n"); | 
|  | } | 
|  |  | 
|  | f_print (fout, "\t}\n"); | 
|  | } | 
|  |  | 
|  | static void | 
|  | inline_struct (definition *def, int flag) | 
|  | { | 
|  | decl_list *dl; | 
|  | int i, size; | 
|  | decl_list *cur = NULL; | 
|  | decl_list *psav; | 
|  | bas_type *ptr; | 
|  | char *sizestr; | 
|  | const char *plus; | 
|  | char ptemp[256]; | 
|  | int indent = 1; | 
|  |  | 
|  | if (flag == PUT) | 
|  | f_print (fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n"); | 
|  | else | 
|  | f_print (fout, | 
|  | "\t\treturn TRUE;\n\t} else if (xdrs->x_op == XDR_DECODE) {\n"); | 
|  |  | 
|  | i = 0; | 
|  | size = 0; | 
|  | sizestr = NULL; | 
|  | for (dl = def->def.st.decls; dl != NULL; dl = dl->next) | 
|  | {			/* xxx */ | 
|  | /* now walk down the list and check for basic types */ | 
|  | if ((dl->decl.prefix == NULL) && | 
|  | ((ptr = find_type (dl->decl.type)) != NULL) && | 
|  | ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) | 
|  | { | 
|  | if (i == 0) | 
|  | cur = dl; | 
|  | ++i; | 
|  |  | 
|  | if (dl->decl.rel == REL_ALIAS) | 
|  | size += ptr->length; | 
|  | else | 
|  | { | 
|  | /* this is required to handle arrays */ | 
|  | if (sizestr == NULL) | 
|  | plus = ""; | 
|  | else | 
|  | plus = "+ "; | 
|  |  | 
|  | if (ptr->length != 1) | 
|  | s_print (ptemp, " %s %s * %d", plus, dl->decl.array_max, | 
|  | ptr->length); | 
|  | else | 
|  | s_print (ptemp, " %s%s ", plus, dl->decl.array_max); | 
|  |  | 
|  | /*now concatenate to sizestr !!!! */ | 
|  | if (sizestr == NULL) | 
|  | sizestr = strdup (ptemp); | 
|  | else | 
|  | { | 
|  | sizestr = realloc (sizestr, strlen (sizestr) + | 
|  | strlen (ptemp) + 1); | 
|  | if (sizestr == NULL) | 
|  | { | 
|  | f_print (stderr, "Fatal error : no memory \n"); | 
|  | crash (); | 
|  | }; | 
|  | sizestr = strcat (sizestr, ptemp); | 
|  | /*build up length of array */ | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if (i > 0) | 
|  | { | 
|  | if (sizestr == NULL && size < inlineflag) | 
|  | { | 
|  | /* don't expand into inline code if size < inlineflag */ | 
|  | while (cur != dl) | 
|  | { | 
|  | print_stat (indent + 1, &cur->decl); | 
|  | cur = cur->next; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | /* were already looking at a xdr_inlineable structure */ | 
|  | tabify (fout, indent + 1); | 
|  | if (sizestr == NULL) | 
|  | f_print (fout, "buf = XDR_INLINE (xdrs, %d * BYTES_PER_XDR_UNIT);", size); | 
|  | else if (size == 0) | 
|  | f_print (fout, | 
|  | "buf = XDR_INLINE (xdrs, (%s) * BYTES_PER_XDR_UNIT);", | 
|  | sizestr); | 
|  | else | 
|  | f_print (fout, | 
|  | "buf = XDR_INLINE (xdrs, (%d + (%s)) * BYTES_PER_XDR_UNIT);", | 
|  | size, sizestr); | 
|  | f_print (fout, "\n"); | 
|  | tabify (fout, indent + 1); | 
|  | fprintf (fout, "if (buf == NULL) {\n"); | 
|  | psav = cur; | 
|  | while (cur != dl) | 
|  | { | 
|  | print_stat (indent + 2, &cur->decl); | 
|  | cur = cur->next; | 
|  | } | 
|  |  | 
|  | f_print (fout, "\n\t\t} else {\n"); | 
|  | cur = psav; | 
|  | while (cur != dl) | 
|  | { | 
|  | emit_inline (indent + 1, &cur->decl, flag); | 
|  | cur = cur->next; | 
|  | } | 
|  | tabify (fout, indent + 1); | 
|  | f_print (fout, "}\n"); | 
|  | } | 
|  | } | 
|  | size = 0; | 
|  | i = 0; | 
|  | free (sizestr); | 
|  | sizestr = NULL; | 
|  | print_stat (indent + 1, &dl->decl); | 
|  | } | 
|  | } | 
|  | if (i > 0) | 
|  | { | 
|  | if (sizestr == NULL && size < inlineflag) | 
|  | { | 
|  | /* don't expand into inline code if size < inlineflag */ | 
|  | while (cur != dl) | 
|  | { | 
|  | print_stat (indent + 1, &cur->decl); | 
|  | cur = cur->next; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | /* were already looking at a xdr_inlineable structure */ | 
|  | if (sizestr == NULL) | 
|  | f_print (fout, | 
|  | "\t\tbuf = XDR_INLINE (xdrs, %d * BYTES_PER_XDR_UNIT);", | 
|  | size); | 
|  | else if (size == 0) | 
|  | f_print (fout, | 
|  | "\t\tbuf = XDR_INLINE (xdrs, (%s) * BYTES_PER_XDR_UNIT);", | 
|  | sizestr); | 
|  | else | 
|  | f_print (fout, | 
|  | "\t\tbuf = XDR_INLINE (xdrs, (%d + %s)* BYTES_PER_XDR_UNIT);", | 
|  | size, sizestr); | 
|  | f_print (fout, "\n\t\tif (buf == NULL) {\n"); | 
|  | psav = cur; | 
|  | while (cur != NULL) | 
|  | { | 
|  | print_stat (indent + 2, &cur->decl); | 
|  | cur = cur->next; | 
|  | } | 
|  | f_print (fout, "\t\t} else {\n"); | 
|  |  | 
|  | cur = psav; | 
|  | while (cur != dl) | 
|  | { | 
|  | emit_inline (indent + 2, &cur->decl, flag); | 
|  | cur = cur->next; | 
|  | } | 
|  | f_print (fout, "\t\t}\n"); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* this may be const.  i haven't traced this one through yet. */ | 
|  |  | 
|  | static void | 
|  | emit_struct (definition * def) | 
|  | { | 
|  | decl_list *dl; | 
|  | int j, size, flag; | 
|  | bas_type *ptr; | 
|  | int can_inline; | 
|  |  | 
|  |  | 
|  | if (inlineflag == 0) | 
|  | { | 
|  | /* No xdr_inlining at all */ | 
|  | for (dl = def->def.st.decls; dl != NULL; dl = dl->next) | 
|  | print_stat (1, &dl->decl); | 
|  | return; | 
|  | } | 
|  |  | 
|  | for (dl = def->def.st.decls; dl != NULL; dl = dl->next) | 
|  | if (dl->decl.rel == REL_VECTOR) | 
|  | { | 
|  | f_print (fout, "\tint i;\n"); | 
|  | break; | 
|  | } | 
|  |  | 
|  | size = 0; | 
|  | can_inline = 0; | 
|  | /* | 
|  | * Make a first pass and see if inling is possible. | 
|  | */ | 
|  | for (dl = def->def.st.decls; dl != NULL; dl = dl->next) | 
|  | if ((dl->decl.prefix == NULL) && | 
|  | ((ptr = find_type (dl->decl.type)) != NULL) && | 
|  | ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) | 
|  | { | 
|  | if (dl->decl.rel == REL_ALIAS) | 
|  | size += ptr->length; | 
|  | else | 
|  | { | 
|  | can_inline = 1; | 
|  | break;		/* can be inlined */ | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if (size >= inlineflag) | 
|  | { | 
|  | can_inline = 1; | 
|  | break;		/* can be inlined */ | 
|  | } | 
|  | size = 0; | 
|  | } | 
|  | if (size > inlineflag) | 
|  | can_inline = 1; | 
|  |  | 
|  | if (can_inline == 0) | 
|  | {			/* can not inline, drop back to old mode */ | 
|  | for (dl = def->def.st.decls; dl != NULL; dl = dl->next) | 
|  | print_stat (1, &dl->decl); | 
|  | return; | 
|  | }; | 
|  |  | 
|  | flag = PUT; | 
|  | for (j = 0; j < 2; j++) | 
|  | { | 
|  | inline_struct (def, flag); | 
|  | if (flag == PUT) | 
|  | flag = GET; | 
|  | } | 
|  |  | 
|  | f_print (fout, "\t return TRUE;\n\t}\n\n"); | 
|  |  | 
|  | /* now take care of XDR_FREE case */ | 
|  |  | 
|  | for (dl = def->def.st.decls; dl != NULL; dl = dl->next) | 
|  | print_stat (1, &dl->decl); | 
|  | } | 
|  |  | 
|  | static void | 
|  | emit_typedef (const definition * def) | 
|  | { | 
|  | const char *prefix = def->def.ty.old_prefix; | 
|  | const char *type = def->def.ty.old_type; | 
|  | const char *amax = def->def.ty.array_max; | 
|  | relation rel = def->def.ty.rel; | 
|  |  | 
|  | print_ifstat (1, prefix, type, rel, amax, "objp", def->def_name); | 
|  | } | 
|  |  | 
|  | static void | 
|  | print_stat (int indent, const declaration * dec) | 
|  | { | 
|  | const char *prefix = dec->prefix; | 
|  | const char *type = dec->type; | 
|  | const char *amax = dec->array_max; | 
|  | relation rel = dec->rel; | 
|  | char name[256]; | 
|  |  | 
|  | if (isvectordef (type, rel)) | 
|  | { | 
|  | s_print (name, "objp->%s", dec->name); | 
|  | } | 
|  | else | 
|  | { | 
|  | s_print (name, "&objp->%s", dec->name); | 
|  | } | 
|  | print_ifstat (indent, prefix, type, rel, amax, name, dec->name); | 
|  | } | 
|  |  | 
|  |  | 
|  | static void | 
|  | emit_inline (int indent, declaration * decl, int flag) | 
|  | { | 
|  | switch (decl->rel) | 
|  | { | 
|  | case REL_ALIAS: | 
|  | emit_single_in_line (indent, decl, flag, REL_ALIAS); | 
|  | break; | 
|  | case REL_VECTOR: | 
|  | tabify (fout, indent); | 
|  | f_print (fout, "{\n"); | 
|  | tabify (fout, indent + 1); | 
|  | f_print (fout, "register %s *genp;\n\n", decl->type); | 
|  | tabify (fout, indent + 1); | 
|  | f_print (fout, | 
|  | "for (i = 0, genp = objp->%s;\n", decl->name); | 
|  | tabify (fout, indent + 2); | 
|  | f_print (fout, "i < %s; ++i) {\n", decl->array_max); | 
|  | emit_single_in_line (indent + 2, decl, flag, REL_VECTOR); | 
|  | tabify (fout, indent + 1); | 
|  | f_print (fout, "}\n"); | 
|  | tabify (fout, indent); | 
|  | f_print (fout, "}\n"); | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | /* ?... do nothing I guess */ | 
|  | } | 
|  | } | 
|  |  | 
|  | static void | 
|  | emit_single_in_line (int indent, declaration *decl, int flag, relation rel) | 
|  | { | 
|  | char *upp_case; | 
|  | int freed = 0; | 
|  |  | 
|  | tabify (fout, indent); | 
|  | if (flag == PUT) | 
|  | f_print (fout, "IXDR_PUT_"); | 
|  | else | 
|  | { | 
|  | if (rel == REL_ALIAS) | 
|  | f_print (fout, "objp->%s = IXDR_GET_", decl->name); | 
|  | else | 
|  | f_print (fout, "*genp++ = IXDR_GET_"); | 
|  | } | 
|  |  | 
|  | upp_case = upcase (decl->type); | 
|  |  | 
|  | /* hack  - XX */ | 
|  | if (!strcmp (upp_case, "INT")) | 
|  | { | 
|  | free (upp_case); | 
|  | freed = 1; | 
|  | /* Casting is safe since the `freed' flag is set.  */ | 
|  | upp_case = (char *) "LONG"; | 
|  | } | 
|  |  | 
|  | if (!strcmp (upp_case, "U_INT")) | 
|  | { | 
|  | free (upp_case); | 
|  | freed = 1; | 
|  | /* Casting is safe since the `freed' flag is set.  */ | 
|  | upp_case = (char *) "U_LONG"; | 
|  | } | 
|  |  | 
|  | if (flag == PUT) | 
|  | { | 
|  | if (rel == REL_ALIAS) | 
|  | f_print (fout, "%s(buf, objp->%s);\n", upp_case, decl->name); | 
|  | else | 
|  | f_print (fout, "%s(buf, *genp++);\n", upp_case); | 
|  | } | 
|  | else | 
|  | { | 
|  | f_print (fout, "%s(buf);\n", upp_case); | 
|  | } | 
|  |  | 
|  | if (!freed) | 
|  | free (upp_case); | 
|  | } | 
|  |  | 
|  |  | 
|  | static char * | 
|  | upcase (const char *str) | 
|  | { | 
|  | char *ptr, *hptr; | 
|  | ptr = malloc (strlen (str) + 1); | 
|  | if (ptr == NULL) | 
|  | { | 
|  | f_print (stderr, "malloc failed\n"); | 
|  | exit (1); | 
|  | } | 
|  | hptr = ptr; | 
|  | while (*str != '\0') | 
|  | *ptr++ = toupper (*str++); | 
|  |  | 
|  | *ptr = '\0'; | 
|  | return hptr; | 
|  | } |