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