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