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