Back to index

glibc  2.9
rpc_cout.c
Go to the documentation of this file.
00001 /*
00002  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
00003  * unrestricted use provided that this legend is included on all tape
00004  * media and as a part of the software program in whole or part.  Users
00005  * may copy or modify Sun RPC without charge, but are not authorized
00006  * to license or distribute it to anyone else except as part of a product or
00007  * program developed by the user or with the express written consent of
00008  * Sun Microsystems, Inc.
00009  *
00010  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
00011  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
00012  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
00013  *
00014  * Sun RPC is provided with no support and without any obligation on the
00015  * part of Sun Microsystems, Inc. to assist in its use, correction,
00016  * modification or enhancement.
00017  *
00018  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
00019  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
00020  * OR ANY PART THEREOF.
00021  *
00022  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
00023  * or profits or other special, indirect and consequential damages, even if
00024  * Sun has been advised of the possibility of such damages.
00025  *
00026  * Sun Microsystems, Inc.
00027  * 2550 Garcia Avenue
00028  * Mountain View, California  94043
00029  */
00030 
00031 /*
00032  * From: @(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI
00033  */
00034 
00035 /*
00036  * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
00037  */
00038 #include <ctype.h>
00039 #include <stdio.h>
00040 #include <string.h>
00041 #include "rpc_parse.h"
00042 #include "rpc_util.h"
00043 #include "proto.h"
00044 
00045 static void emit_enum (definition * def);
00046 static void emit_program (const definition * def);
00047 static void emit_union (const definition * def);
00048 static void emit_struct (definition * def);
00049 static void emit_typedef (const definition * def);
00050 static void emit_inline (int indent, declaration * decl, int flag);
00051 static void emit_single_in_line (int indent, declaration *decl, int flag,
00052                              relation rel);
00053 static int findtype (const definition * def, const char *type);
00054 static int undefined (const char *type);
00055 static void print_generic_header (const char *procname, int pointerp);
00056 static void print_ifopen (int indent, const char *name);
00057 static void print_ifarg (const char *arg);
00058 static void print_ifsizeof (int indent, const char *prefix, const char *type);
00059 static void print_ifclose (int indent);
00060 static void print_ifstat (int indent, const char *prefix, const char *type,
00061                        relation rel, const char *amax,
00062                        const char *objname, const char *name);
00063 static void print_stat (int indent, const declaration * dec);
00064 static void print_header (const definition * def);
00065 static void print_trailer (void);
00066 static char *upcase (const char *str);
00067 
00068 /*
00069  * Emit the C-routine for the given definition
00070  */
00071 void
00072 emit (definition * def)
00073 {
00074   if (def->def_kind == DEF_CONST)
00075     {
00076       return;
00077     }
00078   if (def->def_kind == DEF_PROGRAM)
00079     {
00080       emit_program (def);
00081       return;
00082     }
00083   if (def->def_kind == DEF_TYPEDEF)
00084     {
00085       /* now we need to handle declarations like
00086          struct typedef foo foo;
00087          since we don't want this to be expanded
00088          into 2 calls to xdr_foo */
00089 
00090       if (strcmp (def->def.ty.old_type, def->def_name) == 0)
00091        return;
00092     };
00093 
00094   print_header (def);
00095   switch (def->def_kind)
00096     {
00097     case DEF_UNION:
00098       emit_union (def);
00099       break;
00100     case DEF_ENUM:
00101       emit_enum (def);
00102       break;
00103     case DEF_STRUCT:
00104       emit_struct (def);
00105       break;
00106     case DEF_TYPEDEF:
00107       emit_typedef (def);
00108       break;
00109     default:
00110       /* can't happen */
00111       break;
00112     }
00113   print_trailer ();
00114 }
00115 
00116 static int
00117 findtype (const definition * def, const char *type)
00118 {
00119   if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST)
00120     {
00121       return 0;
00122     }
00123   else
00124     {
00125       return (streq (def->def_name, type));
00126     }
00127 }
00128 
00129 static int
00130 undefined (const char *type)
00131 {
00132   definition *def;
00133   def = (definition *) FINDVAL (defined, type, findtype);
00134   return (def == NULL);
00135 }
00136 
00137 
00138 static void
00139 print_generic_header (const char *procname, int pointerp)
00140 {
00141   f_print (fout, "\n");
00142   f_print (fout, "bool_t\n");
00143   if (Cflag)
00144     {
00145       f_print (fout, "xdr_%s (", procname);
00146       f_print (fout, "XDR *xdrs, ");
00147       f_print (fout, "%s ", procname);
00148       if (pointerp)
00149        f_print (fout, "*");
00150       f_print (fout, "objp)\n{\n");
00151     }
00152   else
00153     {
00154       f_print (fout, "xdr_%s (xdrs, objp)\n", procname);
00155       f_print (fout, "\tXDR *xdrs;\n");
00156       f_print (fout, "\t%s ", procname);
00157       if (pointerp)
00158        f_print (fout, "*");
00159       f_print (fout, "objp;\n{\n");
00160     }
00161 }
00162 
00163 static void
00164 print_header (const definition * def)
00165 {
00166   print_generic_header (def->def_name,
00167                      def->def_kind != DEF_TYPEDEF ||
00168                      !isvectordef (def->def.ty.old_type,
00169                                   def->def.ty.rel));
00170 
00171   /* Now add Inline support */
00172 
00173   if (inlineflag == 0)
00174     return;
00175   /*May cause lint to complain. but  ... */
00176   f_print (fout, "\tregister int32_t *buf;\n\n");
00177 }
00178 
00179 static void
00180 print_prog_header (const proc_list * plist)
00181 {
00182   print_generic_header (plist->args.argname, 1);
00183 }
00184 
00185 static void
00186 print_trailer (void)
00187 {
00188   f_print (fout, "\treturn TRUE;\n");
00189   f_print (fout, "}\n");
00190 }
00191 
00192 
00193 static void
00194 print_ifopen (int indent, const char *name)
00195 {
00196   tabify (fout, indent);
00197   f_print (fout, " if (!xdr_%s (xdrs", name);
00198 }
00199 
00200 static void
00201 print_ifarg (const char *arg)
00202 {
00203   f_print (fout, ", %s", arg);
00204 }
00205 
00206 static void
00207 print_ifsizeof (int indent, const char *prefix, const char *type)
00208 {
00209   if (indent)
00210     {
00211       fprintf (fout, ",\n");
00212       tabify (fout, indent);
00213     }
00214   else
00215     fprintf (fout, ", ");
00216 
00217   if (streq (type, "bool"))
00218     fprintf (fout, "sizeof (bool_t), (xdrproc_t) xdr_bool");
00219   else
00220     {
00221       fprintf (fout, "sizeof (");
00222       if (undefined (type) && prefix)
00223        {
00224          f_print (fout, "%s ", prefix);
00225        }
00226       fprintf (fout, "%s), (xdrproc_t) xdr_%s", type, type);
00227     }
00228 }
00229 
00230 static void
00231 print_ifclose (int indent)
00232 {
00233   f_print (fout, "))\n");
00234   tabify (fout, indent);
00235   f_print (fout, "\t return FALSE;\n");
00236 }
00237 
00238 static void
00239 print_ifstat (int indent, const char *prefix, const char *type, relation rel,
00240              const char *amax, const char *objname, const char *name)
00241 {
00242   const char *alt = NULL;
00243 
00244   switch (rel)
00245     {
00246     case REL_POINTER:
00247       print_ifopen (indent, "pointer");
00248       print_ifarg ("(char **)");
00249       f_print (fout, "%s", objname);
00250       print_ifsizeof (0, prefix, type);
00251       break;
00252     case REL_VECTOR:
00253       if (streq (type, "string"))
00254        {
00255          alt = "string";
00256        }
00257       else if (streq (type, "opaque"))
00258        {
00259          alt = "opaque";
00260        }
00261       if (alt)
00262        {
00263          print_ifopen (indent, alt);
00264          print_ifarg (objname);
00265        }
00266       else
00267        {
00268          print_ifopen (indent, "vector");
00269          print_ifarg ("(char *)");
00270          f_print (fout, "%s", objname);
00271        }
00272       print_ifarg (amax);
00273       if (!alt)
00274        {
00275          print_ifsizeof (indent + 1, prefix, type);
00276        }
00277       break;
00278     case REL_ARRAY:
00279       if (streq (type, "string"))
00280        {
00281          alt = "string";
00282        }
00283       else if (streq (type, "opaque"))
00284        {
00285          alt = "bytes";
00286        }
00287       if (streq (type, "string"))
00288        {
00289          print_ifopen (indent, alt);
00290          print_ifarg (objname);
00291        }
00292       else
00293        {
00294          if (alt)
00295            {
00296              print_ifopen (indent, alt);
00297            }
00298          else
00299            {
00300              print_ifopen (indent, "array");
00301            }
00302          print_ifarg ("(char **)");
00303          if (*objname == '&')
00304            {
00305              f_print (fout, "%s.%s_val, (u_int *) %s.%s_len",
00306                      objname, name, objname, name);
00307            }
00308          else
00309            {
00310              f_print (fout, "&%s->%s_val, (u_int *) &%s->%s_len",
00311                      objname, name, objname, name);
00312            }
00313        }
00314       print_ifarg (amax);
00315       if (!alt)
00316        {
00317          print_ifsizeof (indent + 1, prefix, type);
00318        }
00319       break;
00320     case REL_ALIAS:
00321       print_ifopen (indent, type);
00322       print_ifarg (objname);
00323       break;
00324     }
00325   print_ifclose (indent);
00326 }
00327 
00328 static void
00329 emit_enum (definition * def)
00330 {
00331   (void) def;
00332 
00333   print_ifopen (1, "enum");
00334   print_ifarg ("(enum_t *) objp");
00335   print_ifclose (1);
00336 }
00337 
00338 static void
00339 emit_program (const definition * def)
00340 {
00341   decl_list *dl;
00342   version_list *vlist;
00343   proc_list *plist;
00344 
00345   for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next)
00346     for (plist = vlist->procs; plist != NULL; plist = plist->next)
00347       {
00348        if (!newstyle || plist->arg_num < 2)
00349          continue;          /* old style, or single argument */
00350        print_prog_header (plist);
00351        for (dl = plist->args.decls; dl != NULL;
00352             dl = dl->next)
00353          print_stat (1, &dl->decl);
00354        print_trailer ();
00355       }
00356 }
00357 
00358 static void
00359 emit_union (const definition * def)
00360 {
00361   declaration *dflt;
00362   case_list *cl;
00363   declaration *cs;
00364   char *object;
00365   const char *vecformat = "objp->%s_u.%s";
00366   const char *format = "&objp->%s_u.%s";
00367 
00368   print_stat (1, &def->def.un.enum_decl);
00369   f_print (fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
00370   for (cl = def->def.un.cases; cl != NULL; cl = cl->next)
00371     {
00372 
00373       f_print (fout, "\tcase %s:\n", cl->case_name);
00374       if (cl->contflag == 1)       /* a continued case statement */
00375        continue;
00376       cs = &cl->case_decl;
00377       if (!streq (cs->type, "void"))
00378        {
00379          object = alloc (strlen (def->def_name) + strlen (format) +
00380                        strlen (cs->name) + 1);
00381          if (isvectordef (cs->type, cs->rel))
00382            {
00383              s_print (object, vecformat, def->def_name,
00384                      cs->name);
00385            }
00386          else
00387            {
00388              s_print (object, format, def->def_name,
00389                      cs->name);
00390            }
00391          print_ifstat (2, cs->prefix, cs->type, cs->rel, cs->array_max,
00392                      object, cs->name);
00393          free (object);
00394        }
00395       f_print (fout, "\t\tbreak;\n");
00396     }
00397   dflt = def->def.un.default_decl;
00398   if (dflt != NULL)
00399     {
00400       if (!streq (dflt->type, "void"))
00401        {
00402          f_print (fout, "\tdefault:\n");
00403          object = alloc (strlen (def->def_name) + strlen (format) +
00404                        strlen (dflt->name) + 1);
00405          if (isvectordef (dflt->type, dflt->rel))
00406            {
00407              s_print (object, vecformat, def->def_name,
00408                      dflt->name);
00409            }
00410          else
00411            {
00412              s_print (object, format, def->def_name,
00413                      dflt->name);
00414            }
00415 
00416          print_ifstat (2, dflt->prefix, dflt->type, dflt->rel,
00417                      dflt->array_max, object, dflt->name);
00418          free (object);
00419          f_print (fout, "\t\tbreak;\n");
00420        }
00421 #ifdef __GNU_LIBRARY__
00422       else
00423        {
00424          f_print (fout, "\tdefault:\n");
00425          f_print (fout, "\t\tbreak;\n");
00426        }
00427 #endif
00428     }
00429   else
00430     {
00431       f_print (fout, "\tdefault:\n");
00432       f_print (fout, "\t\treturn FALSE;\n");
00433     }
00434 
00435   f_print (fout, "\t}\n");
00436 }
00437 
00438 static void
00439 inline_struct (definition *def, int flag)
00440 {
00441   decl_list *dl;
00442   int i, size;
00443   decl_list *cur = NULL;
00444   decl_list *psav;
00445   bas_type *ptr;
00446   char *sizestr;
00447   const char *plus;
00448   char ptemp[256];
00449   int indent = 1;
00450 
00451   if (flag == PUT)
00452     f_print (fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n");
00453   else
00454     f_print (fout,
00455             "\t\treturn TRUE;\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
00456 
00457   i = 0;
00458   size = 0;
00459   sizestr = NULL;
00460   for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
00461     {                /* xxx */
00462       /* now walk down the list and check for basic types */
00463       if ((dl->decl.prefix == NULL) &&
00464          ((ptr = find_type (dl->decl.type)) != NULL) &&
00465          ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR)))
00466        {
00467          if (i == 0)
00468            cur = dl;
00469          ++i;
00470 
00471          if (dl->decl.rel == REL_ALIAS)
00472            size += ptr->length;
00473          else
00474            {
00475              /* this is required to handle arrays */
00476              if (sizestr == NULL)
00477               plus = "";
00478              else
00479               plus = "+ ";
00480 
00481              if (ptr->length != 1)
00482               s_print (ptemp, " %s %s * %d", plus, dl->decl.array_max,
00483                       ptr->length);
00484              else
00485               s_print (ptemp, " %s%s ", plus, dl->decl.array_max);
00486 
00487              /*now concatenate to sizestr !!!! */
00488              if (sizestr == NULL)
00489               sizestr = strdup (ptemp);
00490              else
00491               {
00492                 sizestr = realloc (sizestr, strlen (sizestr) +
00493                                  strlen (ptemp) + 1);
00494                 if (sizestr == NULL)
00495                   {
00496                     f_print (stderr, "Fatal error : no memory \n");
00497                     crash ();
00498                   };
00499                 sizestr = strcat (sizestr, ptemp);
00500                 /*build up length of array */
00501               }
00502            }
00503        }
00504       else
00505        {
00506          if (i > 0)
00507            {
00508              if (sizestr == NULL && size < inlineflag)
00509               {
00510                 /* don't expand into inline code if size < inlineflag */
00511                 while (cur != dl)
00512                   {
00513                     print_stat (indent + 1, &cur->decl);
00514                     cur = cur->next;
00515                   }
00516               }
00517              else
00518               {
00519                 /* were already looking at a xdr_inlineable structure */
00520                 tabify (fout, indent + 1);
00521                 if (sizestr == NULL)
00522                   f_print (fout, "buf = XDR_INLINE (xdrs, %d * BYTES_PER_XDR_UNIT);", size);
00523                 else if (size == 0)
00524                   f_print (fout,
00525                           "buf = XDR_INLINE (xdrs, (%s) * BYTES_PER_XDR_UNIT);",
00526                           sizestr);
00527                 else
00528                   f_print (fout,
00529                           "buf = XDR_INLINE (xdrs, (%d + (%s)) * BYTES_PER_XDR_UNIT);",
00530                           size, sizestr);
00531                 f_print (fout, "\n");
00532                 tabify (fout, indent + 1);
00533                 fprintf (fout, "if (buf == NULL) {\n");
00534                 psav = cur;
00535                 while (cur != dl)
00536                   {
00537                     print_stat (indent + 2, &cur->decl);
00538                     cur = cur->next;
00539                   }
00540 
00541                 f_print (fout, "\n\t\t} else {\n");
00542                 cur = psav;
00543                 while (cur != dl)
00544                   {
00545                     emit_inline (indent + 1, &cur->decl, flag);
00546                     cur = cur->next;
00547                   }
00548                 tabify (fout, indent + 1);
00549                 f_print (fout, "}\n");
00550               }
00551            }
00552          size = 0;
00553          i = 0;
00554          free (sizestr);
00555          sizestr = NULL;
00556          print_stat (indent + 1, &dl->decl);
00557        }
00558     }
00559   if (i > 0)
00560     {
00561       if (sizestr == NULL && size < inlineflag)
00562        {
00563          /* don't expand into inline code if size < inlineflag */
00564          while (cur != dl)
00565            {
00566              print_stat (indent + 1, &cur->decl);
00567              cur = cur->next;
00568            }
00569        }
00570       else
00571        {
00572          /* were already looking at a xdr_inlineable structure */
00573          if (sizestr == NULL)
00574            f_print (fout,
00575                    "\t\tbuf = XDR_INLINE (xdrs, %d * BYTES_PER_XDR_UNIT);",
00576                    size);
00577          else if (size == 0)
00578            f_print (fout,
00579                    "\t\tbuf = XDR_INLINE (xdrs, (%s) * BYTES_PER_XDR_UNIT);",
00580                    sizestr);
00581          else
00582            f_print (fout,
00583                    "\t\tbuf = XDR_INLINE (xdrs, (%d + %s)* BYTES_PER_XDR_UNIT);",
00584                    size, sizestr);
00585          f_print (fout, "\n\t\tif (buf == NULL) {\n");
00586          psav = cur;
00587          while (cur != NULL)
00588            {
00589              print_stat (indent + 2, &cur->decl);
00590              cur = cur->next;
00591            }
00592          f_print (fout, "\t\t} else {\n");
00593 
00594          cur = psav;
00595          while (cur != dl)
00596            {
00597              emit_inline (indent + 2, &cur->decl, flag);
00598              cur = cur->next;
00599            }
00600          f_print (fout, "\t\t}\n");
00601        }
00602     }
00603 }
00604 
00605 /* this may be const.  i haven't traced this one through yet. */
00606 
00607 static void
00608 emit_struct (definition * def)
00609 {
00610   decl_list *dl;
00611   int j, size, flag;
00612   bas_type *ptr;
00613   int can_inline;
00614 
00615 
00616   if (inlineflag == 0)
00617     {
00618       /* No xdr_inlining at all */
00619       for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
00620        print_stat (1, &dl->decl);
00621       return;
00622     }
00623 
00624   for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
00625     if (dl->decl.rel == REL_VECTOR)
00626       {
00627        f_print (fout, "\tint i;\n");
00628        break;
00629       }
00630 
00631   size = 0;
00632   can_inline = 0;
00633   /*
00634    * Make a first pass and see if inling is possible.
00635    */
00636   for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
00637     if ((dl->decl.prefix == NULL) &&
00638        ((ptr = find_type (dl->decl.type)) != NULL) &&
00639        ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR)))
00640       {
00641        if (dl->decl.rel == REL_ALIAS)
00642          size += ptr->length;
00643        else
00644          {
00645            can_inline = 1;
00646            break;           /* can be inlined */
00647          }
00648       }
00649     else
00650       {
00651        if (size >= inlineflag)
00652          {
00653            can_inline = 1;
00654            break;           /* can be inlined */
00655          }
00656        size = 0;
00657       }
00658   if (size > inlineflag)
00659     can_inline = 1;
00660 
00661   if (can_inline == 0)
00662     {                /* can not inline, drop back to old mode */
00663       for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
00664        print_stat (1, &dl->decl);
00665       return;
00666     };
00667 
00668   flag = PUT;
00669   for (j = 0; j < 2; j++)
00670     {
00671       inline_struct (def, flag);
00672       if (flag == PUT)
00673        flag = GET;
00674     }
00675 
00676   f_print (fout, "\t return TRUE;\n\t}\n\n");
00677 
00678   /* now take care of XDR_FREE case */
00679 
00680   for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
00681     print_stat (1, &dl->decl);
00682 }
00683 
00684 static void
00685 emit_typedef (const definition * def)
00686 {
00687   const char *prefix = def->def.ty.old_prefix;
00688   const char *type = def->def.ty.old_type;
00689   const char *amax = def->def.ty.array_max;
00690   relation rel = def->def.ty.rel;
00691 
00692   print_ifstat (1, prefix, type, rel, amax, "objp", def->def_name);
00693 }
00694 
00695 static void
00696 print_stat (int indent, const declaration * dec)
00697 {
00698   const char *prefix = dec->prefix;
00699   const char *type = dec->type;
00700   const char *amax = dec->array_max;
00701   relation rel = dec->rel;
00702   char name[256];
00703 
00704   if (isvectordef (type, rel))
00705     {
00706       s_print (name, "objp->%s", dec->name);
00707     }
00708   else
00709     {
00710       s_print (name, "&objp->%s", dec->name);
00711     }
00712   print_ifstat (indent, prefix, type, rel, amax, name, dec->name);
00713 }
00714 
00715 
00716 static void
00717 emit_inline (int indent, declaration * decl, int flag)
00718 {
00719   switch (decl->rel)
00720     {
00721     case REL_ALIAS:
00722       emit_single_in_line (indent, decl, flag, REL_ALIAS);
00723       break;
00724     case REL_VECTOR:
00725       tabify (fout, indent);
00726       f_print (fout, "{\n");
00727       tabify (fout, indent + 1);
00728       f_print (fout, "register %s *genp;\n\n", decl->type);
00729       tabify (fout, indent + 1);
00730       f_print (fout,
00731               "for (i = 0, genp = objp->%s;\n", decl->name);
00732       tabify (fout, indent + 2);
00733       f_print (fout, "i < %s; ++i) {\n", decl->array_max);
00734       emit_single_in_line (indent + 2, decl, flag, REL_VECTOR);
00735       tabify (fout, indent + 1);
00736       f_print (fout, "}\n");
00737       tabify (fout, indent);
00738       f_print (fout, "}\n");
00739       break;
00740     default:
00741       break;
00742       /* ?... do nothing I guess */
00743     }
00744 }
00745 
00746 static void
00747 emit_single_in_line (int indent, declaration *decl, int flag, relation rel)
00748 {
00749   char *upp_case;
00750   int freed = 0;
00751 
00752   tabify (fout, indent);
00753   if (flag == PUT)
00754     f_print (fout, "IXDR_PUT_");
00755   else
00756     {
00757       if (rel == REL_ALIAS)
00758        f_print (fout, "objp->%s = IXDR_GET_", decl->name);
00759       else
00760        f_print (fout, "*genp++ = IXDR_GET_");
00761     }
00762 
00763   upp_case = upcase (decl->type);
00764 
00765   /* hack  - XX */
00766   if (!strcmp (upp_case, "INT"))
00767     {
00768       free (upp_case);
00769       freed = 1;
00770       /* Casting is safe since the `freed' flag is set.  */
00771       upp_case = (char *) "LONG";
00772     }
00773 
00774   if (!strcmp (upp_case, "U_INT"))
00775     {
00776       free (upp_case);
00777       freed = 1;
00778       /* Casting is safe since the `freed' flag is set.  */
00779       upp_case = (char *) "U_LONG";
00780     }
00781 
00782   if (flag == PUT)
00783     {
00784       if (rel == REL_ALIAS)
00785        f_print (fout, "%s(buf, objp->%s);\n", upp_case, decl->name);
00786       else
00787        f_print (fout, "%s(buf, *genp++);\n", upp_case);
00788     }
00789   else
00790     {
00791       f_print (fout, "%s(buf);\n", upp_case);
00792     }
00793 
00794   if (!freed)
00795     free (upp_case);
00796 }
00797 
00798 
00799 static char *
00800 upcase (const char *str)
00801 {
00802   char *ptr, *hptr;
00803   ptr = malloc (strlen (str) + 1);
00804   if (ptr == NULL)
00805     {
00806       f_print (stderr, "malloc failed\n");
00807       exit (1);
00808     }
00809   hptr = ptr;
00810   while (*str != '\0')
00811     *ptr++ = toupper (*str++);
00812 
00813   *ptr = '\0';
00814   return hptr;
00815 }