GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/rpcgen/rpc_util.c Lines: 85 137 62.0 %
Date: 2017-11-07 Branches: 48 76 63.2 %

Line Branch Exec Source
1
/*	$OpenBSD: rpc_util.c,v 1.17 2015/08/20 22:32:41 deraadt Exp $	*/
2
/*	$NetBSD: rpc_util.c,v 1.6 1995/08/29 23:05:57 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_util.c, Utility routines for the RPC protocol compiler
37
 */
38
#include <stdio.h>
39
#include <stdlib.h>
40
#include <string.h>
41
#include <ctype.h>
42
#include <unistd.h>
43
#include "rpc_scan.h"
44
#include "rpc_parse.h"
45
#include "rpc_util.h"
46
47
#define ARGEXT "argument"
48
49
static void printwhere(void);
50
51
char curline[MAXLINESIZE];	/* current read line */
52
char *where = curline;		/* current point in line */
53
int linenum = 0;		/* current line number */
54
55
char *infilename;		/* input filename */
56
57
#define NFILES 7
58
char *outfiles[NFILES];		/* output file names */
59
int nfiles;
60
61
FILE *fout;			/* file pointer of current output */
62
FILE *fin;			/* file pointer of current input */
63
64
list *defined;			/* list of defined things */
65
66
/*
67
 * Reinitialize the world
68
 */
69
void
70
reinitialize()
71
{
72
	memset(curline, 0, MAXLINESIZE);
73
	where = curline;
74
	linenum = 0;
75
	defined = NULL;
76
}
77
78
/*
79
 * string equality
80
 */
81
int
82
streq(a, b)
83
	char *a;
84
	char *b;
85
{
86
143084
	return (strcmp(a, b) == 0);
87
}
88
89
/*
90
 * find a value in a list
91
 */
92
definition *
93
findval(lst, val, cmp)
94
	list *lst;
95
	char *val;
96
	int (*cmp) (definition *, char *);
97
{
98
99
132916
	for (; lst != NULL; lst = lst->next) {
100
63062
		if ((*cmp) (lst->val, val)) {
101
1572
			return (lst->val);
102
		}
103
	}
104
1740
	return (NULL);
105
3312
}
106
107
/*
108
 * store a value in a list
109
 */
110
void
111
storeval(lstp, val)
112
	list **lstp;
113
	definition *val;
114
{
115
	list **l;
116
	list *lst;
117
118
56084
	for (l = lstp; *l != NULL; l = (list **) & (*l)->next)
119
		;
120
1164
	lst = malloc(sizeof(list));
121
1164
	if (lst == NULL) {
122
		fprintf(stderr, "failed in alloc\n");
123
		exit(1);
124
	}
125
1164
	lst->val = val;
126
1164
	lst->next = NULL;
127
1164
	*l = lst;
128
1164
}
129
130
static int
131
findit(definition *def, char *type)
132
{
133
95400
	return (streq(def->def_name, type));
134
}
135
136
static char *
137
fixit(char *type, char *orig)
138
{
139
	definition *def;
140
141
4496
	def = (definition *) FINDVAL(defined, type, findit);
142

3716
	if (def == NULL || def->def_kind != DEF_TYPEDEF) {
143
2132
		return (orig);
144
	}
145
116
	switch (def->def.ty.rel) {
146
	case REL_VECTOR:
147
		return (def->def.ty.old_type);
148
	case REL_ALIAS:
149
		return (fixit(def->def.ty.old_type, orig));
150
	default:
151
116
		return (orig);
152
	}
153
2248
}
154
155
char *
156
fixtype(type)
157
	char *type;
158
{
159
4496
	return (fixit(type, type));
160
}
161
162
char *
163
stringfix(type)
164
	char *type;
165
{
166
	if (streq(type, "string")) {
167
		return ("wrapstring");
168
	} else {
169
		return (type);
170
	}
171
}
172
173
void
174
ptype(prefix, type, follow)
175
	char *prefix;
176
	char *type;
177
	int follow;
178
{
179
4560
	if (prefix != NULL) {
180
208
		if (streq(prefix, "enum")) {
181
			fprintf(fout, "enum ");
182
		} else {
183
208
			fprintf(fout, "struct ");
184
		}
185
	}
186
2280
	if (streq(type, "bool")) {
187
24
		fprintf(fout, "bool_t ");
188
2280
	} else if (streq(type, "string")) {
189
8
		fprintf(fout, "char *");
190
8
	} else {
191
6744
		fprintf(fout, "%s ", follow ? fixtype(type) : type);
192
	}
193
2280
}
194
195
static int
196
typedefed(definition *def, char *type)
197
{
198

30384
	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL)
