rpc_util.c revision 17142
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
33static 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
50char curline[MAXLINESIZE];	/* current read line */
51char *where = curline;		/* current point in line */
52int linenum = 0;		/* current line number */
53
54char *infilename;		/* input filename */
55
56#define	NFILES   7
57char *outfiles[NFILES];		/* output file names */
58int nfiles;
59
60FILE *fout;			/* file pointer of current output */
61FILE *fin;			/* file pointer of current input */
62
63list *defined;			/* list of defined things */
64
65static void printwhere __P(( void ));
66
67/*
68 * Reinitialize the world
69 */
70void
71reinitialize()
72{
73	memset(curline, 0, MAXLINESIZE);
74	where = curline;
75	linenum = 0;
76	defined = NULL;
77}
78
79/*
80 * string equality
81 */
82int
83streq(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 */
93definition *
94findval(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 */
111void
112storeval(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
126static int
127findit(def, type)
128	definition *def;
129	char *type;
130{
131	return (streq(def->def_name, type));
132}
133
134static char *
135fixit(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
159char *
160fixtype(type)
161	char *type;
162{
163	return (fixit(type, type));
164}
165
166char *
167stringfix(type)
168	char *type;
169{
170	if (streq(type, "string")) {
171		return ("wrapstring");
172	} else {
173		return (type);
174	}
175}
176
177void
178ptype(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
199static int
200typedefed(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
211int
212isvectordef(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
239char *
240locase(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
254void
255pvname_svc(pname, vnum)
256	char *pname;
257	char *vnum;
258{
259	f_print(fout, "%s_%s_svc", locase(pname), vnum);
260}
261
262void
263pvname(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 */
273void
274error(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 */
287void
288crash()
289{
290	int i;
291
292	for (i = 0; i < nfiles; i++) {
293		(void) unlink(outfiles[i]);
294	}
295	exit(1);
296}
297
298void
299record_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
310static char expectbuf[100];
311static char *toktostr();
312
313/*
314 * error, token encountered was not the expected one
315 */
316void
317expected1(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 */
328void
329expected2(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 */
341void
342expected3(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
352void
353tabify(f, tab)
354	FILE *f;
355	int tab;
356{
357	while (tab--) {
358		(void) fputc('\t', f);
359	}
360}
361
362
363static 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
400static char *
401toktostr(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
410static void
411printbuf()
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
432static void
433printwhere()
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
454char *
455make_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
470bas_type *typ_list_h;
471bas_type *typ_list_t;
472
473void
474add_type(len, type)
475int len;
476char *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
503bas_type *find_type(type)
504char *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