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