xref: /openbsd-src/usr.bin/rpcgen/rpc_util.c (revision 3a3fbb3f2e2521ab7c4a56b7ff7462ebd9095ec5)
1 /*	$OpenBSD: rpc_util.c,v 1.7 2001/12/05 09:50:31 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 #ifndef lint
34 static 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 __P((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) ();
100 
101 {
102 
103 	for (; lst != NULL; lst = lst->next) {
104 		if ((*cmp) (lst->val, val)) {
105 			return (lst->val);
106 		}
107 	}
108 	return (NULL);
109 }
110 
111 /*
112  * store a value in a list
113  */
114 void
115 storeval(lstp, val)
116 	list **lstp;
117 	definition *val;
118 {
119 	list **l;
120 	list *lst;
121 
122 	for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
123 	lst = ALLOC(list);
124 	lst->val = val;
125 	lst->next = NULL;
126 	*l = lst;
127 }
128 
129 static int
130 findit(def, type)
131 	definition *def;
132 	char *type;
133 {
134 	return (streq(def->def_name, type));
135 }
136 
137 static char *
138 fixit(type, orig)
139 	char *type;
140 	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 			f_print(fout, "enum ");
185 		} else {
186 			f_print(fout, "struct ");
187 		}
188 	}
189 	if (streq(type, "bool")) {
190 		f_print(fout, "bool_t ");
191 	} else if (streq(type, "string")) {
192 		f_print(fout, "char *");
193 	} else {
194 		f_print(fout, "%s ", follow ? fixtype(type) : type);
195 	}
196 }
197 
198 static int
199 typedefed(def, type)
200 	definition *def;
201 	char *type;
202 {
203 	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
204 		return (0);
205 	} else {
206 		return (streq(def->def_name, type));
207 	}
208 }
209 
210 int
211 isvectordef(type, rel)
212 	char *type;
213 	relation rel;
214 {
215 	definition *def;
216 
217 	for (;;) {
218 		switch (rel) {
219 		case REL_VECTOR:
220 			return (!streq(type, "string"));
221 		case REL_ARRAY:
222 			return (0);
223 		case REL_POINTER:
224 			return (0);
225 		case REL_ALIAS:
226 			def = (definition *) FINDVAL(defined, type, typedefed);
227 			if (def == NULL) {
228 				return (0);
229 			}
230 			type = def->def.ty.old_type;
231 			rel = def->def.ty.rel;
232 		}
233 	}
234 }
235 
236 char *
237 locase(str)
238 	char *str;
239 {
240 	char c;
241 	static char buf[100];
242 	char *p = buf;
243 
244 	while ((c = *str++)) {
245 		*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
246 	}
247 	*p = 0;
248 	return (buf);
249 }
250 
251 void
252 pvname_svc(pname, vnum)
253 	char *pname;
254 	char *vnum;
255 {
256 	f_print(fout, "%s_%s_svc", locase(pname), vnum);
257 }
258 
259 void
260 pvname(pname, vnum)
261 	char *pname;
262 	char *vnum;
263 {
264 	f_print(fout, "%s_%s", locase(pname), vnum);
265 }
266 
267 /*
268  * print a useful (?) error message, and then die
269  */
270 void
271 error(msg)
272 	char *msg;
273 {
274 	printwhere();
275 	f_print(stderr, "%s, line %d: ", infilename, linenum);
276 	f_print(stderr, "%s\n", msg);
277 	crash();
278 }
279 
280 /*
281  * Something went wrong, unlink any files that we may have created and then
282  * die.
283  */
284 void
285 crash()
286 {
287 	int i;
288 
289 	for (i = 0; i < nfiles; i++) {
290 		(void) unlink(outfiles[i]);
291 	}
292 	exit(1);
293 }
294 
295 void
296 record_open(file)
297 	char *file;
298 {
299 	if (nfiles < NFILES) {
300 		outfiles[nfiles++] = file;
301 	} else {
302 		f_print(stderr, "too many files!\n");
303 		crash();
304 	}
305 }
306 
307 static char expectbuf[100];
308 static char *toktostr();
309 
310 /*
311  * error, token encountered was not the expected one
312  */
313 void
314 expected1(exp1)
315 	tok_kind exp1;
316 {
317 	s_print(expectbuf, "expected '%s'",
318 		toktostr(exp1));
319 	error(expectbuf);
320 }
321 
322 /*
323  * error, token encountered was not one of two expected ones
324  */
325 void
326 expected2(exp1, exp2)
327 	tok_kind exp1, exp2;
328 {
329 	s_print(expectbuf, "expected '%s' or '%s'",
330 		toktostr(exp1),
331 		toktostr(exp2));
332 	error(expectbuf);
333 }
334 
335 /*
336  * error, token encountered was not one of 3 expected ones
337  */
338 void
339 expected3(exp1, exp2, exp3)
340 	tok_kind exp1, exp2, exp3;
341 {
342 	s_print(expectbuf, "expected '%s', '%s' or '%s'",
343 		toktostr(exp1),
344 		toktostr(exp2),
345 		toktostr(exp3));
346 	error(expectbuf);
347 }
348 
349 void
350 tabify(f, tab)
351 	FILE *f;
352 	int tab;
353 {
354 	while (tab--) {
355 		(void) fputc('\t', f);
356 	}
357 }
358 
359 static token tokstrings[] = {
360 	{TOK_IDENT, "identifier"},
361 	{TOK_CONST, "const"},
362 	{TOK_RPAREN, ")"},
363 	{TOK_LPAREN, "("},
364 	{TOK_RBRACE, "}"},
365 	{TOK_LBRACE, "{"},
366 	{TOK_LBRACKET, "["},
367 	{TOK_RBRACKET, "]"},
368 	{TOK_STAR, "*"},
369 	{TOK_COMMA, ","},
370 	{TOK_EQUAL, "="},
371 	{TOK_COLON, ":"},
372 	{TOK_SEMICOLON, ";"},
373 	{TOK_UNION, "union"},
374 	{TOK_STRUCT, "struct"},
375 	{TOK_SWITCH, "switch"},
376 	{TOK_CASE, "case"},
377 	{TOK_DEFAULT, "default"},
378 	{TOK_ENUM, "enum"},
379 	{TOK_TYPEDEF, "typedef"},
380 	{TOK_INT, "int"},
381 	{TOK_SHORT, "short"},
382 	{TOK_LONG, "long"},
383 	{TOK_UNSIGNED, "unsigned"},
384 	{TOK_DOUBLE, "double"},
385 	{TOK_FLOAT, "float"},
386 	{TOK_CHAR, "char"},
387 	{TOK_STRING, "string"},
388 	{TOK_OPAQUE, "opaque"},
389 	{TOK_BOOL, "bool"},
390 	{TOK_VOID, "void"},
391 	{TOK_PROGRAM, "program"},
392 	{TOK_VERSION, "version"},
393 	{TOK_EOF, "??????"}
394 };
395 
396 static char *
397 toktostr(kind)
398 	tok_kind kind;
399 {
400 	token *sp;
401 
402 	for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
403 	return (sp->str);
404 }
405 
406 static void
407 printbuf()
408 {
409 	char c;
410 	int i;
411 	int cnt;
412 
413 #	define TABSIZE 4
414 
415 	for (i = 0; (c = curline[i]); i++) {
416 		if (c == '\t') {
417 			cnt = 8 - (i % TABSIZE);
418 			c = ' ';
419 		} else {
420 			cnt = 1;
421 		}
422 		while (cnt--) {
423 			(void) fputc(c, stderr);
424 		}
425 	}
426 }
427 
428 static void
429 printwhere()
430 {
431 	int i;
432 	char c;
433 	int cnt;
434 
435 	printbuf();
436 	for (i = 0; i < where - curline; i++) {
437 		c = curline[i];
438 		if (c == '\t') {
439 			cnt = 8 - (i % TABSIZE);
440 		} else {
441 			cnt = 1;
442 		}
443 		while (cnt--) {
444 			(void) fputc('^', stderr);
445 		}
446 	}
447 	(void) fputc('\n', stderr);
448 }
449 
450 char *
451 make_argname(pname, vname)
452 	char *pname;
453 	char *vname;
454 {
455 	char *name;
456 
457 	name = (char *)malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
458 	if (!name) {
459 		fprintf(stderr, "failed in malloc");
460 		exit(1);
461 	}
462 	sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
463 	return(name);
464 }
465 
466 bas_type *typ_list_h;
467 bas_type *typ_list_t;
468 
469 void
470 add_type(len,type)
471 	int len;
472 	char *type;
473 {
474 	bas_type *ptr;
475 
476 	if ((ptr = (bas_type *)malloc(sizeof(bas_type))) == (bas_type *)NULL) {
477 		fprintf(stderr, "failed in malloc");
478 		exit(1);
479 	}
480 
481 	ptr->name=type;
482 	ptr->length=len;
483 	ptr->next=NULL;
484 	if (typ_list_t == NULL) {
485 		typ_list_t=ptr;
486 		typ_list_h=ptr;
487 	} else {
488 		typ_list_t->next=ptr;
489 		typ_list_t=ptr;
490 	}
491 }
492 
493 bas_type *
494 find_type(type)
495 	char *type;
496 {
497 	bas_type * ptr;
498 
499 	ptr = typ_list_h;
500 
501 	while (ptr != NULL) {
502 		if (strcmp(ptr->name,type) == 0)
503 			return(ptr);
504 		else
505 			ptr=ptr->next;
506 	}
507 	return(NULL);
508 }
509 
510