rpc_util.c revision 299509
154359Sroberto/*
254359Sroberto * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
354359Sroberto * unrestricted use provided that this legend is included on all tape
454359Sroberto * media and as a part of the software program in whole or part.  Users
554359Sroberto * may copy or modify Sun RPC without charge, but are not authorized
654359Sroberto * to license or distribute it to anyone else except as part of a product or
754359Sroberto * program developed by the user.
854359Sroberto *
954359Sroberto * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
1054359Sroberto * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
1154359Sroberto * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1254359Sroberto *
1354359Sroberto * Sun RPC is provided with no support and without any obligation on the
1454359Sroberto * part of Sun Microsystems, Inc. to assist in its use, correction,
1554359Sroberto * modification or enhancement.
1654359Sroberto *
1754359Sroberto * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
1854359Sroberto * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
1954359Sroberto * OR ANY PART THEREOF.
2054359Sroberto *
2154359Sroberto * In no event will Sun Microsystems, Inc. be liable for any lost revenue
2254359Sroberto * or profits or other special, indirect and consequential damages, even if
23182007Sroberto * Sun has been advised of the possibility of such damages.
24182007Sroberto *
25182007Sroberto * Sun Microsystems, Inc.
26290001Sglebius * 2550 Garcia Avenue
27290001Sglebius * Mountain View, California  94043
28290001Sglebius */
29290001Sglebius
30290001Sglebius#if 0
31182007Sroberto#ifndef lint
32182007Sroberto#ident	"@(#)rpc_util.c	1.14	93/07/05 SMI"
33290001Sglebiusstatic char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
34290001Sglebius#endif
35290001Sglebius#endif
36290001Sglebius
37182007Sroberto#include <sys/cdefs.h>
38182007Sroberto__FBSDID("$FreeBSD: head/usr.bin/rpcgen/rpc_util.c 299509 2016-05-12 03:49:05Z cem $");
39290001Sglebius
40182007Sroberto/*
41182007Sroberto * rpc_util.c, Utility routines for the RPC protocol compiler
42182007Sroberto * Copyright (C) 1989, Sun Microsystems, Inc.
43290001Sglebius */
44290001Sglebius#include <err.h>
45290001Sglebius#include <ctype.h>
4654359Sroberto#include <stdio.h>
4754359Sroberto#include <string.h>
4854359Sroberto#include <unistd.h>
4954359Sroberto#include "rpc_parse.h"
5054359Sroberto#include "rpc_scan.h"
5154359Sroberto#include "rpc_util.h"
5254359Sroberto
5354359Sroberto#define	ARGEXT "argument"
5454359Sroberto
5554359Srobertochar curline[MAXLINESIZE];	/* current read line */
5654359Srobertochar *where = curline;		/* current point in line */
5754359Srobertoint linenum = 0;		/* current line number */
5854359Sroberto
5954359Srobertoconst char *infilename;		/* input filename */
6082498Sroberto
6182498Sroberto#define	NFILES   7
6282498Srobertostatic const char *outfiles[NFILES]; /* output file names */
6382498Srobertostatic int nfiles;
6454359Sroberto
6554359SrobertoFILE *fout;			/* file pointer of current output */
6654359SrobertoFILE *fin;			/* file pointer of current input */
6754359Sroberto
6854359Srobertolist *defined;			/* list of defined things */
6954359Sroberto
7054359Srobertostatic void printwhere( void );
7154359Sroberto
7254359Sroberto/*
7354359Sroberto * Reinitialize the world
7454359Sroberto */
7554359Srobertovoid
7654359Srobertoreinitialize(void)
7754359Sroberto{
7854359Sroberto	memset(curline, 0, MAXLINESIZE);
7954359Sroberto	where = curline;
8054359Sroberto	linenum = 0;
8154359Sroberto	defined = NULL;
8254359Sroberto}
8354359Sroberto
84182007Sroberto/*
85182007Sroberto * string equality
86182007Sroberto */
87182007Srobertoint
88182007Srobertostreq(const char *a, const char *b)
89182007Sroberto{
90290001Sglebius	return (strcmp(a, b) == 0);
91290001Sglebius}
92290001Sglebius
93290001Sglebius/*
94290001Sglebius * find a value in a list
95290001Sglebius */
96290001Sglebiusdefinition *
97290001Sglebiusfindval(list *lst, const char *val, int (*cmp)(definition *, const char *))
98290001Sglebius{
99290001Sglebius	for (; lst != NULL; lst = lst->next) {
100290001Sglebius		if ((*cmp) (lst->val, val)) {
101290001Sglebius			return (lst->val);
10254359Sroberto		}
103290001Sglebius	}
104290001Sglebius	return (NULL);
105290001Sglebius}
106290001Sglebius
107290001Sglebius/*
108290001Sglebius * store a value in a list
109290001Sglebius */
110290001Sglebiusvoid
111290001Sglebiusstoreval(list **lstp, definition *val)
112290001Sglebius{
113290001Sglebius	list **l;
114290001Sglebius	list *lst;
115290001Sglebius
116290001Sglebius	for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
117290001Sglebius	lst = XALLOC(list);
118290001Sglebius	lst->val = val;
119290001Sglebius	lst->next = NULL;
120290001Sglebius	*l = lst;
12154359Sroberto}
12254359Sroberto
12354359Srobertostatic int
12454359Srobertofindit(definition *def, const char *type)
12554359Sroberto{
126182007Sroberto	return (streq(def->def_name, type));
12754359Sroberto}
12854359Sroberto
12954359Srobertostatic const char *
130182007Srobertofixit(const char *type, const char *orig)
13154359Sroberto{
13254359Sroberto	definition *def;
13354359Sroberto
13454359Sroberto	def = (definition *) FINDVAL(defined, type, findit);
13554359Sroberto	if (def == NULL || def->def_kind != DEF_TYPEDEF) {
13654359Sroberto		return (orig);
13754359Sroberto	}
13854359Sroberto	switch (def->def.ty.rel) {
13954359Sroberto	case REL_VECTOR:
14054359Sroberto		if (streq(def->def.ty.old_type, "opaque"))
14154359Sroberto			return ("char");
14254359Sroberto		else
14354359Sroberto			return (def->def.ty.old_type);
14454359Sroberto
14554359Sroberto	case REL_ALIAS:
14654359Sroberto		return (fixit(def->def.ty.old_type, orig));
14754359Sroberto	default:
14854359Sroberto		return (orig);
14954359Sroberto	}
15054359Sroberto}
15154359Sroberto
15254359Srobertoconst char *
15354359Srobertofixtype(const char *type)
15454359Sroberto{
15554359Sroberto	return (fixit(type, type));
15654359Sroberto}
15754359Sroberto
15854359Srobertoconst char *
15954359Srobertostringfix(const char *type)
16054359Sroberto{
16154359Sroberto	if (streq(type, "string")) {
16254359Sroberto		return ("wrapstring");
16354359Sroberto	} else {
16454359Sroberto		return (type);
165182007Sroberto	}
166290001Sglebius}
167290001Sglebius
168290001Sglebiusvoid
169290001Sglebiusptype(const char *prefix, const char *type, int follow)
170290001Sglebius{
171182007Sroberto	if (prefix != NULL) {
172182007Sroberto		if (streq(prefix, "enum")) {
173182007Sroberto			f_print(fout, "enum ");
174182007Sroberto		} else {
175182007Sroberto			f_print(fout, "struct ");
176182007Sroberto		}
177182007Sroberto	}
178182007Sroberto	if (streq(type, "bool")) {
17954359Sroberto		f_print(fout, "bool_t ");
18054359Sroberto	} else if (streq(type, "string")) {
18154359Sroberto		f_print(fout, "char *");
18254359Sroberto	} else {
18354359Sroberto		f_print(fout, "%s ", follow ? fixtype(type) : type);
18482498Sroberto	}
18582498Sroberto}
18682498Sroberto
18782498Srobertostatic int
18882498Srobertotypedefed(definition *def, const char *type)
18982498Sroberto{
19082498Sroberto	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
19154359Sroberto		return (0);
19254359Sroberto	} else {
19354359Sroberto		return (streq(def->def_name, type));
19454359Sroberto	}
195182007Sroberto}
196182007Sroberto
19754359Srobertoint
198290001Sglebiusisvectordef(const char *type, relation rel)
199290001Sglebius{
200290001Sglebius	definition *def;
201290001Sglebius
202290001Sglebius	for (;;) {
203290001Sglebius		switch (rel) {
204290001Sglebius		case REL_VECTOR:
205290001Sglebius			return (!streq(type, "string"));
206290001Sglebius		case REL_ARRAY:
20754359Sroberto			return (0);
20854359Sroberto		case REL_POINTER:
20954359Sroberto			return (0);
21054359Sroberto		case REL_ALIAS:
21154359Sroberto			def = (definition *) FINDVAL(defined, type, typedefed);
21254359Sroberto			if (def == NULL) {
21354359Sroberto				return (0);
21454359Sroberto			}
21554359Sroberto			type = def->def.ty.old_type;
21654359Sroberto			rel = def->def.ty.rel;
21754359Sroberto		}
21854359Sroberto	}
21954359Sroberto
22054359Sroberto	return (0);
221182007Sroberto}
222182007Sroberto
223182007Srobertochar *
224182007Srobertolocase(const char *str)
225290001Sglebius{
226182007Sroberto	char c;
227182007Sroberto	static char buf[100];
228182007Sroberto	char *p = buf;
229182007Sroberto
230182007Sroberto	while ( (c = *str++) ) {
231182007Sroberto		*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
232182007Sroberto	}
23354359Sroberto	*p = 0;
23454359Sroberto	return (buf);
23554359Sroberto}
23654359Sroberto
23754359Srobertovoid
238290001Sglebiuspvname_svc(const char *pname, const char *vnum)
23954359Sroberto{
240290001Sglebius	f_print(fout, "%s_%s_svc", locase(pname), vnum);
24154359Sroberto}
24254359Sroberto
24354359Srobertovoid
244182007Srobertopvname(const char *pname, const char *vnum)
245182007Sroberto{
246182007Sroberto	f_print(fout, "%s_%s", locase(pname), vnum);
247182007Sroberto}
248290001Sglebius
249182007Sroberto/*
250182007Sroberto * print a useful (?) error message, and then die
251182007Sroberto */
252182007Srobertovoid
25354359Srobertoerror(const char *msg)
254182007Sroberto{
255182007Sroberto	printwhere();
256182007Sroberto	warnx("%s, line %d: %s", infilename, linenum, msg);
257182007Sroberto	crash();
258182007Sroberto}
25954359Sroberto
26054359Sroberto/*
26154359Sroberto * Something went wrong, unlink any files that we may have created and then
26254359Sroberto * die.
26354359Sroberto */
264290001Sglebiusvoid __dead2
26554359Srobertocrash(void)
26654359Sroberto{
26754359Sroberto	int i;
26854359Sroberto
26954359Sroberto	for (i = 0; i < nfiles; i++) {
27054359Sroberto		(void) unlink(outfiles[i]);
271290001Sglebius	}
27254359Sroberto	exit(1);
27354359Sroberto}
27454359Sroberto
275290001Sglebiusvoid
27654359Srobertorecord_open(const char *file)
27754359Sroberto{
278290001Sglebius	if (nfiles < NFILES) {
27954359Sroberto		outfiles[nfiles++] = file;
28054359Sroberto	} else {
28154359Sroberto		warnx("too many files");
28254359Sroberto		crash();
28354359Sroberto	}
28454359Sroberto}
28554359Sroberto
28682498Srobertostatic char expectbuf[100];
28754359Srobertostatic const char *toktostr(tok_kind kind);
28854359Sroberto
28954359Sroberto/*
29054359Sroberto * error, token encountered was not the expected one
29154359Sroberto */
29254359Srobertovoid
29354359Srobertoexpected1(tok_kind exp1)
29454359Sroberto{
29554359Sroberto	s_print(expectbuf, "expected '%s'",
29654359Sroberto		toktostr(exp1));
29754359Sroberto	error(expectbuf);
29854359Sroberto}
29954359Sroberto
30054359Sroberto/*
30154359Sroberto * error, token encountered was not one of two expected ones
30254359Sroberto */
30354359Srobertovoid
30454359Srobertoexpected2(tok_kind exp1, tok_kind exp2)
30554359Sroberto{
30682498Sroberto	s_print(expectbuf, "expected '%s' or '%s'",
307290001Sglebius		toktostr(exp1),
30854359Sroberto		toktostr(exp2));
30954359Sroberto	error(expectbuf);
310290001Sglebius}
311290001Sglebius
312290001Sglebius/*
313290001Sglebius * error, token encountered was not one of 3 expected ones
31454359Sroberto */
31554359Srobertovoid
31654359Srobertoexpected3(tok_kind exp1, tok_kind exp2, tok_kind exp3)
31754359Sroberto{
31854359Sroberto	s_print(expectbuf, "expected '%s', '%s' or '%s'",
31954359Sroberto		toktostr(exp1),
32054359Sroberto		toktostr(exp2),
32154359Sroberto		toktostr(exp3));
32254359Sroberto	error(expectbuf);
32354359Sroberto}
32454359Sroberto
32554359Srobertovoid
32654359Srobertotabify(FILE *f, int tab)
32754359Sroberto{
32854359Sroberto	while (tab--) {
32954359Sroberto		(void) fputc('\t', f);
33054359Sroberto	}
33154359Sroberto}
33254359Sroberto
33354359Sroberto
33454359Srobertostatic token tokstrings[] = {
33554359Sroberto			{TOK_IDENT, "identifier"},
33654359Sroberto			{TOK_CONST, "const"},
33754359Sroberto			{TOK_RPAREN, ")"},
33854359Sroberto			{TOK_LPAREN, "("},
33954359Sroberto			{TOK_RBRACE, "}"},
34054359Sroberto			{TOK_LBRACE, "{"},
34154359Sroberto			{TOK_LBRACKET, "["},
34254359Sroberto			{TOK_RBRACKET, "]"},
34354359Sroberto			{TOK_STAR, "*"},
34454359Sroberto			{TOK_COMMA, ","},
34554359Sroberto			{TOK_EQUAL, "="},
34654359Sroberto			{TOK_COLON, ":"},
347290001Sglebius			{TOK_SEMICOLON, ";"},
34854359Sroberto			{TOK_UNION, "union"},
34954359Sroberto			{TOK_STRUCT, "struct"},
35054359Sroberto			{TOK_SWITCH, "switch"},
35154359Sroberto			{TOK_CASE, "case"},
35254359Sroberto			{TOK_DEFAULT, "default"},
35354359Sroberto			{TOK_ENUM, "enum"},
35454359Sroberto			{TOK_TYPEDEF, "typedef"},
35554359Sroberto			{TOK_INT, "int"},
35654359Sroberto			{TOK_SHORT, "short"},
35754359Sroberto			{TOK_LONG, "long"},
35854359Sroberto			{TOK_UNSIGNED, "unsigned"},
35954359Sroberto			{TOK_DOUBLE, "double"},
36054359Sroberto			{TOK_FLOAT, "float"},
36154359Sroberto			{TOK_CHAR, "char"},
36254359Sroberto			{TOK_STRING, "string"},
36354359Sroberto			{TOK_OPAQUE, "opaque"},
36454359Sroberto			{TOK_BOOL, "bool"},
36554359Sroberto			{TOK_VOID, "void"},
36654359Sroberto			{TOK_PROGRAM, "program"},
36754359Sroberto			{TOK_VERSION, "version"},
368290001Sglebius			{TOK_EOF, "??????"}
369290001Sglebius};
370290001Sglebius
371290001Sglebiusstatic const char *
372290001Sglebiustoktostr(tok_kind kind)
373290001Sglebius{
374290001Sglebius	token *sp;
375290001Sglebius
376290001Sglebius	for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
37754359Sroberto	return (sp->str);
37854359Sroberto}
37954359Sroberto
38054359Srobertostatic void
38154359Srobertoprintbuf(void)
38254359Sroberto{
38354359Sroberto	char c;
384182007Sroberto	int i;
38554359Sroberto	int cnt;
38654359Sroberto
38754359Sroberto#	define TABSIZE 4
38854359Sroberto
38954359Sroberto	for (i = 0; (c = curline[i]); i++) {
390182007Sroberto		if (c == '\t') {
39154359Sroberto			cnt = 8 - (i % TABSIZE);
39254359Sroberto			c = ' ';
39354359Sroberto		} else {
39454359Sroberto			cnt = 1;
39554359Sroberto		}
39654359Sroberto		while (cnt--) {
39754359Sroberto			(void) fputc(c, stderr);
39854359Sroberto		}
39954359Sroberto	}
40054359Sroberto}
40154359Sroberto
40254359Srobertostatic void
40354359Srobertoprintwhere(void)
40454359Sroberto{
40554359Sroberto	int i;
40654359Sroberto	char c;
40754359Sroberto	int cnt;
40854359Sroberto
409132451Sroberto	printbuf();
410132451Sroberto	for (i = 0; i < where - curline; i++) {
41154359Sroberto		c = curline[i];
41254359Sroberto		if (c == '\t') {
41354359Sroberto			cnt = 8 - (i % TABSIZE);
41454359Sroberto		} else {
41554359Sroberto			cnt = 1;
41654359Sroberto		}
41754359Sroberto		while (cnt--) {
41854359Sroberto			(void) fputc('^', stderr);
419182007Sroberto		}
420182007Sroberto	}
421290001Sglebius	(void) fputc('\n', stderr);
42254359Sroberto}
423290001Sglebius
424290001Sglebiuschar *
42554359Srobertomake_argname(const char *pname, const char *vname)
426182007Sroberto{
427182007Sroberto	char *name;
428182007Sroberto
429182007Sroberto	name = xmalloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
430182007Sroberto	sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
431182007Sroberto	return (name);
432182007Sroberto}
433182007Sroberto
43454359Srobertobas_type *typ_list_h;
435182007Srobertobas_type *typ_list_t;
436182007Sroberto
437182007Srobertovoid
438182007Srobertoadd_type(int len, const char *type)
439182007Sroberto{
440182007Sroberto	bas_type *ptr;
441182007Sroberto
442290001Sglebius	ptr = XALLOC(bas_type);
443290001Sglebius
444290001Sglebius	ptr->name = type;
445290001Sglebius	ptr->length = len;
446290001Sglebius	ptr->next = NULL;
447290001Sglebius	if (typ_list_t == NULL)
448290001Sglebius	{
449290001Sglebius
450290001Sglebius		typ_list_t = ptr;
451290001Sglebius		typ_list_h = ptr;
452290001Sglebius	}
453290001Sglebius	else
454290001Sglebius	{
455290001Sglebius		typ_list_t->next = ptr;
456290001Sglebius		typ_list_t = ptr;
457290001Sglebius	}
458290001Sglebius}
459290001Sglebius
460290001Sglebius
461290001Sglebiusbas_type *
46254359Srobertofind_type(const char *type)
463182007Sroberto{
46454359Sroberto	bas_type * ptr;
465182007Sroberto
466290001Sglebius	ptr = typ_list_h;
467290001Sglebius	while (ptr != NULL)
468182007Sroberto	{
469182007Sroberto		if (strcmp(ptr->name, type) == 0)
470182007Sroberto			return (ptr);
471290001Sglebius		else
472290001Sglebius			ptr = ptr->next;
473290001Sglebius	}
474182007Sroberto	return (NULL);
47554359Sroberto}
476182007Sroberto
477290001Sglebiusvoid *
478290001Sglebiusxmalloc(size_t size)
479182007Sroberto{
48054359Sroberto	void *p;
481182007Sroberto
482290001Sglebius	if ((p = malloc(size)) == NULL) {
483290001Sglebius		warnx("malloc failed");
484182007Sroberto		crash();
48554359Sroberto	}
486182007Sroberto	return (p);
487290001Sglebius}
488290001Sglebius
489182007Srobertovoid *
49054359Srobertoxrealloc(void *ptr, size_t size)
491182007Sroberto{
492182007Sroberto	void *p;
49354359Sroberto
494290001Sglebius	if ((p = realloc(ptr, size)) == NULL) {
495290001Sglebius		warnx("realloc failed");
496290001Sglebius		crash();
497182007Sroberto	}
49854359Sroberto	return (p);
499182007Sroberto}
500290001Sglebius
50154359Srobertochar *
502182007Srobertoxstrdup(const char *str)
503182007Sroberto{
50454359Sroberto	char *p;
505182007Sroberto
50654359Sroberto	if ((p = strdup(str)) == NULL) {
50754359Sroberto		warnx("strdup failed");
50854359Sroberto		crash();
50954359Sroberto	}
510182007Sroberto	return (p);
511182007Sroberto}
512182007Sroberto