GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/rpcgen/rpc_hout.c Lines: 199 224 88.8 %
Date: 2017-11-07 Branches: 103 127 81.1 %

Line Branch Exec Source
1
/*	$OpenBSD: rpc_hout.c,v 1.22 2016/12/20 22:19:08 krw Exp $	*/
2
/*	$NetBSD: rpc_hout.c,v 1.4 1995/06/11 21:49:55 pk 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_hout.c, Header file outputter for the RPC protocol compiler
37
 */
38
#include <stdio.h>
39
#include <stdlib.h>
40
#include <ctype.h>
41
#include "rpc_parse.h"
42
#include "rpc_util.h"
43
44
static void pconstdef(definition *);
45
static void pargdef(definition *);
46
static void pstructdef(definition *);
47
static void puniondef(definition *);
48
static void pprogramdef(definition *);
49
static void penumdef(definition *);
50
static void ptypedef(definition *);
51
static void pdefine(char *, char *);
52
static void puldefine(char *, char *);
53
static int define_printed(proc_list *, version_list *);
54
static int undefined2(char *, char *);
55
static void parglist(proc_list *, char *);
56
void pxdrfuncdecl(char *, int);
57
void pprocdef(proc_list *, version_list *, char *, int, int);
58
void pdeclaration(char *, declaration *, int, char *);
59
60
/*
61
 * Print the C-version of an xdr definition
62
 */
63
void
64
print_datadef(def)
65
	definition *def;
66
{
67
68
1164
	if (def->def_kind == DEF_PROGRAM)  /* handle data only */
69
		return;
70
71
550
	if (def->def_kind != DEF_CONST)
72
290
		fprintf(fout, "\n");
73

1100
	switch (def->def_kind) {
74
	case DEF_STRUCT:
75
196
		pstructdef(def);
76
196
		break;
77
	case DEF_UNION:
78
28
		puniondef(def);
79
28
		break;
80
	case DEF_ENUM:
81
26
		penumdef(def);
82
26
		break;
83
	case DEF_TYPEDEF:
84
40
		ptypedef(def);
85
40
		break;
86
	case DEF_PROGRAM:
87
		pprogramdef(def);
88
		break;
89
	case DEF_CONST:
90
260
		pconstdef(def);
91
260
		break;
92
	default:
93
		break;
94
	}
95

1100
	if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
96
580
		pxdrfuncdecl(def->def_name,
97
620
		    def->def_kind != DEF_TYPEDEF ||
98
40
		    !isvectordef(def->def.ty.old_type, def->def.ty.rel));
99
290
	}
100
582
}
101
102
103
void
104
print_funcdef(def)
105
	definition *def;
106
{
107
1164
	switch (def->def_kind) {
108
	case DEF_PROGRAM:
109
32
		fprintf(fout, "\n");
110
32
		pprogramdef(def);
111
32
		break;
112
	default:
113
		break;
114
	}
115
582
}
116
117
void
118
pxdrfuncdecl(name, pointerp)
119
	char *name;
120
	int pointerp;
121
{
122
123
580
	fprintf(fout,"#ifdef __cplusplus\n");
124
580
	fprintf(fout, "extern \"C\" bool_t xdr_%s(XDR *, %s %s);\n",
125
290
	    name, name, pointerp ? ("*") : "");
126
290
	fprintf(fout,"#elif defined(__STDC__)\n");
127
290
	fprintf(fout, "extern bool_t xdr_%s(XDR *, %s %s);\n",
128
	    name, name, pointerp ? ("*") : "");
129
290
	fprintf(fout,"#else /* Old Style C */\n");
130
290
	fprintf(fout, "bool_t xdr_%s();\n", name);
131
290
	fprintf(fout,"#endif /* Old Style C */\n\n");
132
290
}
133
134
135
static void
136
pconstdef(def)
137
	definition *def;
138
{
139
520
	pdefine(def->def_name, def->def.co);
140
260
}
141
142
/*
143
 * print out the definitions for the arguments of functions in the
144
 * header file
145
 */
146
static void
147
pargdef(def)
148
	definition *def;
