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