xref: /freebsd/usr.bin/rpcgen/rpc_util.c (revision e627b39baccd1ec9129690167cf5e6d860509655)
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 #ident	"@(#)rpc_util.c	1.14	93/07/05 SMI"
31 
32 #ifndef lint
33 static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
34 #endif
35 
36 /*
37  * rpc_util.c, Utility routines for the RPC protocol compiler
38  * Copyright (C) 1989, Sun Microsystems, Inc.
39  */
40 #include <stdio.h>
41 #include <string.h>
42 #include <ctype.h>
43 #include <unistd.h>
44 #include "rpc_scan.h"
45 #include "rpc_parse.h"
46 #include "rpc_util.h"
47 
48 #define	ARGEXT "argument"
49 
50 char curline[MAXLINESIZE];	/* current read line */
51 char *where = curline;		/* current point in line */
52 int linenum = 0;		/* current line number */
53 
54 char *infilename;		/* input filename */
55 
56 #define	NFILES   7
57 char *outfiles[NFILES];		/* output file names */
58 int nfiles;
59 
60 FILE *fout;			/* file pointer of current output */
61 FILE *fin;			/* file pointer of current input */
62 
63 list *defined;			/* list of defined things */
64 
65 static void printwhere __P(( void ));
66 
67 /*
68  * Reinitialize the world
69  */
70 void
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 int
83 streq(a, b)
84 	char *a;
85 	char *b;
86 {
87 	return (strcmp(a, b) == 0);
88 }
89 
90 /*
91  * find a value in a list
92  */
93 definition *
94 findval(lst, val, cmp)
95 	list *lst;
96 	char *val;
97 	int (*cmp) ();
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 	for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
120 	lst = ALLOC(list);
121 	lst->val = val;
122 	lst->next = NULL;
123 	*l = lst;
124 }
125 
126 static int
127 findit(def, type)
128 	definition *def;
129 	char *type;
130 {
131 	return (streq(def->def_name, type));
132 }
133 
134 static char *
135 fixit(type, orig)
136 	char *type;
137 	char *orig;
138 {
139 	definition *def;
140 
141 	def = (definition *) FINDVAL(defined, type, findit);
142 	if (def == NULL || def->def_kind != DEF_TYPEDEF) {
143 		return (orig);
144 	}
145 	switch (def->def.ty.rel) {
146 	case REL_VECTOR:
147 		if (streq(def->def.ty.old_type, "opaque"))
148 			return ("char");
149 		else
150 			return (def->def.ty.old_type);
151 
152 	case REL_ALIAS:
153 		return (fixit(def->def.ty.old_type, orig));
154 	default:
155 		return (orig);
156 	}
157 }
158 
159 char *
160 fixtype(type)
161 	char *type;
162 {
163 	return (fixit(type, type));
164 }
165 
166 char *
167 stringfix(type)
168 	char *type;
169 {
170 	if (streq(type, "string")) {
171 		return ("wrapstring");
172 	} else {
173 		return (type);
174 	}
175 }
176 
177 void
178 ptype(prefix, type, follow)
179 	char *prefix;
180 	char *type;
181 	int follow;
182 {
183 	if (prefix != NULL) {
184 		if (streq(prefix, "enum")) {
185 			f_print(fout, "enum ");
186 		} else {
187 			f_print(fout, "struct ");
188 		}
189 	}
190 	if (streq(type, "bool")) {
191 		f_print(fout, "bool_t ");
192 	} else if (streq(type, "string")) {
193 		f_print(fout, "char *");
194 	} else {
195 		f_print(fout, "%s ", follow ? fixtype(type) : type);
196 	}
197 }
198 
199 static int
200 typedefed(def, type)
201 	definition *def;
202 	char *type;
203 {
204 	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
205 		return (0);
206 	} else {
207 		return (streq(def->def_name, type));
208 	}
209 }
210 
211 int
212 isvectordef(type, rel)
213 	char *type;
214 	relation rel;
215 {
216 	definition *def;
217 
218 	for (;;) {
219 		switch (rel) {
220 		case REL_VECTOR:
221 			return (!streq(type, "string"));
222 		case REL_ARRAY:
223 			return (0);
224 		case REL_POINTER:
225 			return (0);
226 		case REL_ALIAS:
227 			def = (definition *) FINDVAL(defined, type, typedefed);
228 			if (def == NULL) {
229 				return (0);
230 			}
231 			type = def->def.ty.old_type;
232 			rel = def->def.ty.rel;
233 		}
234 	}
235 
236 	return (0);
237 }
238 
239 char *
240 locase(str)
241 	char *str;
242 {
243 	char c;
244 	static char buf[100];
245 	char *p = buf;
246 
247 	while ( (c = *str++) ) {
248 		*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
249 	}
250 	*p = 0;
251 	return (buf);
252 }
253 
254 void
255 pvname_svc(pname, vnum)
256 	char *pname;
257 	char *vnum;
258 {
259 	f_print(fout, "%s_%s_svc", locase(pname), vnum);
260 }
261 
262 void
263 pvname(pname, vnum)
264 	char *pname;
265 	char *vnum;
266 {
267 	f_print(fout, "%s_%s", locase(pname), vnum);
268 }
269 
270 /*
271  * print a useful (?) error message, and then die
272  */
273 void
274 error(msg)
275 	char *msg;
276 {
277 	printwhere();
278 	f_print(stderr, "%s, line %d: ", infilename, linenum);
279 	f_print(stderr, "%s\n", 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 		f_print(stderr, "too many files!\n");
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 		fprintf(stderr, "failed in malloc");
464 		exit(1);
465 	}
466 	sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
467 	return (name);
468 }
469 
470 bas_type *typ_list_h;
471 bas_type *typ_list_t;
472 
473 void
474 add_type(len, type)
475 int len;
476 char *type;
477 {
478 	bas_type *ptr;
479 
480 	if ((ptr = (bas_type *) malloc(sizeof (bas_type))) ==
481 	    (bas_type *)NULL) {
482 		fprintf(stderr, "failed in malloc");
483 		exit(1);
484 	}
485 
486 	ptr->name = type;
487 	ptr->length = len;
488 	ptr->next = NULL;
489 	if (typ_list_t == NULL)
490 	{
491 
492 		typ_list_t = ptr;
493 		typ_list_h = ptr;
494 	}
495 	else
496 	{
497 		typ_list_t->next = ptr;
498 		typ_list_t = ptr;
499 	};
500 }
501 
502 
503 bas_type *find_type(type)
504 char *type;
505 {
506 	bas_type * ptr;
507 
508 	ptr = typ_list_h;
509 	while (ptr != NULL)
510 	{
511 		if (strcmp(ptr->name, type) == 0)
512 			return (ptr);
513 		else
514 			ptr = ptr->next;
515 	};
516 	return (NULL);
517 }
518