home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-B.05 / NETKIT-B / NetKit-B-0.05 / rpcgen.new / rpc_cout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-10  |  15.0 KB  |  733 lines

  1. /*
  2.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  3.  * unrestricted use provided that this legend is included on all tape
  4.  * media and as a part of the software program in whole or part.  Users
  5.  * may copy or modify Sun RPC without charge, but are not authorized
  6.  * to license or distribute it to anyone else except as part of a product or
  7.  * program developed by the user or with the express written consent of
  8.  * Sun Microsystems, Inc.
  9.  *
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  *
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  *
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  *
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  *
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30.  
  31. #ifndef lint
  32. static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI";
  33. #endif
  34.  
  35. /*
  36.  * rpc_cout.c, XDR routine outputter for the RPC protocol compiler 
  37.  */
  38. #include <stdio.h>
  39. #include <string.h>
  40. #include "rpc_parse.h"
  41. #include "rpc_util.h"
  42.  
  43. /*
  44.  * Emit the C-routine for the given definition 
  45.  */
  46. void
  47. emit(def)
  48.     definition *def;
  49. {
  50.     if (def->def_kind == DEF_CONST) {
  51.         return;
  52.     }
  53.     if (def->def_kind == DEF_PROGRAM) {
  54.         emit_program(def);
  55.         return;
  56.     }
  57.     if(def->def_kind == DEF_TYPEDEF)
  58.       {
  59.       /* now we need to handle declarations like 
  60.    struct typedef foo foo; 
  61.    since we dont want this to be expanded into 2 calls to xdr_foo */
  62.  
  63.      if(strcmp(def->def.ty.old_type,def->def_name)==0)
  64.       return;
  65.       };
  66.  
  67.     print_header(def);
  68.     switch (def->def_kind) {
  69.     case DEF_UNION:
  70.         emit_union(def);
  71.         break;
  72.     case DEF_ENUM:
  73.         emit_enum(def);
  74.         break;
  75.     case DEF_STRUCT:
  76.         emit_struct(def);
  77.         break;
  78.     case DEF_TYPEDEF:
  79.         emit_typedef(def);
  80.         break;
  81.     }
  82.     print_trailer();
  83. }
  84.  
  85. static
  86. findtype(def, type)
  87.     definition *def;
  88.     char *type;
  89. {
  90.  
  91.     if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
  92.         return (0);
  93.     } else {
  94.         return (streq(def->def_name, type));
  95.     }
  96. }
  97.  
  98. static
  99. undefined(type)
  100.     char *type;
  101. {
  102.     definition *def;
  103.  
  104.     def = (definition *) FINDVAL(defined, type, findtype);
  105.  
  106.     
  107.     return (def == NULL);
  108. }
  109.  
  110.  
  111. static
  112. print_generic_header(procname, pointerp )
  113.      char* procname;
  114.      int pointerp;
  115. {
  116.     f_print(fout, "\n");
  117.     f_print(fout, "bool_t\n");
  118.     if (Cflag) {
  119.        f_print(fout, "xdr_%s(", procname);
  120.        f_print(fout, "XDR *xdrs, ");
  121.        f_print(fout, "%s ", procname);
  122.        if( pointerp )
  123.          f_print(fout, "*");
  124.        f_print(fout, "objp)\n{\n\n");
  125.     } else {
  126.       f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
  127.       f_print(fout, "\tXDR *xdrs;\n");
  128.       f_print(fout, "\t%s ", procname);
  129.       if( pointerp )
  130.         f_print(fout, "*");
  131.       f_print(fout, "objp;\n{\n\n");
  132.     }
  133. }
  134.  
  135. static
  136. print_header(def)
  137.     definition *def;
  138. {
  139.  
  140.   decl_list *dl;
  141.   bas_type *ptr;
  142.   int i;
  143.  
  144.  
  145.   print_generic_header( def->def_name,
  146.                def->def_kind != DEF_TYPEDEF ||
  147.                !isvectordef(def->def.ty.old_type, def->def.ty.rel));
  148.  
  149.   /* Now add Inline support */
  150.  
  151.  
  152.   if(inline == 0 )
  153.     return;
  154.   /*May cause lint to complain. but  ... */
  155. f_print(fout, "\t register long *buf;\n\n");
  156.  
  157. }
  158.  
  159. static
  160. print_prog_header(plist)
  161.     proc_list *plist;
  162. {
  163.   print_generic_header( plist->args.argname, 1 );
  164. }
  165.  
  166. static
  167. print_trailer()
  168. {
  169.     f_print(fout, "\treturn (TRUE);\n");
  170.     f_print(fout, "}\n");
  171. }
  172.  
  173.  
  174. static
  175. print_ifopen(indent, name)
  176.     int indent;
  177.     char *name;
  178. {
  179.     tabify(fout, indent);
  180.     f_print(fout, " if (!xdr_%s(xdrs", name);
  181. }
  182.  
  183. static
  184. print_ifarg(arg)
  185.     char *arg;
  186. {
  187.     f_print(fout, ", %s", arg);
  188. }
  189.  
  190. static
  191. print_ifsizeof(prefix, type)
  192.     char *prefix;
  193.     char *type;
  194. {
  195.     if (streq(type, "bool")) {
  196.         f_print(fout, ", sizeof(bool_t), (xdrproc_t)xdr_bool");
  197.     } else {
  198.         f_print(fout, ", sizeof(");
  199.         if (undefined(type) && prefix) {
  200.             f_print(fout, "%s ", prefix);
  201.         }
  202.         f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type);
  203.     }
  204. }
  205.  
  206. static
  207. print_ifclose(indent)
  208.     int indent;
  209. {
  210.     f_print(fout, ")) {\n");
  211.     tabify(fout, indent);
  212.     f_print(fout, "\t return (FALSE);\n");
  213.     tabify(fout, indent);
  214.     f_print(fout, " }\n");
  215. }
  216.  
  217. static
  218. print_ifstat(indent, prefix, type, rel, amax, objname, name)
  219.     int indent;
  220.     char *prefix;
  221.     char *type;
  222.     relation rel;
  223.     char *amax;
  224.     char *objname;
  225.     char *name;
  226. {
  227.     char *alt = NULL;
  228.  
  229.     switch (rel) {
  230.     case REL_POINTER:
  231.         print_ifopen(indent, "pointer");
  232.         print_ifarg("(char **)");
  233.         f_print(fout, "%s", objname);
  234.         print_ifsizeof(prefix, type);
  235.         break;
  236.     case REL_VECTOR:
  237.         if (streq(type, "string")) {
  238.             alt = "string";
  239.         } else if (streq(type, "opaque")) {
  240.             alt = "opaque";
  241.         }
  242.         if (alt) {
  243.             print_ifopen(indent, alt);
  244.             print_ifarg(objname);
  245.         } else {
  246.             print_ifopen(indent, "vector");
  247.             print_ifarg("(char *)");
  248.             f_print(fout, "%s", objname);
  249.         }
  250.         print_ifarg(amax);
  251.         if (!alt) {
  252.             print_ifsizeof(prefix, type);
  253.         }
  254.         break;
  255.     case REL_ARRAY:
  256.         if (streq(type, "string")) {
  257.             alt = "string";
  258.         } else if (streq(type, "opaque")) {
  259.             alt = "bytes";
  260.         }
  261.         if (streq(type, "string")) {
  262.             print_ifopen(indent, alt);
  263.             print_ifarg(objname);
  264.         } else {
  265.             if (alt) {
  266.                 print_ifopen(indent, alt);
  267.             } else {
  268.                 print_ifopen(indent, "array");
  269.             }
  270.             print_ifarg("(char **)");
  271.             if (*objname == '&') {
  272.                 f_print(fout, "%s.%s_val, (u_int *)%s.%s_len",
  273.                     objname, name, objname, name);
  274.             } else {
  275.                 f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len",
  276.                     objname, name, objname, name);
  277.             }
  278.         }
  279.         print_ifarg(amax);
  280.         if (!alt) {
  281.             print_ifsizeof(prefix, type);
  282.         }
  283.         break;
  284.     case REL_ALIAS:
  285.         print_ifopen(indent, type);
  286.         print_ifarg(objname);
  287.         break;
  288.     }
  289.     print_ifclose(indent);
  290. }
  291.  
  292. /* ARGSUSED */
  293. static
  294. emit_enum(def)
  295.     definition *def;
  296. {
  297.     print_ifopen(1, "enum");
  298.     print_ifarg("(enum_t *)objp");
  299.     print_ifclose(1);
  300. }
  301.  
  302. static
  303. emit_program(def)
  304.     definition *def;
  305. {
  306.     decl_list *dl;
  307.     version_list *vlist;
  308.     proc_list *plist;
  309.     
  310.     for (vlist = def->def.pr.versions; vlist != NULL;vlist = vlist->next) 
  311.       for(plist = vlist->procs; plist != NULL; plist = plist->next) {
  312.           if (!newstyle || plist->arg_num < 2) 
  313.             continue; /* old style, or single argument */
  314.           print_prog_header(plist);
  315.           for (dl = plist->args.decls; dl != NULL; 
  316.                dl = dl->next) 
  317.               print_stat(1,&dl->decl);
  318.           print_trailer();
  319.       }
  320. }
  321.  
  322.  
  323. static
  324. emit_union(def)
  325.     definition *def;
  326. {
  327.   declaration *dflt;
  328.   case_list *cl;
  329.   declaration *cs;
  330.   char *object;
  331.   char *vecformat = "objp->%s_u.%s";
  332.   char *format = "&objp->%s_u.%s";
  333.  
  334.   print_stat(1,&def->def.un.enum_decl);
  335.   f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
  336.   for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
  337.  
  338.     f_print(fout, "\tcase %s:\n", cl->case_name);
  339.     if(cl->contflag == 1)    /* a continued case statement */
  340.       continue;
  341.     cs = &cl->case_decl;
  342.     if (!streq(cs->type, "void")) {
  343.       object = alloc(strlen(def->def_name) + strlen(format) +
  344.              strlen(cs->name) + 1);
  345.       if (isvectordef (cs->type, cs->rel)) {
  346.     s_print(object, vecformat, def->def_name, 
  347.         cs->name);
  348.       } else {
  349.     s_print(object, format, def->def_name, 
  350.         cs->name);
  351.       }
  352.       print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
  353.            object, cs->name);
  354.       free(object);
  355.     }
  356.     f_print(fout, "\t\tbreak;\n");
  357.   }
  358.   dflt = def->def.un.default_decl;
  359.   if (dflt != NULL) {
  360.     if (!streq(dflt->type, "void")) {
  361.       f_print(fout, "\tdefault:\n");
  362.       object = alloc(strlen(def->def_name) + strlen(format) +
  363.              strlen(dflt->name) + 1);
  364.       if (isvectordef (dflt->type, dflt->rel)) {
  365.     s_print(object, vecformat, def->def_name, 
  366.         dflt->name);
  367.       } else {
  368.     s_print(object, format, def->def_name, 
  369.         dflt->name);
  370.       }
  371.  
  372.       print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
  373.            dflt->array_max, object, dflt->name);
  374.       free(object);
  375.       f_print(fout, "\t\tbreak;\n");
  376.     }
  377. #ifdef linux
  378.     else {
  379.       f_print(fout, "\tdefault:\n");
  380.       f_print(fout, "\t\tbreak;\n");
  381.     }
  382. #endif
  383.   } else {
  384.     f_print(fout, "\tdefault:\n");
  385.     f_print(fout, "\t\treturn (FALSE);\n");
  386.   }
  387.  
  388.   f_print(fout, "\t}\n");
  389. }
  390.  
  391. static
  392. emit_struct(def)
  393.     definition *def;
  394. {
  395.     decl_list *dl;
  396.     int i,j,size,flag;
  397.     decl_list *cur,*psav;
  398.     bas_type *ptr;
  399.     char *sizestr,*plus;
  400.     char ptemp[256];
  401.     int can_inline;
  402.  
  403.  
  404.     if(inline  == 0)    {
  405.         for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 
  406.             print_stat(1,&dl->decl);
  407.     }
  408.     
  409.     else    {
  410.         
  411.         for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 
  412.             if(dl->decl.rel == REL_VECTOR){
  413.                 f_print(fout,"\t int i;\n");
  414.                 break;
  415.             }
  416.  
  417.         size=0;can_inline=0;
  418.         for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 
  419.             if((dl->decl.prefix == NULL) && ((ptr=find_type(dl->decl.type))!= NULL) &&          ((dl->decl.rel == REL_ALIAS)||(dl->decl.rel == REL_VECTOR))){
  420.                 
  421.                 if(dl->decl.rel == REL_ALIAS) 
  422.                     size+=ptr->length;
  423.                 else {
  424.                     can_inline=1;
  425.                     break; /* can be inlined */
  426.                 };
  427.             }
  428.             else {
  429.                 if(size >= inline){
  430.                     can_inline=1;
  431.                     break; /* can be inlined */
  432.                 }
  433.                 size=0;
  434.             }
  435.         if(size > inline)
  436.             can_inline=1;
  437.  
  438.         if(can_inline == 0){ /* can not inline, drop back to old mode */
  439.             for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 
  440.                 print_stat(1,&dl->decl);
  441.             return;
  442.         };
  443.  
  444.  
  445.             
  446.  
  447.         flag=PUT;
  448.         for(j=0; j<2; j++){
  449.  
  450.             if(flag == PUT)
  451.                 f_print(fout,"\n\t if (xdrs->x_op == XDR_ENCODE) {\n");
  452.             else
  453.                 f_print(fout,"\n \t return (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
  454.  
  455.  
  456.             i=0;
  457.             size=0;
  458.             sizestr=NULL;
  459.             for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */
  460.  
  461.                 /* now walk down the list and check for basic types */
  462.                 if((dl->decl.prefix == NULL) && ((ptr=find_type(dl->decl.type))!= NULL) &&          ((dl->decl.rel == REL_ALIAS)||(dl->decl.rel == REL_VECTOR))){
  463.                     if(i ==0 ) 
  464.                         cur=dl;
  465.                     i++;
  466.  
  467.                     if(dl->decl.rel == REL_ALIAS) 
  468.                         size+=ptr->length;
  469.                     else {
  470.                         /* this is required to handle arrays */
  471.             
  472.                         if(sizestr == NULL)
  473.                             plus = " ";
  474.                         else
  475.                             plus = "+";
  476.  
  477.                         if(ptr->length != 1)
  478.                             s_print(ptemp," %s %s * %d",plus,dl->decl.array_max,ptr->length);
  479.                         else
  480.                             s_print(ptemp," %s %s ",plus,dl->decl.array_max);
  481.  
  482.                         /*now concatenate to sizestr !!!! */
  483.                         if (sizestr == NULL)
  484.                             sizestr=strdup(ptemp);
  485.                         else{
  486.                             sizestr=realloc(sizestr,strlen(sizestr)+strlen(ptemp)+1);
  487.                             if(sizestr == NULL){
  488.  
  489.                                 f_print(stderr, "Fatal error : no memory \n");
  490.                                 crash();
  491.                             };
  492.                             sizestr=strcat(sizestr,ptemp); /*build up length of array */
  493.             
  494.                         }
  495.                     }
  496.  
  497.                 }
  498.                 else{
  499.                     if(i > 0 )
  500.                         if(sizestr == NULL && size < inline){    
  501.                             /* don't expand into inline code if size < inline */
  502.                             while(cur != dl){
  503.                                 print_stat(1,&cur->decl);
  504.                                 cur=cur->next;
  505.                             } 
  506.                         }
  507.                         else{
  508.  
  509.  
  510.  
  511.                             /* were already looking at a xdr_inlineable structure */
  512.                             if(sizestr == NULL)
  513.                                 f_print(fout,"\t buf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
  514.                                     size);
  515.                             else
  516.                                 if(size == 0)
  517.                                     f_print(fout,
  518.                                         "\t buf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
  519.                                         sizestr);
  520.                                 else
  521.                                     f_print(fout,
  522.                                         "\t buf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
  523.                                         size,sizestr);
  524.             
  525.                             f_print(fout,"\n\t   if (buf == NULL) {\n");
  526.  
  527.                             psav=cur;
  528.                             while(cur != dl){
  529.                                 print_stat(2,&cur->decl);
  530.                                 cur=cur->next;
  531.                             }
  532.  
  533.                             f_print(fout,"\n\t  }\n\t  else {\n");
  534.         
  535.                             cur=psav;
  536.                             while(cur != dl){
  537.                                 emit_inline(&cur->decl,flag);
  538.                                 cur=cur->next;
  539.                             }
  540.  
  541.                             f_print(fout,"\t  }\n");
  542.                         }
  543.                     size=0;i=0;sizestr=NULL;
  544.                     print_stat(1,&dl->decl);
  545.                 }
  546.         
  547.             }
  548.             if(i > 0 )
  549.                 if(sizestr == NULL && size < inline){
  550.                     /* don't expand into inline code if size < inline */
  551.                     while(cur != dl){
  552.                         print_stat(1,&cur->decl);
  553.                         cur=cur->next;
  554.                     } 
  555.                 }
  556.                 else{
  557.  
  558.                     /* were already looking at a xdr_inlineable structure */
  559.                     if(sizestr == NULL)
  560.                         f_print(fout,"\t\tbuf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
  561.                             size);
  562.                     else
  563.                         if(size == 0)
  564.                             f_print(fout,
  565.                                 "\t\tbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
  566.                                 sizestr);
  567.                         else
  568.                             f_print(fout,
  569.                                 "\t\tbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
  570.                                 size,sizestr);
  571.             
  572.                     f_print(fout,"\n\t\tif (buf == NULL) {\n");
  573.  
  574.                     psav=cur;
  575.                     while(cur != NULL){
  576.                         print_stat(2,&cur->decl);
  577.                         cur=cur->next;
  578.                     }
  579.                     f_print(fout,"\n\t  }\n\t  else {\n");
  580.         
  581.                     cur=psav;
  582.                     while(cur != dl){
  583.                         emit_inline(&cur->decl,flag);
  584.                         cur=cur->next;
  585.                     }
  586.  
  587.                     f_print(fout,"\t  }\n");
  588.  
  589.                 }
  590.             flag=GET;
  591.         }
  592.         f_print(fout,"\t return(TRUE);\n\t}\n\n");
  593.   
  594.         /* now take care of XDR_FREE case */
  595.  
  596.         for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 
  597.             print_stat(1,&dl->decl);
  598.     }    
  599. }
  600.  
  601.  
  602.  
  603.  
  604. static
  605. emit_typedef(def)
  606.     definition *def;
  607. {
  608.     char *prefix = def->def.ty.old_prefix;
  609.     char *type = def->def.ty.old_type;
  610.     char *amax = def->def.ty.array_max;
  611.     relation rel = def->def.ty.rel;
  612.  
  613.  
  614.       print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
  615. }
  616.  
  617. static
  618. print_stat(indent,dec)
  619.     declaration *dec;
  620.      int indent;
  621. {
  622.     char *prefix = dec->prefix;
  623.     char *type = dec->type;
  624.     char *amax = dec->array_max;
  625.     relation rel = dec->rel;
  626.     char name[256];
  627.  
  628.     if (isvectordef(type, rel)) {
  629.         s_print(name, "objp->%s", dec->name);
  630.     } else {
  631.         s_print(name, "&objp->%s", dec->name);
  632.     }
  633.     print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
  634. }
  635.  
  636.  
  637. char *upcase ();
  638.  
  639.  
  640. emit_inline(decl,flag)
  641. declaration *decl;
  642. int flag;
  643. {
  644.  
  645. /*check whether an array or not */
  646.  
  647. switch(decl->rel)
  648.   {
  649.  case  REL_ALIAS :
  650.   emit_single_in_line(decl,flag,REL_ALIAS);
  651.   break;
  652.  case REL_VECTOR :
  653.    f_print(fout,"\t\t{ register %s *genp; \n",decl->type);
  654.    f_print(fout,"\t\t  for ( i = 0,genp=objp->%s;\n \t\t\ti < %s; i++){\n\t\t",
  655.        decl->name,decl->array_max);
  656.   emit_single_in_line(decl,flag,REL_VECTOR);
  657.     f_print(fout,"\t\t   }\n\t\t };\n");
  658.  
  659.   }
  660. }
  661.  
  662. emit_single_in_line(decl,flag,rel)
  663. declaration *decl;
  664. int flag;
  665. relation rel;
  666. {
  667.     char *upp_case;
  668.     int freed=0;
  669.  
  670.  
  671.  
  672.     if(flag == PUT)
  673.         f_print(fout,"\t\t IXDR_PUT_");
  674.     else    
  675.         if(rel== REL_ALIAS)
  676.             f_print(fout,"\t\t objp->%s = IXDR_GET_",decl->name);
  677.         else
  678.             f_print(fout,"\t\t *genp++ = IXDR_GET_");
  679.  
  680.     upp_case=upcase(decl->type);
  681.  
  682.     /* hack  - XX */
  683.     if(strcmp(upp_case,"INT") == 0)
  684.     {
  685.         free(upp_case);
  686.         freed=1;
  687.         upp_case="LONG";
  688.     }
  689.  
  690.     if(strcmp(upp_case,"U_INT") == 0)
  691.     {
  692.         free(upp_case);
  693.         freed=1;
  694.         upp_case="U_LONG";
  695.     }
  696.  
  697.  
  698.     if(flag == PUT) 
  699.         if(rel== REL_ALIAS)
  700.             f_print(fout,"%s(buf,objp->%s);\n",upp_case,decl->name);
  701.         else
  702.             f_print(fout,"%s(buf,*genp++);\n",upp_case);
  703.  
  704.     else
  705.         f_print(fout,"%s(buf);\n",upp_case);
  706.     if(!freed)
  707.         free(upp_case);
  708.  
  709. }
  710.  
  711.  
  712. char * upcase(str)
  713. char *str;
  714. {
  715. char *ptr,*hptr;
  716.  
  717.  
  718. ptr =  (char * )malloc(strlen(str));
  719. if(ptr == (char * ) NULL)
  720.   {
  721.     f_print(stderr,"malloc failed \n");
  722.     exit(1);
  723.   };
  724.  
  725. hptr=ptr;
  726. while (*str != '\0')
  727.     *ptr++=toupper(*str++);
  728.  
  729. *ptr='\0';
  730. return(hptr);
  731.   
  732. }
  733.