199
13998
		return (0);
200
	else
201
790
		return (streq(def->def_name, type));
202
14788
}
203
204
int
205
isvectordef(type, rel)
206
	char *type;
207
	relation rel;
208
{
209
	definition *def;
210
211
2412
	for (;;) {
212

2536
		switch (rel) {
213
		case REL_VECTOR:
214
80
			return (!streq(type, "string"));
215
		case REL_ARRAY:
216
200
			return (0);
217
		case REL_POINTER:
218
20
			return (0);
219
		case REL_ALIAS:
220
988
			def = (definition *) FINDVAL(defined, type, typedefed);
221
988
			if (def == NULL)
222
906
				return (0);
223
82
			type = def->def.ty.old_type;
224
82
			rel = def->def.ty.rel;
225
82
		}
226
	}
227
1206
}
228
229
char *
230
locase(str)
231
	char *str;
232
{
233
	char c;
234
	static char buf[100];
235
	char *p = buf;
236
237
54560
	while ((c = *str++))
238

97872
		*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
239
1824
	*p = 0;
240
1824
	return (buf);
241
}
242
243
void
244
pvname_svc(pname, vnum)
245
	char *pname;
246
	char *vnum;
247
{
248
1368
	fprintf(fout, "%s_%s_svc", locase(pname), vnum);
249
684
}
250
251
void
252
pvname(pname, vnum)
253
	char *pname;
254
	char *vnum;
255
{
256
1368
	fprintf(fout, "%s_%s", locase(pname), vnum);
257
684
}
258
259
/*
260
 * print a useful (?) error message, and then die
261
 */
262
void
263
error(msg)
264
	char *msg;
265
{
266
	printwhere();
267
	fprintf(stderr, "%s, line %d: ", infilename, linenum);
268
	fprintf(stderr, "%s\n", msg);
269
	crash();
270
}
271
272
/*
273
 * Something went wrong, unlink any files that we may have created and then
274
 * die.
275
 */
276
void
277
crash()
278
{
279
	int i;
280
281
	for (i = 0; i < nfiles; i++) {
282
		(void) unlink(outfiles[i]);
283
	}
284
	exit(1);
285
}
286
287
void
288
record_open(file)
289
	char *file;
290
{
291
120
	if (nfiles < NFILES) {
292
60
		outfiles[nfiles++] = file;
293
60
	} else {
294
		fprintf(stderr, "too many files!\n");
295
		crash();
296
	}
297
60
}
298
299
static char expectbuf[100];
300
static char *toktostr(tok_kind);
301
302
/*
303
 * error, token encountered was not the expected one
304
 */
305
void
306
expected1(exp1)
307
	tok_kind exp1;
308
{
309
	snprintf(expectbuf, sizeof expectbuf, "expected '%s'",
310
	    toktostr(exp1));
311
	error(expectbuf);
312
}
313
314
/*
315
 * error, token encountered was not one of two expected ones
316
 */
317
void
318
expected2(exp1, exp2)
319
	tok_kind exp1, exp2;
320
{
321
	snprintf(expectbuf, sizeof expectbuf, "expected '%s' or '%s'",
322
	    toktostr(exp1), toktostr(exp2));
323
	error(expectbuf);
324
}
325
326
/*
327
 * error, token encountered was not one of 3 expected ones
328
 */
329
void
330
expected3(exp1, exp2, exp3)
331
	tok_kind exp1, exp2, exp3;
332
{
333
	snprintf(expectbuf, sizeof expectbuf, "expected '%s', '%s' or '%s'",
334
	    toktostr(exp1), toktostr(exp2), toktostr(exp3));
335
	error(expectbuf);
336
}
337
338
void
339
tabify(f, tab)
340
	FILE *f;
341
	int tab;