149
{
150
	decl_list *l;
151
	version_list *vers;
152
	char *name;
153
	proc_list *plist;
154
155
180
	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
156
540
		for (plist = vers->procs; plist != NULL;
157
228
		    plist = plist->next) {
158

228
			if (!newstyle || plist->arg_num < 2) {
159
				continue; /* old style or single args */
160
			}
161
			name = plist->args.argname;
162
			fprintf(fout, "struct %s {\n", name);
163
			for (l = plist->args.decls;
164
			    l != NULL; l = l->next) {
165
				pdeclaration(name, &l->decl, 1, ";\n");
166
			}
167
			fprintf(fout, "};\n");
168
			fprintf(fout, "typedef struct %s %s;\n", name, name);
169
			pxdrfuncdecl(name, 0);
170
			fprintf(fout, "\n");
171
		}
172
	}
173
32
}
174
175
static void
176
pstructdef(def)
177
	definition *def;
178
{
179
392
	char *name = def->def_name;
180
	decl_list *l;
181
182
196
	fprintf(fout, "struct %s {\n", name);
183
1760
	for (l = def->def.st.decls; l != NULL; l = l->next)
184
684
		pdeclaration(name, &l->decl, 1, ";\n");
185
196
	fprintf(fout, "};\n");
186
196
	fprintf(fout, "typedef struct %s %s;\n", name, name);
187
196
}
188
189
static void
190
puniondef(def)
191
	definition *def;
192
{
193
	case_list *l;
194
56
	char *name = def->def_name;
195
	declaration *decl;
196
197
28
	fprintf(fout, "struct %s {\n", name);
198
28
	decl = &def->def.un.enum_decl;
199
28
	if (streq(decl->type, "bool")) {
200
2
		fprintf(fout, "\tbool_t %s;\n", decl->name);
201
2
	} else {
202
26
		fprintf(fout, "\t%s %s;\n", decl->type, decl->name);
203
	}
204
28
	fprintf(fout, "\tunion {\n");
205
128
	for (l = def->def.un.cases; l != NULL; l = l->next) {
206
36
	  if (l->contflag == 0)
207
36
		pdeclaration(name, &l->case_decl, 2, ";\n");
208
	}
209
28
	decl = def->def.un.default_decl;
210

48
	if (decl && !streq(decl->type, "void")) {
211
		pdeclaration(name, decl, 2, ";\n");
212
	}
213
28
	fprintf(fout, "\t} %s_u;\n", name);
214
28
	fprintf(fout, "};\n");
215
28
	fprintf(fout, "typedef struct %s %s;\n", name, name);
216
28
}
217
218
static void
219
pdefine(name, num)
220
	char *name;
221
	char *num;
222
{
223
520
	fprintf(fout, "#define %s %s\n", name, num);
224
260
}
225
226
static void
227
puldefine(name, num)
228
	char *name;
229
	char *num;
230
{
231
1468
	fprintf(fout, "#define %s ((u_long)%s)\n", name, num);
232
734
}
233
234
static int
235
define_printed(stop, start)
236
	proc_list *stop;
237
	version_list *start;
238
{
239
	version_list *vers;
240
	proc_list *proc;
241
242
3012
	for (vers = start; vers != NULL; vers = vers->next) {
243
14652
		for (proc = vers->procs; proc != NULL; proc = proc->next) {
244
6846
			if (proc == stop) {
245
660
				return (0);
246
6186
			} else if (streq(proc->proc_name, stop->proc_name)) {
247
24
				return (1);
248
			}
249
		}
250
	}
251
	abort();
252
	/* NOTREACHED */
253
684
}
254
255
static void
256
pprogramdef(def)
257
	definition *def;
