GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/rpcgen/rpc_hout.c Lines: 149 220 67.7 %
Date: 2016-12-06 Branches: 69 133 51.9 %

Line Branch Exec Source
1
/*	$OpenBSD: rpc_hout.c,v 1.21 2012/12/05 23:20:26 deraadt 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
33
{
67
68
33
	if (def->def_kind == DEF_PROGRAM)  /* handle data only */
69
1
		return;
70
71
32
	if (def->def_kind != DEF_CONST)
72
32
		fprintf(fout, "\n");
73

32
	switch (def->def_kind) {
74
	case DEF_STRUCT:
75
26
		pstructdef(def);
76
26
		break;
77
	case DEF_UNION:
78
2
		puniondef(def);
79
2
		break;
80
	case DEF_ENUM:
81
4
		penumdef(def);
82
4
		break;
83
	case DEF_TYPEDEF:
84
		ptypedef(def);
85
		break;
86
	case DEF_PROGRAM:
87
		pprogramdef(def);
88
		break;
89
	case DEF_CONST:
90
		pconstdef(def);
91
		break;
92
	}
93
32
	if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
94

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

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

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

156
	if (proc->arg_num < 2 && newstyle &&
337
	   streq(proc->args.decls->decl.type, "void")) {
338
		/* 0 argument in new style:  do nothing */
339
	} else {
340
312
		for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
341
156
			ptype(dl->decl.prefix, dl->decl.type, 1);
342
156
			if (!newstyle)
343
156
				fprintf(fout, "*"); /* old style passes by reference */
344
156
			fprintf(fout, ", ");
345
		}
346
	}
347
156
	fprintf(fout, "%s);\n", addargtype);
348
156
}
349
350
static void
351
penumdef(def)
352
	definition *def;
353
4
{
354
4
	char *name = def->def_name;
355
	enumval_list *l;
356
4
	char *last = NULL;
357
4
	int count = 0;
358
359
4
	fprintf(fout, "enum %s {\n", name);
360
27
	for (l = def->def.en.vals; l != NULL; l = l->next) {
361
23
		fprintf(fout, "\t%s", l->name);
362
23
		if (l->assignment) {
363
23
			fprintf(fout, " = %s", l->assignment);
364
23
			last = l->assignment;
365
23
			count = 1;
366
		} else {
367
			if (last == NULL) {
368
				fprintf(fout, " = %d", count++);
369
			} else {
370
				fprintf(fout, " = %s + %d", last, count++);
371
			}
372
		}
373
23
		if (l->next)
374
19
			fprintf(fout, ",\n");
375
		else
376
4
			fprintf(fout, "\n");
377
	}
378
4
	fprintf(fout, "};\n");
379
4
	fprintf(fout, "typedef enum %s %s;\n", name, name);
380
4
}
381
382
static void
383
ptypedef(def)
384
	definition *def;
385
{
386
	char *name = def->def_name;
387
	char *old = def->def.ty.old_type;
388
	char prefix[8];	/* enough to contain "struct ", including NUL */
389
	relation rel = def->def.ty.rel;
390
391
	if (!streq(name, old)) {
392
		if (streq(old, "string")) {
393
			old = "char";
394
			rel = REL_POINTER;
395
		} else if (streq(old, "opaque")) {
396
			old = "char";
397
		} else if (streq(old, "bool")) {
398
			old = "bool_t";
399
		}
400
		if (undefined2(old, name) && def->def.ty.old_prefix) {
401
			snprintf(prefix, sizeof prefix, "%s ", def->def.ty.old_prefix);
402
		} else {
403
			prefix[0] = 0;
404
		}
405
		fprintf(fout, "typedef ");
406
		switch (rel) {
407
		case REL_ARRAY:
408
			fprintf(fout, "struct {\n");
409
			fprintf(fout, "\tu_int %s_len;\n", name);
410
			fprintf(fout, "\t%s%s *%s_val;\n", prefix, old, name);
411
			fprintf(fout, "} %s", name);
412
			break;
413
		case REL_POINTER:
414
			fprintf(fout, "%s%s *%s", prefix, old, name);
415
			break;
416
		case REL_VECTOR:
417
			fprintf(fout, "%s%s %s[%s]", prefix, old, name,
418
				def->def.ty.array_max);
419
			break;
420
		case REL_ALIAS:
421
			fprintf(fout, "%s%s %s", prefix, old, name);
422
			break;
423
		}
424
		fprintf(fout, ";\n");
425
	}
426
}
427
428
void
429
pdeclaration(name, dec, tab, separator)
430
	char *name;
431
	declaration *dec;
432
	int tab;
433
	char *separator;
434
91
{
435
	char buf[8];	/* enough to hold "struct ", include NUL */
436
	char *prefix;
437
	char *type;
438
439
91
	if (streq(dec->type, "void"))
440
		return;
441
91
	tabify(fout, tab);
442

91
	if (streq(dec->type, name) && !dec->prefix) {
443
		fprintf(fout, "struct ");
444
	}
445
91
	if (streq(dec->type, "string")) {
446
6
		fprintf(fout, "char *%s", dec->name);
447
	} else {
448
85
		prefix = "";
449
85
		if (streq(dec->type, "bool")) {
450
16
			type = "bool_t";
451
69
		} else if (streq(dec->type, "opaque")) {
452
1
			type = "char";
453
		} else {
454
68
			if (dec->prefix) {
455
10
				snprintf(buf, sizeof buf, "%s ", dec->prefix);
456
10
				prefix = buf;
457
			}
458
68
			type = dec->type;
459
		}
460

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