GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/rpcgen/rpc_hout.c Lines: 199 224 88.8 %
Date: 2017-11-13 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
582
	if (def->def_kind == DEF_PROGRAM)  /* handle data only */
69
		return;
70
71
275
	if (def->def_kind != DEF_CONST)
72
145
		fprintf(fout, "\n");
73

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

550
	if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
96
290
		pxdrfuncdecl(def->def_name,
97
310
		    def->def_kind != DEF_TYPEDEF ||
98
20
		    !isvectordef(def->def.ty.old_type, def->def.ty.rel));
99
145
	}
100
291
}
101
102
103
void
104
print_funcdef(def)
105
	definition *def;
106
{
107
582
	switch (def->def_kind) {
108
	case DEF_PROGRAM:
109
16
		fprintf(fout, "\n");
110
16
		pprogramdef(def);
111
16
		break;
112
	default:
113
		break;
114
	}
115
291
}
116
117
void
118
pxdrfuncdecl(name, pointerp)
119
	char *name;
120
	int pointerp;
121
{
122
123
290
	fprintf(fout,"#ifdef __cplusplus\n");
124
290
	fprintf(fout, "extern \"C\" bool_t xdr_%s(XDR *, %s %s);\n",
125
145
	    name, name, pointerp ? ("*") : "");
126
145
	fprintf(fout,"#elif defined(__STDC__)\n");
127
145
	fprintf(fout, "extern bool_t xdr_%s(XDR *, %s %s);\n",
128
	    name, name, pointerp ? ("*") : "");
129
145
	fprintf(fout,"#else /* Old Style C */\n");
130
145
	fprintf(fout, "bool_t xdr_%s();\n", name);
131
145
	fprintf(fout,"#endif /* Old Style C */\n\n");
132
145
}
133
134
135
static void
136
pconstdef(def)
137
	definition *def;
138
{
139
260
	pdefine(def->def_name, def->def.co);
140
130
}
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
90
	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
156
270
		for (plist = vers->procs; plist != NULL;
157
114
		    plist = plist->next) {
158

114
			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
16
}
174
175
static void
176
pstructdef(def)
177
	definition *def;
178
{
179
196
	char *name = def->def_name;
180
	decl_list *l;
181
182
98
	fprintf(fout, "struct %s {\n", name);
183
880
	for (l = def->def.st.decls; l != NULL; l = l->next)
184
342
		pdeclaration(name, &l->decl, 1, ";\n");
185
98
	fprintf(fout, "};\n");
186
98
	fprintf(fout, "typedef struct %s %s;\n", name, name);
187
98
}
188
189
static void
190
puniondef(def)
191
	definition *def;
192
{
193
	case_list *l;
194
28
	char *name = def->def_name;
195
	declaration *decl;
196
197
14
	fprintf(fout, "struct %s {\n", name);
198
14
	decl = &def->def.un.enum_decl;
199
14
	if (streq(decl->type, "bool")) {
200
1
		fprintf(fout, "\tbool_t %s;\n", decl->name);
201
1
	} else {
202
13
		fprintf(fout, "\t%s %s;\n", decl->type, decl->name);
203
	}
204
14
	fprintf(fout, "\tunion {\n");
205
64
	for (l = def->def.un.cases; l != NULL; l = l->next) {
206
18
	  if (l->contflag == 0)
207
18
		pdeclaration(name, &l->case_decl, 2, ";\n");
208
	}
209
14
	decl = def->def.un.default_decl;
210

24
	if (decl && !streq(decl->type, "void")) {
211
		pdeclaration(name, decl, 2, ";\n");
212
	}
213
14
	fprintf(fout, "\t} %s_u;\n", name);
214
14
	fprintf(fout, "};\n");
215
14
	fprintf(fout, "typedef struct %s %s;\n", name, name);
216
14
}
217
218
static void
219
pdefine(name, num)
220
	char *name;
221
	char *num;
222
{
223
260
	fprintf(fout, "#define %s %s\n", name, num);
224
130
}
225
226
static void
227
puldefine(name, num)
228
	char *name;
229
	char *num;
230
{
231
734
	fprintf(fout, "#define %s ((u_long)%s)\n", name, num);
232
367
}
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
1506
	for (vers = start; vers != NULL; vers = vers->next) {
243
7326
		for (proc = vers->procs; proc != NULL; proc = proc->next) {
244
3423
			if (proc == stop) {
245
330
				return (0);
246
3093
			} else if (streq(proc->proc_name, stop->proc_name)) {
247
12
				return (1);
248
			}
249
		}
250
	}
251
	abort();
252
	/* NOTREACHED */
253
342
}
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
32
	pargdef(def);
265
266
16
	puldefine(def->def_name, def->def.pr.prog_num);
267
74
	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
268
21
		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
21
		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
168
		for (i=0; i<3; i++) {
281
63
			if (i==0) {
282
21
				fprintf(fout,"\n#ifdef __cplusplus\n");
283
				ext = "extern \"C\" ";
284
63
			} else if (i==1) {
285
21
				fprintf(fout,"\n#elif defined(__STDC__)\n");
286
				ext = "extern ";
287
21
			} else {
288
21
				fprintf(fout,"\n#else /* Old Style C */\n");
289
				ext = "extern ";
290
			}
291
292
810
			for (proc = vers->procs; proc != NULL; proc = proc->next) {
293
342
				if (!define_printed(proc, def->def.pr.versions))
294
330
					puldefine(proc->proc_name, proc->proc_num);
295
342
				fprintf(fout,"%s",ext);
296
342
				pprocdef(proc, vers, "CLIENT *", 0,i);
297
342
				fprintf(fout,"%s",ext);
298
342
				pprocdef(proc, vers, "struct svc_req *", 1,i);
299
			}
300
		}
301
21
		fprintf(fout,"#endif /* Old Style C */\n");
302
	}
303
16
}
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
1368
	ptype(proc->res_prefix, proc->res_type, 1);
315
684
	fprintf(fout, "* ");
316
684
	if (server_p)
317
342
		pvname_svc(proc->proc_name, vp->vers_num);
318
	else
319
342
		pvname(proc->proc_name, vp->vers_num);
320
321
	/*
322
	 * mode  0 == cplusplus, mode  1 = ANSI-C, mode 2 = old style C
323
	 */
324
684
	if (mode == 0 || mode == 1)
325
456
		parglist(proc, addargtype);
326
	else
327
228
		fprintf(fout, "();\n");
328
684
}
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
912
	fprintf(fout,"(");
339
340

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

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

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

359
	if (streq(dec->type, name) && !dec->prefix) {
447
2
		fprintf(fout, "struct ");
448
2
	}
449
357
	if (streq(dec->type, "string")) {
450
22
		fprintf(fout, "char *%s", dec->name);
451
22
	} else {
452
		prefix = "";
453
335
		if (streq(dec->type, "bool")) {
454
			type = "bool_t";
455
335
		} else if (streq(dec->type, "opaque")) {
456
			type = "char";
457
11
		} else {
458
302
			if (dec->prefix) {
459
16
				snprintf(buf, sizeof buf, "%s ", dec->prefix);
460
				prefix = buf;
461
16
			}
462
302
			type = dec->type;
463
		}
464

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