258
{
259
	version_list *vers;
260
	proc_list *proc;
261
	int i;
262
	char *ext;
263
264
64
	pargdef(def);
265
266
32
	puldefine(def->def_name, def->def.pr.prog_num);
267
148
	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
268
42
		if (tblflag) {
269
			fprintf(fout, "extern struct rpcgen_table %s_%s_table[];\n",
270
			    locase(def->def_name), vers->vers_num);
271
			fprintf(fout, "extern %s_%s_nproc;\n",
272
			    locase(def->def_name), vers->vers_num);
273
		}
274
42
		puldefine(vers->vers_name, vers->vers_num);
275
276
		/*
277
		 * Print out 3 definitions, one for ANSI-C, another for C++,
278
		 * a third for old style C
279
		 */
280
336
		for (i=0; i<3; i++) {
281
126
			if (i==0) {
282
42
				fprintf(fout,"\n#ifdef __cplusplus\n");
283
				ext = "extern \"C\" ";
284
126
			} else if (i==1) {
285
42
				fprintf(fout,"\n#elif defined(__STDC__)\n");
286
				ext = "extern ";
287
42
			} else {
288
42
				fprintf(fout,"\n#else /* Old Style C */\n");
289
				ext = "extern ";
290
			}
291
292
1620
			for (proc = vers->procs; proc != NULL; proc = proc->next) {
293
684
				if (!define_printed(proc, def->def.pr.versions))
294
660
					puldefine(proc->proc_name, proc->proc_num);
295
684
				fprintf(fout,"%s",ext);
296
684
				pprocdef(proc, vers, "CLIENT *", 0,i);
297
684
				fprintf(fout,"%s",ext);
298
684
				pprocdef(proc, vers, "struct svc_req *", 1,i);
299
			}
300
		}
301
42
		fprintf(fout,"#endif /* Old Style C */\n");
302
	}
303
32
}
304
305
void
306
pprocdef(proc, vp, addargtype, server_p,mode)
307
	proc_list *proc;
308
	version_list *vp;
309
	char *addargtype;
310
	int server_p;
311
	int mode;
312
{
313
314
2736
	ptype(proc->res_prefix, proc->res_type, 1);
315
1368
	fprintf(fout, "* ");
316
1368
	if (server_p)
317
684
		pvname_svc(proc->proc_name, vp->vers_num);
318
	else
319
684
		pvname(proc->proc_name, vp->vers_num);
320
321
	/*
322
	 * mode  0 == cplusplus, mode  1 = ANSI-C, mode 2 = old style C
323
	 */
324
1368
	if (mode == 0 || mode == 1)
325
912
		parglist(proc, addargtype);
326
	else
327
456
		fprintf(fout, "();\n");
328
1368
}
329
330
/* print out argument list of procedure */
331
static void
332
parglist(proc, addargtype)
333
	proc_list *proc;
334
	char *addargtype;
335
{
336
	decl_list *dl;
337
338
1824
	fprintf(fout,"(");
339
340

912
	if (proc->arg_num < 2 && newstyle &&
341
	   streq(proc->args.decls->decl.type, "void")) {
342
		/* 0 argument in new style:  do nothing */
343
	} else {
344
3648
		for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
345
912
			ptype(dl->decl.prefix, dl->decl.type, 1);
346
912
			if (!newstyle)
347
912
				fprintf(fout, "*"); /* old style passes by reference */
348
912
			fprintf(fout, ", ");
349
		}
350
	}
351
912
	fprintf(fout, "%s);\n", addargtype);
352
912
}
353
354
static void
355
penumdef(def)
356
	definition *def;
357
{
358
52
	char *name = def->def_name;
359
	enumval_list *l;
360
	char *last = NULL;
361
	int count = 0;
362
363
26
	fprintf(fout, "enum %s {\n", name);
364
468
	for (l = def->def.en.vals; l != NULL; l = l->next) {
365
208
		fprintf(fout, "\t%s", l->name);
366
208
		if (l->assignment) {
367
208
			fprintf(fout, " = %s", l->assignment);
368
208
			last = l->assignment;
369
			count = 1;
370
208
		} else {
371
			if (last == NULL) {
372
				fprintf(fout, " = %d", count++);
373
			} else {
374
				fprintf(fout, " = %s + %d", last, count++);
375
			}
376
		}
377
208
		if (l->next)
378
182
			fprintf(fout, ",\n");
379
		else
380
26
			fprintf(fout, "\n");
381
	}
382
26
	fprintf(fout, "};\n");
383
26
	fprintf(fout, "typedef enum %s %s;\n", name, name);
384
26
}
385
386
static void
387
ptypedef(def)
388
	definition *def;
