Home | History | Annotate | Line # | Download | only in rpcgen
      1 /*	$NetBSD: rpc_cout.c,v 1.39 2023/08/07 21:12:02 tnn 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 #if HAVE_NBTOOL_CONFIG_H
     33 #include "nbtool_config.h"
     34 #endif
     35 
     36 #include <sys/cdefs.h>
     37 #if defined(__RCSID) && !defined(lint)
     38 #if 0
     39 static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI";
     40 #else
     41 __RCSID("$NetBSD: rpc_cout.c,v 1.39 2023/08/07 21:12:02 tnn Exp $");
     42 #endif
     43 #endif
     44 
     45 /*
     46  * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
     47  */
     48 #include <ctype.h>
     49 #include <err.h>
     50 #include <stdio.h>
     51 #include <stdlib.h>
     52 #include <string.h>
     53 #include "rpc_scan.h"
     54 #include "rpc_parse.h"
     55 #include "rpc_util.h"
     56 
     57 static int findtype(definition *, const char *);
     58 static int undefined(const char *);
     59 static void print_generic_header(const char *, int);
     60 static void print_header(definition *);
     61 static void print_prog_header(proc_list *);
     62 static void print_trailer(void);
     63 static void print_ifopen(int, const char *);
     64 static void print_ifarg(const char *);
     65 static void print_ifsizeof(const char *, const char *);
     66 static void print_ifclose(int);
     67 static void print_ifstat(int, const char *, const char *, relation,
     68     const char *, const char *, const char *);
     69 static void emit_enum(definition *);
     70 static void emit_program(definition *);
     71 static void emit_union(definition *);
     72 static void emit_struct(definition *);
     73 static void emit_typedef(definition *);
     74 static void print_stat(int, declaration *);
     75 
     76 /*
     77  * Emit the C-routine for the given definition
     78  */
     79 void
     80 emit(definition *def)
     81 {
     82 	if (def->def_kind == DEF_CONST) {
     83 		return;
     84 	}
     85 	if (def->def_kind == DEF_PROGRAM) {
     86 		emit_program(def);
     87 		return;
     88 	}
     89 	if (def->def_kind == DEF_TYPEDEF) {
     90 		/* now we need to handle declarations like struct typedef foo
     91 		 * foo; since we dont want this to be expanded into 2 calls to
     92 		 * xdr_foo */
     93 
     94 		if (strcmp(def->def.ty.old_type, def->def_name) == 0)
     95 			return;
     96 	};
     97 
     98 	print_header(def);
     99 
    100 	switch (def->def_kind) {
    101 	case DEF_UNION:
    102 		emit_union(def);
    103 		break;
    104 	case DEF_ENUM:
    105 		emit_enum(def);
    106 		break;
    107 	case DEF_STRUCT:
    108 		emit_struct(def);
    109 		break;
    110 	case DEF_TYPEDEF:
    111 		emit_typedef(def);
    112 		break;
    113 	case DEF_PROGRAM:
    114 	case DEF_CONST:
    115 		errx(1, "Internal error at %s:%d: Case %d not handled",
    116 		    __FILE__, __LINE__, def->def_kind);
    117 		break;
    118 	}
    119 	print_trailer();
    120 }
    121 
    122 static int
    123 findtype(definition *def, const char *type)
    124 {
    125 
    126 	if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
    127 		return (0);
    128 	} else {
    129 		return (streq(def->def_name, type));
    130 	}
    131 }
    132 
    133 static int
    134 undefined(const char *type)
    135 {
    136 	definition *def;
    137 
    138 	def = (definition *) FINDVAL(defined, type, findtype);
    139 
    140 
    141 	return (def == NULL);
    142 }
    143 
    144 static void
    145 print_generic_header(const char *procname, int pointerp)
    146 {
    147 	f_print(fout, "\n");
    148 	f_print(fout, "bool_t\n");
    149 	f_print(fout, "xdr_%s(", procname);
    150 	f_print(fout, "XDR *xdrs, ");
    151 	f_print(fout, "%s ", procname);
    152 	if (pointerp)
    153 		f_print(fout, "*");
    154 	f_print(fout, "objp)\n{\n");
    155 }
    156 
    157 static void
    158 print_header(definition *def)
    159 {
    160 	print_generic_header(def->def_name,
    161 	    def->def_kind != DEF_TYPEDEF ||
    162 	    !isvectordef(def->def.ty.old_type, def->def.ty.rel));
    163 }
    164 
    165 static void
    166 print_prog_header(proc_list *plist)
    167 {
    168 	print_generic_header(plist->args.argname, 1);
    169 }
    170 
    171 static void
    172 print_trailer(void)
    173 {
    174 	f_print(fout, "\treturn (TRUE);\n");
    175 	f_print(fout, "}\n");
    176 }
    177 
    178 
    179 static void
    180 print_ifopen(int indent, const char *name)
    181 {
    182 	char _t_kludge[32];
    183 	/*
    184 	 * XXX Solaris seems to strip the _t. No idea why.
    185 	 */
    186 	if (!strcmp(name, "rpcprog_t") || !strcmp(name, "rpcvers_t") ||
    187 	    !strcmp(name, "rpcproc_t") || !strcmp(name, "rpcprot_t") ||
    188 	    !strcmp(name, "rpcport_t") || !strcmp(name, "rpcpinline_t")) {
    189 		strlcpy(_t_kludge, name, sizeof(_t_kludge));
    190 		char *underscore = strchr(_t_kludge, '_');
    191 		*underscore = 0;
    192 		name = _t_kludge;
    193 	}
    194 	tabify(fout, indent);
    195 	f_print(fout, "if (!xdr_%s(xdrs", name);
    196 }
    197 
    198 static void
    199 print_ifarg(const char *arg)
    200 {
    201 	f_print(fout, ", %s", arg);
    202 }
    203 
    204 static void
    205 print_ifsizeof(const char *prefix, const char *type)
    206 {
    207 	if (streq(type, "bool")) {
    208 		f_print(fout, ", (unsigned int)sizeof(bool_t), (xdrproc_t)xdr_bool");
    209 	} else {
    210 		f_print(fout, ", (unsigned int)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 void
    219 print_ifclose(int indent)
    220 {
    221 	f_print(fout, "))\n");
    222 	tabify(fout, indent);
    223 	f_print(fout, "\treturn (FALSE);\n");
    224 }
    225 
    226 static void
    227 print_ifstat(int indent, const char *prefix, const char *type, relation rel,
    228 	     const char *amax, const char *objname, const char *name)
    229 {
    230 	const char *alt = NULL;
    231 
    232 	switch (rel) {
    233 	case REL_POINTER:
    234 		print_ifopen(indent, "pointer");
    235 		print_ifarg("(char **)(void *)");
    236 		f_print(fout, "%s", objname);
    237 		print_ifsizeof(prefix, type);
    238 		break;
    239 	case REL_VECTOR:
    240 		if (streq(type, "string")) {
    241 			alt = "string";
    242 		} else
    243 			if (streq(type, "opaque")) {
    244 				alt = "opaque";
    245 			}
    246 		if (alt) {
    247 			print_ifopen(indent, alt);
    248 			print_ifarg(objname);
    249 		} else {
    250 			print_ifopen(indent, "vector");
    251 			print_ifarg("(char *)(void *)");
    252 			f_print(fout, "%s", objname);
    253 		}
    254 		print_ifarg(amax);
    255 		if (!alt) {
    256 			print_ifsizeof(prefix, type);
    257 		}
    258 		break;
    259 	case REL_ARRAY:
    260 		if (streq(type, "string")) {
    261 			alt = "string";
    262 		} else
    263 			if (streq(type, "opaque")) {
    264 				alt = "bytes";
    265 			}
    266 		if (streq(type, "string")) {
    267 			print_ifopen(indent, alt);
    268 			print_ifarg(objname);
    269 		} else {
    270 			if (alt) {
    271 				print_ifopen(indent, alt);
    272 			} else {
    273 				print_ifopen(indent, "array");
    274 			}
    275 			print_ifarg("(char **)(void *)");
    276 			if (*objname == '&') {
    277 				f_print(fout, "%s.%s_val, (unsigned int *)%s.%s_len",
    278 				    objname, name, objname, name);
    279 			} else {
    280 				f_print(fout, "&%s->%s_val, (unsigned int *)&%s->%s_len",
    281 				    objname, name, objname, name);
    282 			}
    283 		}
    284 		print_ifarg(amax);
    285 		if (!alt) {
    286 			print_ifsizeof(prefix, type);
    287 		}
    288 		break;
    289 	case REL_ALIAS:
    290 		print_ifopen(indent, type);
    291 		print_ifarg(objname);
    292 		break;
    293 	}
    294 	print_ifclose(indent);
    295 }
    296 /* ARGSUSED */
    297 static void
    298 emit_enum(definition *def)
    299 {
    300 	tabify(fout, 1);
    301 	f_print(fout, "{\n");
    302 	tabify(fout, 2);
    303 	f_print(fout, "enum_t et = (enum_t)*objp;\n");
    304 	print_ifopen(2, "enum");
    305 	print_ifarg("&et");
    306 	print_ifclose(2);
    307 	tabify(fout, 2);
    308 	f_print(fout, "*objp = (%s)et;\n", def->def_name);
    309 	tabify(fout, 1);
    310 	f_print(fout, "}\n");
    311 }
    312 
    313 static void
    314 emit_program(definition *def)
    315 {
    316 	decl_list *dl;
    317 	version_list *vlist;
    318 	proc_list *plist;
    319 
    320 	for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next)
    321 		for (plist = vlist->procs; plist != NULL; plist = plist->next) {
    322 			if (!newstyle || plist->arg_num < 2)
    323 				continue;	/* old style, or single
    324 						 * argument */
    325 			print_prog_header(plist);
    326 			for (dl = plist->args.decls; dl != NULL;
    327 			    dl = dl->next)
    328 				print_stat(1, &dl->decl);
    329 			print_trailer();
    330 		}
    331 }
    332 
    333 
    334 static void
    335 emit_union(definition *def)
    336 {
    337 	declaration *dflt;
    338 	case_list *cl;
    339 	declaration *cs;
    340 	char   *object;
    341 	static const char vecformat[] = "objp->%s_u.%s";
    342 	static const char format[] = "&objp->%s_u.%s";
    343 
    344 	f_print(fout, "\n");
    345 	print_stat(1, &def->def.un.enum_decl);
    346 	f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
    347 	for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
    348 		f_print(fout, "\tcase %s:\n", cl->case_name);
    349 		if (cl->contflag == 1)	/* a continued case statement */
    350 			continue;
    351 		cs = &cl->case_decl;
    352 		if (!streq(cs->type, "void")) {
    353 			object = alloc(strlen(def->def_name) + strlen(format) +
    354 			    strlen(cs->name) + 1);
    355 			if (isvectordef(cs->type, cs->rel)) {
    356 				s_print(object, vecformat, def->def_name,
    357 				    cs->name);
    358 			} else {
    359 				s_print(object, format, def->def_name,
    360 				    cs->name);
    361 			}
    362 			print_ifstat(2, cs->prefix, cs->type, cs->rel,
    363 			    cs->array_max, object, cs->name);
    364 			free(object);
    365 		}
    366 		f_print(fout, "\t\tbreak;\n");
    367 	}
    368 	dflt = def->def.un.default_decl;
    369 	f_print(fout, "\tdefault:\n");
    370 	if (dflt != NULL) {
    371 		if (!streq(dflt->type, "void")) {
    372 			object = alloc(strlen(def->def_name) + strlen(format) +
    373 			    strlen(dflt->name) + 1);
    374 			if (isvectordef(dflt->type, dflt->rel)) {
    375 				s_print(object, vecformat, def->def_name,
    376 				    dflt->name);
    377 			} else {
    378 				s_print(object, format, def->def_name,
    379 				    dflt->name);
    380 			}
    381 			print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
    382 			    dflt->array_max, object, dflt->name);
    383 			free(object);
    384 		}
    385 		f_print(fout, "\t\tbreak;\n");
    386 	} else {
    387 		f_print(fout, "\t\treturn (FALSE);\n");
    388 	}
    389 
    390 	f_print(fout, "\t}\n");
    391 }
    392 
    393 static void
    394 emit_struct(definition *def)
    395 {
    396 	decl_list *dl;
    397 	int     i, j, size, flag;
    398 	decl_list *cur = NULL, *psav;
    399 	bas_type *ptr;
    400 	char   *sizestr;
    401 	const char *plus;
    402 	char    ptemp[256];
    403 	int     can_inline;
    404 
    405 
    406 	if (doinline == 0) {
    407 		f_print(fout, "\n");
    408 		for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
    409 			print_stat(1, &dl->decl);
    410 		return;
    411 	}
    412 	size = 0;
    413 	can_inline = 0;
    414 	for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
    415 		if ((dl->decl.prefix == NULL) &&
    416 		    ((ptr = find_type(dl->decl.type)) != NULL) &&
    417 		    ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
    418 
    419 			if (dl->decl.rel == REL_ALIAS)
    420 				size += ptr->length;
    421 			else {
    422 				can_inline = 1;
    423 				break;	/* can be inlined */
    424 			};
    425 		} else {
    426 			if (size >= doinline) {
    427 				can_inline = 1;
    428 				break;	/* can be inlined */
    429 			}
    430 			size = 0;
    431 		}
    432 	if (size > doinline)
    433 		can_inline = 1;
    434 
    435 	if (can_inline == 0) {	/* can not inline, drop back to old mode */
    436 		f_print(fout, "\n");
    437 		for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
    438 			print_stat(1, &dl->decl);
    439 		return;
    440 	};
    441 
    442 	/* May cause lint to complain. but  ... */
    443 	f_print(fout, "\tint32_t *buf;\n");
    444 
    445 	flag = PUT;
    446 	f_print(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n");
    447 
    448 	for (j = 0; j < 2; j++) {
    449 		i = 0;
    450 		size = 0;
    451 		sizestr = NULL;
    452 		for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {	/* xxx */
    453 
    454 			/* now walk down the list and check for basic types */
    455 			if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
    456 				if (i == 0)
    457 					cur = dl;
    458 				i++;
    459 
    460 				if (dl->decl.rel == REL_ALIAS)
    461 					size += ptr->length;
    462 				else {
    463 					/* this is required to handle arrays */
    464 
    465 					if (sizestr == NULL)
    466 						plus = "";
    467 					else
    468 						plus = " + ";
    469 
    470 					if (ptr->length != 1)
    471 						s_print(ptemp, "%s%s * %d", plus, dl->decl.array_max, ptr->length);
    472 					else
    473 						s_print(ptemp, "%s%s", plus, dl->decl.array_max);
    474 
    475 					/* now concatenate to sizestr !!!! */
    476 					if (sizestr == NULL)
    477 						sizestr = strdup(ptemp);
    478 					else {
    479 						char *nsizestr;
    480 
    481 						nsizestr = realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1);
    482 						if (nsizestr == NULL) {
    483 							err(EXIT_FAILURE, "realloc");
    484 						}
    485 						sizestr = nsizestr;
    486 						sizestr = strcat(sizestr, ptemp);	/* build up length of
    487 											 * array */
    488 
    489 					}
    490 				}
    491 
    492 			} else {
    493 				if (i > 0)  {
    494 					if (sizestr == NULL && size < doinline) {
    495 						/* don't expand into inline
    496 						 * code if size < doinline */
    497 						while (cur != dl) {
    498 							print_stat(2, &cur->decl);
    499 							cur = cur->next;
    500 						}
    501 					} else {
    502 
    503 
    504 
    505 						/* were already looking at a
    506 						 * xdr_inlineable structure */
    507 						if (sizestr == NULL)
    508 							f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n",
    509 							    size);
    510 						else
    511 							if (size == 0)
    512 								f_print(fout,
    513 								    "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n",
    514 								    sizestr);
    515 							else
    516 								f_print(fout,
    517 								    "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n",
    518 								    size, sizestr);
    519 
    520 						f_print(fout, "\t\tif (buf == NULL) {\n");
    521 
    522 						psav = cur;
    523 						while (cur != dl) {
    524 							print_stat(3, &cur->decl);
    525 							cur = cur->next;
    526 						}
    527 
    528 						f_print(fout, "\t\t} else {\n");
    529 
    530 						cur = psav;
    531 						while (cur != dl) {
    532 							emit_inline(&cur->decl, flag);
    533 							cur = cur->next;
    534 						}
    535 
    536 						f_print(fout, "\t\t}\n");
    537 					}
    538 				}
    539 				size = 0;
    540 				i = 0;
    541 				if (sizestr) {
    542 					free(sizestr);
    543 					sizestr = NULL;
    544 				}
    545 				print_stat(2, &dl->decl);
    546 			}
    547 
    548 		}
    549 		if (i > 0) {
    550 			if (sizestr == NULL && size < doinline) {
    551 				/* don't expand into inline code if size <
    552 				 * doinline */
    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 void
    610 emit_typedef(definition *def)
    611 {
    612 	const char *prefix = def->def.ty.old_prefix;
    613 	const char *type = def->def.ty.old_type;
    614 	const char *amax = def->def.ty.array_max;
    615 	relation rel = def->def.ty.rel;
    616 
    617 	f_print(fout, "\n");
    618 	print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
    619 }
    620 
    621 static void
    622 print_stat(int indent, declaration *dec)
    623 {
    624 	const char *prefix = dec->prefix;
    625 	const char *type = dec->type;
    626 	const char *amax = dec->array_max;
    627 	relation rel = dec->rel;
    628 	char    name[256];
    629 
    630 	if (isvectordef(type, rel)) {
    631 		s_print(name, "objp->%s", dec->name);
    632 	} else {
    633 		s_print(name, "&objp->%s", dec->name);
    634 	}
    635 	print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
    636 }
    637 
    638 
    639 void
    640 emit_inline(declaration *decl, int flag)
    641 {
    642 
    643 /*check whether an array or not */
    644 
    645 	switch (decl->rel) {
    646 	case REL_ALIAS:
    647 		emit_single_in_line(decl, flag, REL_ALIAS);
    648 		break;
    649 	case REL_VECTOR:
    650 		f_print(fout, "\t\t\t{\n");
    651 		f_print(fout, "\t\t\t\tint i;\n");
    652 		f_print(fout, "\t\t\t\t%s *genp;\n", decl->type);
    653 		f_print(fout, "\n");
    654 		f_print(fout, "\t\t\t\tfor (i = 0, genp = objp->%s;\n",
    655 		    decl->name);
    656 		f_print(fout, "\t\t\t\t    i < %s; i++) {\n\t\t",
    657 		    decl->array_max);
    658 		emit_single_in_line(decl, flag, REL_VECTOR);
    659 		f_print(fout, "\t\t\t\t}\n\t\t\t}\n");
    660 		break;
    661 	case REL_ARRAY:
    662 	case REL_POINTER:
    663 		errx(1, "Internal error at %s:%d: Case %d not handled",
    664 		    __FILE__, __LINE__, decl->rel);
    665 	}
    666 }
    667 
    668 void
    669 emit_single_in_line(declaration *decl, int flag, relation rel)
    670 {
    671 	const char *upp_case;
    672 	char *freeable;
    673 	int     freed = 0;
    674 
    675 	if (flag == PUT)
    676 		f_print(fout, "\t\t\tIXDR_PUT_");
    677 	else
    678 		if (rel == REL_ALIAS)
    679 			f_print(fout, "\t\t\tobjp->%s = IXDR_GET_", decl->name);
    680 		else
    681 			f_print(fout, "\t\t\t*genp++ = IXDR_GET_");
    682 
    683 	upp_case = freeable = upcase(decl->type);
    684 
    685 	/* hack  - XX */
    686 	if (strcmp(upp_case, "INT") == 0) {
    687 		free(freeable);
    688 		freed = 1;
    689 		upp_case = "INT32";
    690 	} else if (strcmp(upp_case, "U_INT") == 0) {
    691 		free(freeable);
    692 		freed = 1;
    693 		upp_case = "U_INT32";
    694 	}
    695 	if (flag == PUT) {
    696 		if (rel == REL_ALIAS)
    697 			f_print(fout, "%s(buf, objp->%s);\n", upp_case, decl->name);
    698 		else
    699 			f_print(fout, "%s(buf, *genp++);\n", upp_case);
    700 
    701 	} else
    702 		f_print(fout, "%s(buf);\n", upp_case);
    703 	if (!freed)
    704 		free(freeable);
    705 
    706 }
    707 
    708 
    709 char   *
    710 upcase(const char *str)
    711 {
    712 	char   *ptr, *hptr;
    713 
    714 
    715 	ptr = malloc(strlen(str) + 1);
    716 	if (ptr == NULL) {
    717 		errx(EXIT_FAILURE, "Out of memory");
    718 	}
    719 
    720 	hptr = ptr;
    721 	while (*str != '\0')
    722 		*ptr++ = toupper((unsigned char)*str++);
    723 
    724 	*ptr = '\0';
    725 	return (hptr);
    726 
    727 }
    728