xref: /openbsd-src/usr.bin/rpcgen/rpc_util.c (revision 7bbe964f6b7d22ad07ca46292495604f942eba4e)
1 /*	$OpenBSD: rpc_util.c,v 1.14 2009/10/27 23:59:42 deraadt Exp $	*/
2 /*	$NetBSD: rpc_util.c,v 1.6 1995/08/29 23:05:57 cgd Exp $	*/
3 /*
4  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5  * unrestricted use provided that this legend is included on all tape
6  * media and as a part of the software program in whole or part.  Users
7  * may copy or modify Sun RPC without charge, but are not authorized
8  * to license or distribute it to anyone else except as part of a product or
9  * program developed by the user or with the express written consent of
10  * Sun Microsystems, Inc.
11  *
12  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
13  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
14  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
15  *
16  * Sun RPC is provided with no support and without any obligation on the
17  * part of Sun Microsystems, Inc. to assist in its use, correction,
18  * modification or enhancement.
19  *
20  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
21  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
22  * OR ANY PART THEREOF.
23  *
24  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
25  * or profits or other special, indirect and consequential damages, even if
26  * Sun has been advised of the possibility of such damages.
27  *
28  * Sun Microsystems, Inc.
29  * 2550 Garcia Avenue
30  * Mountain View, California  94043
31  */
32 
33 /*
34  * rpc_util.c, Utility routines for the RPC protocol compiler
35  */
36 #include <sys/cdefs.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <ctype.h>
41 #include <unistd.h>
42 #include "rpc_scan.h"
43 #include "rpc_parse.h"
44 #include "rpc_util.h"
45 
46 #define ARGEXT "argument"
47 
48 static void printwhere(void);
49 
50 char curline[MAXLINESIZE];	/* current read line */
51 char *where = curline;		/* current point in line */
52 int linenum = 0;		/* current line number */
53 
54 char *infilename;		/* input filename */
55 
56 #define NFILES 7
57 char *outfiles[NFILES];		/* output file names */
58 int nfiles;
59 
60 FILE *fout;			/* file pointer of current output */
61 FILE *fin;			/* file pointer of current input */
62 
63 list *defined;			/* list of defined things */
64 
65 /*
66  * Reinitialize the world
67  */
68 void
69 reinitialize()
70 {
71 	memset(curline, 0, MAXLINESIZE);
72 	where = curline;
73 	linenum = 0;
74 	defined = NULL;
75 }
76 
77 /*
78  * string equality
79  */
80 int
81 streq(a, b)
82 	char *a;
83 	char *b;
84 {
85 	return (strcmp(a, b) == 0);
86 }
87 
88 /*
89  * find a value in a list
90  */
91 definition *
92 findval(lst, val, cmp)
93 	list *lst;
94 	char *val;
95 	int (*cmp) (definition *, char *);
96 {
97 
98 	for (; lst != NULL; lst = lst->next) {
99 		if ((*cmp) (lst->val, val)) {
100 			return (lst->val);
101 		}
102 	}
103 	return (NULL);
104 }
105 
106 /*
107  * store a value in a list
108  */
109 void
110 storeval(lstp, val)
111 	list **lstp;
112 	definition *val;
113 {
114 	list **l;
115 	list *lst;
116 
117 	for (l = lstp; *l != NULL; l = (list **) & (*l)->next)
118 		;
119 	lst = ALLOC(list);
120 	if (lst == NULL) {
121 		fprintf(stderr, "failed in alloc\n");
122 		exit(1);
123 	}
124 	lst->val = val;
125 	lst->next = NULL;
126 	*l = lst;
127 }
128 
129 static int
130 findit(definition *def, char *type)
131 {
132 	return (streq(def->def_name, type));
133 }
134 
135 static char *
136 fixit(char *type, char *orig)
137 {
138 	definition *def;
139 
140 	def = (definition *) FINDVAL(defined, type, findit);
141 	if (def == NULL || def->def_kind != DEF_TYPEDEF) {
142 		return (orig);
143 	}
144 	switch (def->def.ty.rel) {
145 	case REL_VECTOR:
146 		return (def->def.ty.old_type);
147 	case REL_ALIAS:
148 		return (fixit(def->def.ty.old_type, orig));
149 	default:
150 		return (orig);
151 	}
152 }
153 
154 char *
155 fixtype(type)
156 	char *type;
157 {
158 	return (fixit(type, type));
159 }
160 
161 char *
162 stringfix(type)
163 	char *type;
164 {
165 	if (streq(type, "string")) {
166 		return ("wrapstring");
167 	} else {
168 		return (type);
169 	}
170 }
171 
172 void
173 ptype(prefix, type, follow)
174 	char *prefix;
175 	char *type;
176 	int follow;
177 {
178 	if (prefix != NULL) {
179 		if (streq(prefix, "enum")) {
180 			fprintf(fout, "enum ");
181 		} else {
182 			fprintf(fout, "struct ");
183 		}
184 	}
185 	if (streq(type, "bool")) {
186 		fprintf(fout, "bool_t ");
187 	} else if (streq(type, "string")) {
188 		fprintf(fout, "char *");
189 	} else {
190 		fprintf(fout, "%s ", follow ? fixtype(type) : type);
191 	}
192 }
193 
194 static int
195 typedefed(definition *def, char *type)
196 {
197 	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL)
198 		return (0);
199 	else
200 		return (streq(def->def_name, type));
201 }
202 
203 int
204 isvectordef(type, rel)
205 	char *type;
206 	relation rel;
207 {
208 	definition *def;
209 
210 	for (;;) {
211 		switch (rel) {
212 		case REL_VECTOR:
213 			return (!streq(type, "string"));
214 		case REL_ARRAY:
215 			return (0);
216 		case REL_POINTER:
217 			return (0);
218 		case REL_ALIAS:
219 			def = (definition *) FINDVAL(defined, type, typedefed);
220 			if (def == NULL)
221 				return (0);
222 			type = def->def.ty.old_type;
223 			rel = def->def.ty.rel;
224 		}
225 	}
226 }
227 
228 char *
229 locase(str)
230 	char *str;
231 {
232 	char c;
233 	static char buf[100];
234 	char *p = buf;
235 
236 	while ((c = *str++))
237 		*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
238 	*p = 0;
239 	return (buf);
240 }
241 
242 void
243 pvname_svc(pname, vnum)
244 	char *pname;
245 	char *vnum;
246 {
247 	fprintf(fout, "%s_%s_svc", locase(pname), vnum);
248 }
249 
250 void
251 pvname(pname, vnum)
252 	char *pname;
253 	char *vnum;
254 {
255 	fprintf(fout, "%s_%s", locase(pname), vnum);
256 }
257 
258 /*
259  * print a useful (?) error message, and then die
260  */
261 void
262 error(msg)
263 	char *msg;
264 {
265 	printwhere();
266 	fprintf(stderr, "%s, line %d: ", infilename, linenum);
267 	fprintf(stderr, "%s\n", msg);
268 	crash();
269 }
270 
271 /*
272  * Something went wrong, unlink any files that we may have created and then
273  * die.
274  */
275 void
276 crash()
277 {
278 	int i;
279 
280 	for (i = 0; i < nfiles; i++) {
281 		(void) unlink(outfiles[i]);
282 	}
283 	exit(1);
284 }
285 
286 void
287 record_open(file)
288 	char *file;
289 {
290 	if (nfiles < NFILES) {
291 		outfiles[nfiles++] = file;
292 	} else {
293 		fprintf(stderr, "too many files!\n");
294 		crash();
295 	}
296 }
297 
298 static char expectbuf[100];
299 static char *toktostr(tok_kind);
300 
301 /*
302  * error, token encountered was not the expected one
303  */
304 void
305 expected1(exp1)
306 	tok_kind exp1;
307 {
308 	snprintf(expectbuf, sizeof expectbuf, "expected '%s'",
309 	    toktostr(exp1));
310 	error(expectbuf);
311 }
312 
313 /*
314  * error, token encountered was not one of two expected ones
315  */
316 void
317 expected2(exp1, exp2)
318 	tok_kind exp1, exp2;
319 {
320 	snprintf(expectbuf, sizeof expectbuf, "expected '%s' or '%s'",
321 	    toktostr(exp1), toktostr(exp2));
322 	error(expectbuf);
323 }
324 
325 /*
326  * error, token encountered was not one of 3 expected ones
327  */
328 void
329 expected3(exp1, exp2, exp3)
330 	tok_kind exp1, exp2, exp3;
331 {
332 	snprintf(expectbuf, sizeof expectbuf, "expected '%s', '%s' or '%s'",
333 	    toktostr(exp1), toktostr(exp2), toktostr(exp3));
334 	error(expectbuf);
335 }
336 
337 void
338 tabify(f, tab)
339 	FILE *f;
340 	int tab;
341 {
342 	while (tab--) {
343 		(void) fputc('\t', f);
344 	}
345 }
346 
347 static token tokstrings[] = {
348 	{TOK_IDENT, "identifier"},
349 	{TOK_CONST, "const"},
350 	{TOK_RPAREN, ")"},
351 	{TOK_LPAREN, "("},
352 	{TOK_RBRACE, "}"},
353 	{TOK_LBRACE, "{"},
354 	{TOK_LBRACKET, "["},
355 	{TOK_RBRACKET, "]"},
356 	{TOK_STAR, "*"},
357 	{TOK_COMMA, ","},
358 	{TOK_EQUAL, "="},
359 	{TOK_COLON, ":"},
360 	{TOK_SEMICOLON, ";"},
361 	{TOK_UNION, "union"},
362 	{TOK_STRUCT, "struct"},
363 	{TOK_SWITCH, "switch"},
364 	{TOK_CASE, "case"},
365 	{TOK_DEFAULT, "default"},
366 	{TOK_ENUM, "enum"},
367 	{TOK_TYPEDEF, "typedef"},
368 	{TOK_INT, "int"},
369 	{TOK_SHORT, "short"},
370 	{TOK_LONG, "long"},
371 	{TOK_UNSIGNED, "unsigned"},
372 	{TOK_DOUBLE, "double"},
373 	{TOK_FLOAT, "float"},
374 	{TOK_CHAR, "char"},
375 	{TOK_STRING, "string"},
376 	{TOK_OPAQUE, "opaque"},
377 	{TOK_BOOL, "bool"},
378 	{TOK_VOID, "void"},
379 	{TOK_PROGRAM, "program"},
380 	{TOK_VERSION, "version"},
381 	{TOK_EOF, "??????"}
382 };
383 
384 static char *
385 toktostr(tok_kind kind)
386 {
387 	token *sp;
388 
389 	for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++)
390 		;
391 	return (sp->str);
392 }
393 
394 static void
395 printbuf(void)
396 {
397 	char c;
398 	int i;
399 	int cnt;
400 
401 #	define TABSIZE 4
402 
403 	for (i = 0; (c = curline[i]); i++) {
404 		if (c == '\t') {
405 			cnt = 8 - (i % TABSIZE);
406 			c = ' ';
407 		} else {
408 			cnt = 1;
409 		}
410 		while (cnt--) {
411 			(void) fputc(c, stderr);
412 		}
413 	}
414 }
415 
416 static void
417 printwhere()
418 {
419 	int i;
420 	char c;
421 	int cnt;
422 
423 	printbuf();
424 	for (i = 0; i < where - curline; i++) {
425 		c = curline[i];
426 		if (c == '\t') {
427 			cnt = 8 - (i % TABSIZE);
428 		} else {
429 			cnt = 1;
430 		}
431 		while (cnt--) {
432 			(void) fputc('^', stderr);
433 		}
434 	}
435 	(void) fputc('\n', stderr);
436 }
437 
438 char *
439 make_argname(pname, vname)
440 	char *pname;
441 	char *vname;
442 {
443 	char *name;
444 	int len = strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3;
445 
446 	name = (char *)malloc(len);
447 	if (!name) {
448 		fprintf(stderr, "failed in malloc\n");
449 		exit(1);
450 	}
451 	snprintf(name, len, "%s_%s_%s", locase(pname), vname, ARGEXT);
452 	return(name);
453 }
454 
455 bas_type *typ_list_h;
456 bas_type *typ_list_t;
457 
458 void
459 add_type(len, type)
460 	int len;
461 	char *type;
462 {
463 	bas_type *ptr;
464 
465 	if ((ptr = (bas_type *)malloc(sizeof(bas_type))) == (bas_type *)NULL) {
466 		fprintf(stderr, "failed in malloc\n");
467 		exit(1);
468 	}
469 
470 	ptr->name = type;
471 	ptr->length = len;
472 	ptr->next = NULL;
473 	if (typ_list_t == NULL) {
474 		typ_list_t = ptr;
475 		typ_list_h = ptr;
476 	} else {
477 		typ_list_t->next = ptr;
478 		typ_list_t = ptr;
479 	}
480 }
481 
482 bas_type *
483 find_type(type)
484 	char *type;
485 {
486 	bas_type * ptr;
487 
488 	ptr = typ_list_h;
489 
490 	while (ptr != NULL) {
491 		if (strcmp(ptr->name, type) == 0)
492 			return(ptr);
493 		else
494 			ptr = ptr->next;
495 	}
496 	return(NULL);
497 }
498 
499