GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/rpcgen/rpc_cout.c Lines: 0 310 0.0 %
Date: 2016-12-06 Branches: 0 193 0.0 %

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