Home | History | Annotate | Line # | Download | only in rpcgen
rpc_cout.c revision 1.31
      1 /*	$NetBSD: rpc_cout.c,v 1.31 2013/08/11 08:03:10 dholland 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.31 2013/08/11 08:03:10 dholland 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 __P((definition *, const char *));
     58 static int undefined __P((const char *));
     59 static void print_generic_header __P((const char *, int));
     60 static void print_header __P((definition *));
     61 static void print_prog_header __P((proc_list *));
     62 static void print_trailer __P((void));
     63 static void print_ifopen __P((int, const char *));
     64 static void print_ifarg __P((const char *));
     65 static void print_ifsizeof __P((const char *, const char *));
     66 static void print_ifclose __P((int));
     67 static void print_ifstat __P((int, const char *, const char *, relation,
     68 			      const char *, const char *, const char *));
     69 static void emit_enum __P((definition *));
     70 static void emit_program __P((definition *));
     71 static void emit_union __P((definition *));
     72 static void emit_struct __P((definition *));
     73 static void emit_typedef __P((definition *));
     74 static void print_stat __P((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 %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 	if (Cflag) {
    150 		f_print(fout, "xdr_%s(", procname);
    151 		f_print(fout, "XDR *xdrs, ");
    152 		f_print(fout, "%s ", procname);
    153 		if (pointerp)
    154 			f_print(fout, "*");
    155 		f_print(fout, "objp)\n{\n");
    156 	} else {
    157 		f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
    158 		f_print(fout, "\tXDR *xdrs;\n");
    159 		f_print(fout, "\t%s ", procname);
    160 		if (pointerp)
    161 			f_print(fout, "*");
    162 		f_print(fout, "objp;\n{\n");
    163 	}
    164 }
    165 
    166 static void
    167 print_header(definition *def)
    168 {
    169 	print_generic_header(def->def_name,
    170 	    def->def_kind != DEF_TYPEDEF ||
    171 	    !isvectordef(def->def.ty.old_type, def->def.ty.rel));
    172 }
    173 
    174 static void
    175 print_prog_header(proc_list *plist)
    176 {
    177 	print_generic_header(plist->args.argname, 1);
    178 }
    179 
    180 static void
    181 print_trailer(void)
    182 {
    183 	f_print(fout, "\treturn (TRUE);\n");
    184 	f_print(fout, "}\n");
    185 }
    186 
    187 
    188 static void
    189 print_ifopen(int indent, const char *name)
    190 {
    191 	char _t_kludge[32];
    192 	/*
    193 	 * XXX Solaris seems to strip the _t. No idea why.
    194 	 */
    195 	if (!strcmp(name, "rpcprog_t") || !strcmp(name, "rpcvers_t") ||
    196 	    !strcmp(name, "rpcproc_t") || !strcmp(name, "rpcprot_t") ||
    197 	    !strcmp(name, "rpcport_t") || !strcmp(name, "rpcpinline_t")) {
    198 		strncpy(_t_kludge, name, strlen(name) - 2);
    199 		name = _t_kludge;
    200 	}
    201 	tabify(fout, indent);
    202 	f_print(fout, "if (!xdr_%s(xdrs", name);
    203 }
    204 
    205 static void
    206 print_ifarg(const char *arg)
    207 {
    208 	f_print(fout, ", %s", arg);
    209 }
    210 
    211 static void
    212 print_ifsizeof(const char *prefix, const char *type)
    213 {
    214 	if (streq(type, "bool")) {
    215 		f_print(fout, ", (u_int)sizeof(bool_t), (xdrproc_t)xdr_bool");
    216 	} else {
    217 		f_print(fout, ", (u_int)sizeof(");
    218 		if (undefined(type) && prefix) {
    219 			f_print(fout, "%s ", prefix);
    220 		}
    221 		f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type);
    222 	}
    223 }
    224 
    225 static void
    226 print_ifclose(int indent)
    227 {
    228 	f_print(fout, "))\n");
    229 	tabify(fout, indent);
    230 	f_print(fout, "\treturn (FALSE);\n");
    231 }
    232 
    233 static void
    234 print_ifstat(int indent, const char *prefix, const char *type, relation rel,
    235 	     const char *amax, const char *objname, const char *name)
    236 {
    237 	const char *alt = NULL;
    238 
    239 	switch (rel) {
    240 	case REL_POINTER:
    241 		print_ifopen(indent, "pointer");
    242 		print_ifarg("(char **)(void *)");
    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 *)(void *)");
    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 **)(void *)");
    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 /* ARGSUSED */
    304 static void
    305 emit_enum(definition *def)
    306 {
    307 	tabify(fout, 1);
    308 	f_print(fout, "{\n");
    309 	tabify(fout, 2);
    310 	f_print(fout, "enum_t et = (enum_t)*objp;\n");
    311 	print_ifopen(2, "enum");
    312 	print_ifarg("&et");
    313 	print_ifclose(2);
    314 	tabify(fout, 2);
    315 	f_print(fout, "*objp = (%s)et;\n", def->def_name);
    316 	tabify(fout, 1);
    317 	f_print(fout, "}\n");
    318 }
    319 
    320 static void
    321 emit_program(definition *def)
    322 {
    323 	decl_list *dl;
    324 	version_list *vlist;
    325 	proc_list *plist;
    326 
    327 	for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next)
    328 		for (plist = vlist->procs; plist != NULL; plist = plist->next) {
    329 			if (!newstyle || plist->arg_num < 2)
    330 				continue;	/* old style, or single
    331 						 * argument */
    332 			print_prog_header(plist);
    333 			for (dl = plist->args.decls; dl != NULL;
    334 			    dl = dl->next)
    335 				print_stat(1, &dl->decl);
    336 			print_trailer();
    337 		}
    338 }
    339 
    340 
    341 static void
    342 emit_union(definition *def)
    343 {
    344 	declaration *dflt;
    345 	case_list *cl;
    346 	declaration *cs;
    347 	char   *object;
    348 	static const char vecformat[] = "objp->%s_u.%s";
    349 	static const char format[] = "&objp->%s_u.%s";
    350 
    351 	f_print(fout, "\n");
    352 	print_stat(1, &def->def.un.enum_decl);
    353 	f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
    354 	for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
    355 		f_print(fout, "\tcase %s:\n", cl->case_name);
    356 		if (cl->contflag == 1)	/* a continued case statement */
    357 			continue;
    358 		cs = &cl->case_decl;
    359 		if (!streq(cs->type, "void")) {
    360 			object = alloc(strlen(def->def_name) + strlen(format) +
    361 			    strlen(cs->name) + 1);
    362 			if (isvectordef(cs->type, cs->rel)) {
    363 				s_print(object, vecformat, def->def_name,
    364 				    cs->name);
    365 			} else {
    366 				s_print(object, format, def->def_name,
    367 				    cs->name);
    368 			}
    369 			print_ifstat(2, cs->prefix, cs->type, cs->rel,
    370 			    cs->array_max, object, cs->name);
    371 			free(object);
    372 		}
    373 		f_print(fout, "\t\tbreak;\n");
    374 	}
    375 	dflt = def->def.un.default_decl;
    376 	f_print(fout, "\tdefault:\n");
    377 	if (dflt != NULL) {
    378 		if (!streq(dflt->type, "void")) {
    379 			object = alloc(strlen(def->def_name) + strlen(format) +
    380 			    strlen(dflt->name) + 1);
    381 			if (isvectordef(dflt->type, dflt->rel)) {
    382 				s_print(object, vecformat, def->def_name,
    383 				    dflt->name);
    384 			} else {
    385 				s_print(object, format, def->def_name,
    386 				    dflt->name);
    387 			}
    388 			print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
    389 			    dflt->array_max, object, dflt->name);
    390 			free(object);
    391 		}
    392 		f_print(fout, "\t\tbreak;\n");
    393 	} else {
    394 		f_print(fout, "\t\treturn (FALSE);\n");
    395 	}
    396 
    397 	f_print(fout, "\t}\n");
    398 }
    399 
    400 static void
    401 emit_struct(definition *def)
    402 {
    403 	decl_list *dl;
    404 	int     i, j, size, flag;
    405 	decl_list *cur = NULL, *psav;
    406 	bas_type *ptr;
    407 	char   *sizestr;
    408 	const char *plus;
    409 	char    ptemp[256];
    410 	int     can_inline;
    411 
    412 
    413 	if (doinline == 0) {
    414 		f_print(fout, "\n");
    415 		for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
    416 			print_stat(1, &dl->decl);
    417 		return;
    418 	}
    419 	size = 0;
    420 	can_inline = 0;
    421 	for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
    422 		if ((dl->decl.prefix == NULL) &&
    423 		    ((ptr = find_type(dl->decl.type)) != NULL) &&
    424 		    ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
    425 
    426 			if (dl->decl.rel == REL_ALIAS)
    427 				size += ptr->length;
    428 			else {
    429 				can_inline = 1;
    430 				break;	/* can be inlined */
    431 			};
    432 		} else {
    433 			if (size >= doinline) {
    434 				can_inline = 1;
    435 				break;	/* can be inlined */
    436 			}
    437 			size = 0;
    438 		}
    439 	if (size > doinline)
    440 		can_inline = 1;
    441 
    442 	if (can_inline == 0) {	/* can not inline, drop back to old mode */
    443 		f_print(fout, "\n");
    444 		for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
    445 			print_stat(1, &dl->decl);
    446 		return;
    447 	};
    448 
    449 	/* May cause lint to complain. but  ... */
    450 	f_print(fout, "\tint32_t *buf;\n");
    451 
    452 	flag = PUT;
    453 	f_print(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n");
    454 
    455 	for (j = 0; j < 2; j++) {
    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 						char *nsizestr;
    487 
    488 						nsizestr = (char *) realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1);
    489 						if (nsizestr == NULL) {
    490 
    491 							f_print(stderr, "Fatal error : no memory\n");
    492 							crash();
    493 						}
    494 						sizestr = nsizestr;
    495 						sizestr = strcat(sizestr, ptemp);	/* build up length of
    496 											 * array */
    497 
    498 					}
    499 				}
    500 
    501 			} else {
    502 				if (i > 0)  {
    503 					if (sizestr == NULL && size < doinline) {
    504 						/* don't expand into inline
    505 						 * code if size < doinline */
    506 						while (cur != dl) {
    507 							print_stat(2, &cur->decl);
    508 							cur = cur->next;
    509 						}
    510 					} else {
    511 
    512 
    513 
    514 						/* were already looking at a
    515 						 * xdr_inlineable structure */
    516 						if (sizestr == NULL)
    517 							f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n",
    518 							    size);
    519 						else
    520 							if (size == 0)
    521 								f_print(fout,
    522 								    "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n",
    523 								    sizestr);
    524 							else
    525 								f_print(fout,
    526 								    "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n",
    527 								    size, sizestr);
    528 
    529 						f_print(fout, "\t\tif (buf == NULL) {\n");
    530 
    531 						psav = cur;
    532 						while (cur != dl) {
    533 							print_stat(3, &cur->decl);
    534 							cur = cur->next;
    535 						}
    536 
    537 						f_print(fout, "\t\t} else {\n");
    538 
    539 						cur = psav;
    540 						while (cur != dl) {
    541 							emit_inline(&cur->decl, flag);
    542 							cur = cur->next;
    543 						}
    544 
    545 						f_print(fout, "\t\t}\n");
    546 					}
    547 				}
    548 				size = 0;
    549 				i = 0;
    550 				if (sizestr) {
    551 					free(sizestr);
    552 					sizestr = NULL;
    553 				}
    554 				print_stat(2, &dl->decl);
    555 			}
    556 
    557 		}
    558 		if (i > 0) {
    559 			if (sizestr == NULL && size < doinline) {
    560 				/* don't expand into inline code if size <
    561 				 * doinline */
    562 				while (cur != dl) {
    563 					print_stat(2, &cur->decl);
    564 					cur = cur->next;
    565 				}
    566 			} else {
    567 
    568 				/* were already looking at a xdr_inlineable
    569 				 * structure */
    570 				if (sizestr == NULL)
    571 					f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n",
    572 					    size);
    573 				else
    574 					if (size == 0)
    575 						f_print(fout,
    576 						    "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n",
    577 						    sizestr);
    578 					else
    579 						f_print(fout,
    580 						    "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n",
    581 						    size, sizestr);
    582 
    583 				f_print(fout, "\t\tif (buf == NULL) {\n");
    584 
    585 				psav = cur;
    586 				while (cur != NULL) {
    587 					print_stat(3, &cur->decl);
    588 					cur = cur->next;
    589 				}
    590 				f_print(fout, "\t\t} else {\n");
    591 
    592 				cur = psav;
    593 				while (cur != dl) {
    594 					emit_inline(&cur->decl, flag);
    595 					cur = cur->next;
    596 				}
    597 
    598 				f_print(fout, "\t\t}\n");
    599 
    600 			}
    601 		}
    602 		if (flag == PUT) {
    603 			flag = GET;
    604 			f_print(fout, "\t} else if (xdrs->x_op == XDR_DECODE) {\n");
    605 		}
    606 	}
    607 
    608 	f_print(fout, "\t} else {\n");
    609 
    610 	/* now take care of XDR_FREE case */
    611 
    612 	for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
    613 		print_stat(2, &dl->decl);
    614 
    615 	f_print(fout, "\t}\n");
    616 }
    617 
    618 static void
    619 emit_typedef(definition *def)
    620 {
    621 	const char *prefix = def->def.ty.old_prefix;
    622 	const char *type = def->def.ty.old_type;
    623 	const char *amax = def->def.ty.array_max;
    624 	relation rel = def->def.ty.rel;
    625 
    626 	f_print(fout, "\n");
    627 	print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
    628 }
    629 
    630 static void
    631 print_stat(int indent, declaration *dec)
    632 {
    633 	const char *prefix = dec->prefix;
    634 	const char *type = dec->type;
    635 	const char *amax = dec->array_max;
    636 	relation rel = dec->rel;
    637 	char    name[256];
    638 
    639 	if (isvectordef(type, rel)) {
    640 		s_print(name, "objp->%s", dec->name);
    641 	} else {
    642 		s_print(name, "&objp->%s", dec->name);
    643 	}
    644 	print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
    645 }
    646 
    647 
    648 void
    649 emit_inline(declaration *decl, int flag)
    650 {
    651 
    652 /*check whether an array or not */
    653 
    654 	switch (decl->rel) {
    655 	case REL_ALIAS:
    656 		emit_single_in_line(decl, flag, REL_ALIAS);
    657 		break;
    658 	case REL_VECTOR:
    659 		f_print(fout, "\t\t\t{\n");
    660 		f_print(fout, "\t\t\t\tint i;\n");
    661 		f_print(fout, "\t\t\t\t%s *genp;\n", decl->type);
    662 		f_print(fout, "\n");
    663 		f_print(fout, "\t\t\t\tfor (i = 0, genp = objp->%s;\n",
    664 		    decl->name);
    665 		f_print(fout, "\t\t\t\t    i < %s; i++) {\n\t\t",
    666 		    decl->array_max);
    667 		emit_single_in_line(decl, flag, REL_VECTOR);
    668 		f_print(fout, "\t\t\t\t}\n\t\t\t}\n");
    669 		break;
    670 	case REL_ARRAY:
    671 	case REL_POINTER:
    672 		errx(1, "Internal error %s, %d: Case %d not handled",
    673 		    __FILE__, __LINE__, decl->rel);
    674 	}
    675 }
    676 
    677 void
    678 emit_single_in_line(declaration *decl, int flag, relation rel)
    679 {
    680 	const char *upp_case;
    681 	char *freeable;
    682 	int     freed = 0;
    683 
    684 	if (flag == PUT)
    685 		f_print(fout, "\t\t\tIXDR_PUT_");
    686 	else
    687 		if (rel == REL_ALIAS)
    688 			f_print(fout, "\t\t\tobjp->%s = IXDR_GET_", decl->name);
    689 		else
    690 			f_print(fout, "\t\t\t*genp++ = IXDR_GET_");
    691 
    692 	upp_case = freeable = upcase(decl->type);
    693 
    694 	/* hack  - XX */
    695 	if (strcmp(upp_case, "INT") == 0) {
    696 		free(freeable);
    697 		freed = 1;
    698 		upp_case = "INT32";
    699 	}
    700 	if (strcmp(upp_case, "U_INT") == 0) {
    701 		free(freeable);
    702 		freed = 1;
    703 		upp_case = "U_INT32";
    704 	}
    705 	if (flag == PUT) {
    706 		if (rel == REL_ALIAS)
    707 			f_print(fout, "%s(buf, objp->%s);\n", upp_case, decl->name);
    708 		else
    709 			f_print(fout, "%s(buf, *genp++);\n", upp_case);
    710 
    711 	} else
    712 		f_print(fout, "%s(buf);\n", upp_case);
    713 	if (!freed)
    714 		free(freeable);
    715 
    716 }
    717 
    718 
    719 char   *
    720 upcase(const char *str)
    721 {
    722 	char   *ptr, *hptr;
    723 
    724 
    725 	ptr = (char *) malloc(strlen(str) + 1);
    726 	if (ptr == NULL) {
    727 		f_print(stderr, "malloc failed\n");
    728 		exit(1);
    729 	};
    730 
    731 	hptr = ptr;
    732 	while (*str != '\0')
    733 		*ptr++ = toupper((unsigned char)*str++);
    734 
    735 	*ptr = '\0';
    736 	return (hptr);
    737 
    738 }
    739