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