342
{
343
18942
	while (tab--) {
344
4716
		(void) fputc('\t', f);
345
	}
346
3170
}
347
348
static token tokstrings[] = {
349
	{TOK_IDENT, "identifier"},
350
	{TOK_CONST, "const"},
351
	{TOK_RPAREN, ")"},
352
	{TOK_LPAREN, "("},
353
	{TOK_RBRACE, "}"},
354
	{TOK_LBRACE, "{"},
355
	{TOK_LBRACKET, "["},
356
	{TOK_RBRACKET, "]"},
357
	{TOK_STAR, "*"},
358
	{TOK_COMMA, ","},
359
	{TOK_EQUAL, "="},
360
	{TOK_COLON, ":"},
361
	{TOK_SEMICOLON, ";"},
362
	{TOK_UNION, "union"},
363
	{TOK_STRUCT, "struct"},
364
	{TOK_SWITCH, "switch"},
365
	{TOK_CASE, "case"},
366
	{TOK_DEFAULT, "default"},
367
	{TOK_ENUM, "enum"},
368
	{TOK_TYPEDEF, "typedef"},
369
	{TOK_INT, "int"},
370
	{TOK_SHORT, "short"},
371
	{TOK_LONG, "long"},
372
	{TOK_UNSIGNED, "unsigned"},
373
	{TOK_DOUBLE, "double"},
374
	{TOK_FLOAT, "float"},
375
	{TOK_CHAR, "char"},
376
	{TOK_STRING, "string"},
377
	{TOK_OPAQUE, "opaque"},
378
	{TOK_BOOL, "bool"},
379
	{TOK_VOID, "void"},
380
	{TOK_PROGRAM, "program"},
381
	{TOK_VERSION, "version"},
382
	{TOK_EOF, "??????"}
383
};
384
385
static char *
386
toktostr(tok_kind kind)
387
{
388
	token *sp;
389
390
	for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++)
391
		;
392
	return (sp->str);
393
}
394
395
static void
396
printbuf(void)
397
{
398
	char c;
399
	int i;
400
	int cnt;
401
402
#	define TABSIZE 4
403
404
	for (i = 0; (c = curline[i]); i++) {
405
		if (c == '\t') {
406
			cnt = 8 - (i % TABSIZE);
407
			c = ' ';
408
		} else {
409
			cnt = 1;
410
		}
411
		while (cnt--) {
412
			(void) fputc(c, stderr);
413
		}
414
	}
415
}
416
417
static void
418
printwhere()
419
{
420
	int i;
421
	char c;
422
	int cnt;
423
424
	printbuf();
425
	for (i = 0; i < where - curline; i++) {
426
		c = curline[i];
427
		if (c == '\t') {
428
			cnt = 8 - (i % TABSIZE);
429
		} else {
430
			cnt = 1;
431
		}
432
		while (cnt--) {
433
			(void) fputc('^', stderr);
434
		}
435
	}
436
	(void) fputc('\n', stderr);
437
}
438
439
char *
440
make_argname(pname, vname)
441
	char *pname;
442
	char *vname;
443
{
444
	char *name;
445
912
	int len = strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3;
446
447
456
	name = malloc(len);
448
456
	if (!name) {
449
		fprintf(stderr, "failed in malloc\n");
450
		exit(1);
451
	}
452
456
	snprintf(name, len, "%s_%s_%s", locase(pname), vname, ARGEXT);
453
456
	return(name);
454
}
455
456
bas_type *typ_list_h;
457
bas_type *typ_list_t;
458
459
void
460
add_type(len, type)
461
	int len;
462
	char *type;
463
{
464
	bas_type *ptr;
465
466
420
	if ((ptr = malloc(sizeof(bas_type))) == (bas_type *)NULL) {
467
		fprintf(stderr, "failed in malloc\n");
468
		exit(1);
469
	}
470
471
210
	ptr->name = type;
472
210
	ptr->length = len;
473
210
	ptr->next = NULL;
474
210
	if (typ_list_t == NULL) {
475
30
		typ_list_t = ptr;
476
30
		typ_list_h = ptr;
477
30
	} else {
478
180
		typ_list_t->next = ptr;
479
180
		typ_list_t = ptr;
480
	}
481
210
}
482
483
bas_type *
484
find_type(type)
485
	char *type;
486
{
487
	bas_type * ptr;
488
489
1912
	ptr = typ_list_h;
490
491
10600
	while (ptr != NULL) {
492
4904
		if (strcmp(ptr->name, type) == 0)
493
560
			return(ptr);
494
		else
495
4344
			ptr = ptr->next;
496
	}
497
396
	return(NULL);
498
956
}
499