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