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