xref: /illumos-gate/usr/src/cmd/rpcgen/rpc_util.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  *
22  * Copyright 2001 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
27 /*
28  * University Copyright- Copyright (c) 1982, 1986, 1988
29  * The Regents of the University of California
30  * All Rights Reserved
31  *
32  * University Acknowledgment- Portions of this document are derived from
33  * software developed by the University of California, Berkeley, and its
34  * contributors.
35  */
36 
37 #pragma ident	"%Z%%M%	%I%	%E% SMI"
38 
39 /*
40  * rpc_util.c, Utility routines for the RPC protocol compiler
41  */
42 #include <stdio.h>
43 #include <ctype.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   15
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 /*
66  * Reinitialize the world
67  */
68 reinitialize()
69 {
70 	memset(curline, 0, MAXLINESIZE);
71 	where = curline;
72 	linenum = 0;
73 	defined = NULL;
74 }
75 
76 /*
77  * string equality
78  */
79 streq(a, b)
80 	char *a;
81 	char *b;
82 {
83 	return (strcmp(a, b) == 0);
84 }
85 
86 /*
87  * find a value in a list
88  */
89 definition *
90 findval(lst, val, cmp)
91 	list *lst;
92 	char *val;
93 	int (*cmp) ();
94 
95 {
96 	for (; lst != NULL; lst = lst->next) {
97 		if ((*cmp) (lst->val, val)) {
98 			return (lst->val);
99 		}
100 	}
101 	return (NULL);
102 }
103 
104 /*
105  * store a value in a list
106  */
107 void
108 storeval(lstp, val)
109 	list **lstp;
110 	definition *val;
111 {
112 	list **l;
113 	list *lst;
114 
115 	for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
116 	lst = ALLOC(list);
117 	lst->val = val;
118 	lst->next = NULL;
119 	*l = lst;
120 }
121 
122 static
123 findit(def, type)
124 	definition *def;
125 	char *type;
126 {
127 	return (streq(def->def_name, type));
128 }
129 
130 static char *
131 fixit(type, orig)
132 	char *type;
133 	char *orig;
134 {
135 	definition *def;
136 
137 	def = (definition *) FINDVAL(defined, type, findit);
138 	if (def == NULL || def->def_kind != DEF_TYPEDEF) {
139 		return (orig);
140 	}
141 	switch (def->def.ty.rel) {
142 	case REL_VECTOR:
143 		if (streq(def->def.ty.old_type, "opaque"))
144 			return ("char");
145 		else
146 			return (def->def.ty.old_type);
147 
148 	case REL_ALIAS:
149 		return (fixit(def->def.ty.old_type, orig));
150 	default:
151 		return (orig);
152 	}
153 }
154 
155 char *
156 fixtype(type)
157 	char *type;
158 {
159 	return (fixit(type, type));
160 }
161 
162 char *
163 stringfix(type)
164 	char *type;
165 {
166 	if (streq(type, "string")) {
167 		return ("wrapstring");
168 	} else {
169 		return (type);
170 	}
171 }
172 
173 void
174 ptype(prefix, type, follow)
175 	char *prefix;
176 	char *type;
177 	int follow;
178 {
179 	if (prefix != NULL) {
180 		if (streq(prefix, "enum")) {
181 			f_print(fout, "enum ");
182 		} else {
183 			f_print(fout, "struct ");
184 		}
185 	}
186 	if (streq(type, "bool")) {
187 		f_print(fout, "bool_t ");
188 	} else if (streq(type, "string")) {
189 		f_print(fout, "char *");
190 	} else if (streq(type, "oneway")) {
191 		f_print(fout, "void ");
192 	} else {
193 		f_print(fout, "%s ", follow ? fixtype(type) : type);
194 	}
195 }
196 
197 static
198 typedefed(def, type)
199 	definition *def;
200 	char *type;
201 {
202 	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
203 		return (0);
204 	} else {
205 		return (streq(def->def_name, type));
206 	}
207 }
208 
209 isvectordef(type, rel)
210 	char *type;
211 	relation rel;
212 {
213 	definition *def;
214 
215 	for (;;) {
216 		switch (rel) {
217 		case REL_VECTOR:
218 			return (!streq(type, "string"));
219 		case REL_ARRAY:
220 			return (0);
221 		case REL_POINTER:
222 			return (0);
223 		case REL_ALIAS:
224 			def = (definition *) FINDVAL(defined, type, typedefed);
225 			if (def == NULL)
226 				return (0);
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
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 = 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 add_type(len, type)
467 int len;
468 char *type;
469 {
470 	bas_type *ptr;
471 
472 	if ((ptr = (bas_type *) malloc(sizeof (bas_type))) ==
473 	    (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 	{
483 
484 		typ_list_t = ptr;
485 		typ_list_h = ptr;
486 	}
487 	else
488 	{
489 		typ_list_t->next = ptr;
490 		typ_list_t = ptr;
491 	};
492 }
493 
494 
495 bas_type *find_type(type)
496 char *type;
497 {
498 	bas_type * ptr;
499 
500 	ptr = typ_list_h;
501 	while (ptr != NULL)
502 	{
503 		if (strcmp(ptr->name, type) == 0)
504 			return (ptr);
505 		else
506 			ptr = ptr->next;
507 	};
508 	return (NULL);
509 }
510