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