389
{
390
80
	char *name = def->def_name;
391
40
	char *old = def->def.ty.old_type;
392
40
	char prefix[8];	/* enough to contain "struct ", including NUL */
393
40
	relation rel = def->def.ty.rel;
394
395
40
	if (!streq(name, old)) {
396
40
		if (streq(old, "string")) {
397
			old = "char";
398
			rel = REL_POINTER;
399
40
		} else if (streq(old, "opaque")) {
400
			old = "char";
401
18
		} else if (streq(old, "bool")) {
402
			old = "bool_t";
403
		}
404

78
		if (undefined2(old, name) && def->def.ty.old_prefix) {
405
6
			snprintf(prefix, sizeof prefix, "%s ", def->def.ty.old_prefix);
406
6
		} else {
407
34
			prefix[0] = 0;
408
		}
409
80
		fprintf(fout, "typedef ");
410

80
		switch (rel) {
411
		case REL_ARRAY:
412
8
			fprintf(fout, "struct {\n");
413
8
			fprintf(fout, "\tu_int %s_len;\n", name);
414
8
			fprintf(fout, "\t%s%s *%s_val;\n", prefix, old, name);
415
8
			fprintf(fout, "} %s", name);
416
8
			break;
417
		case REL_POINTER:
418
28
			fprintf(fout, "%s%s *%s", prefix, old, name);
419
28
			break;
420
		case REL_VECTOR:
421
8
			fprintf(fout, "%s%s %s[%s]", prefix, old, name,
422
4
				def->def.ty.array_max);
423
4
			break;
424
		case REL_ALIAS:
425
			fprintf(fout, "%s%s %s", prefix, old, name);
426
			break;
427
		}
428
40
		fprintf(fout, ";\n");
429
40
	}
430
40
}
431
432
void
433
pdeclaration(name, dec, tab, separator)
434
	char *name;
435
	declaration *dec;
436
	int tab;
437
	char *separator;
438
{
439
1440
	char buf[8];	/* enough to hold "struct ", include NUL */
440
	char *prefix;
441
	char *type;
442
443
720
	if (streq(dec->type, "void"))
444
6
		return;
445
714
	tabify(fout, tab);
446

718
	if (streq(dec->type, name) && !dec->prefix) {
447
4
		fprintf(fout, "struct ");
448
4
	}
449
714
	if (streq(dec->type, "string")) {
450
44
		fprintf(fout, "char *%s", dec->name);
451
44
	} else {
452
		prefix = "";
453
670
		if (streq(dec->type, "bool")) {
454
			type = "bool_t";
455
670
		} else if (streq(dec->type, "opaque")) {
456
			type = "char";
457
22
		} else {
458
604
			if (dec->prefix) {
459
32
				snprintf(buf, sizeof buf, "%s ", dec->prefix);
460
				prefix = buf;
461
32
			}
462
604
			type = dec->type;
463
		}
464

1366
		switch (dec->rel) {
465
		case REL_ALIAS:
466
620
			fprintf(fout, "%s%s %s", prefix, type, dec->name);
467
620
			break;
468
		case REL_VECTOR:
469
68
			fprintf(fout, "%s%s %s[%s]", prefix, type, dec->name,
470
34
				dec->array_max);
471
34
			break;
472
		case REL_POINTER:
473
8
			fprintf(fout, "%s%s *%s", prefix, type, dec->name);
474
8
			break;
475
		case REL_ARRAY:
476
8
			fprintf(fout, "struct {\n");
477
8
			tabify(fout, tab);
478
8
			fprintf(fout, "\tu_int %s_len;\n", dec->name);
479
8
			tabify(fout, tab);
480
8
			fprintf(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
481
8
			tabify(fout, tab);
482
8
			fprintf(fout, "} %s", dec->name);
483
8
			break;
484
		}
485
	}
486
714
	fprintf(fout, "%s", separator);
487
1434
}
488
489
static int
490
undefined2(type, stop)
491
	char *type;
492
	char *stop;
493
{
494
	list *l;
495
	definition *def;
496
497
856
	for (l = defined; l != NULL; l = l->next) {
498
408
		def = (definition *) l->val;
499
408
		if (def->def_kind != DEF_PROGRAM) {
500
408
			if (streq(def->def_name, stop)) {
501
38
				return (1);
502
370
			} else if (streq(def->def_name, type)) {
503
2
				return (0);
504
			}
505
		}
506
	}
507
	return (1);
508
40
}