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