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