11897Swollman/*
21897Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
31897Swollman * unrestricted use provided that this legend is included on all tape
41897Swollman * media and as a part of the software program in whole or part.  Users
51897Swollman * may copy or modify Sun RPC without charge, but are not authorized
61897Swollman * to license or distribute it to anyone else except as part of a product or
71897Swollman * program developed by the user.
8100441Scharnier *
91897Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
101897Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
111897Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12100441Scharnier *
131897Swollman * Sun RPC is provided with no support and without any obligation on the
141897Swollman * part of Sun Microsystems, Inc. to assist in its use, correction,
151897Swollman * modification or enhancement.
16100441Scharnier *
171897Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
181897Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
191897Swollman * OR ANY PART THEREOF.
20100441Scharnier *
211897Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue
221897Swollman * or profits or other special, indirect and consequential damages, even if
231897Swollman * Sun has been advised of the possibility of such damages.
24100441Scharnier *
251897Swollman * Sun Microsystems, Inc.
261897Swollman * 2550 Garcia Avenue
271897Swollman * Mountain View, California  94043
281897Swollman */
2912798Swpaul
30100441Scharnier#if 0
311897Swollman#ifndef lint
32146833Sstefanf#ident	"@(#)rpc_util.c	1.14	93/07/05 SMI"
3312798Swpaulstatic char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
341897Swollman#endif
3527935Scharnier#endif
361897Swollman
37100441Scharnier#include <sys/cdefs.h>
38100441Scharnier__FBSDID("$FreeBSD$");
39100441Scharnier
401897Swollman/*
418874Srgrimes * rpc_util.c, Utility routines for the RPC protocol compiler
4212798Swpaul * Copyright (C) 1989, Sun Microsystems, Inc.
431897Swollman */
4427935Scharnier#include <err.h>
45200462Sdelphij#include <ctype.h>
461897Swollman#include <stdio.h>
4717142Sjkh#include <string.h>
4817142Sjkh#include <unistd.h>
49152398Sdwmalone#include "rpc_parse.h"
501897Swollman#include "rpc_scan.h"
511897Swollman#include "rpc_util.h"
521897Swollman
5312798Swpaul#define	ARGEXT "argument"
5412798Swpaul
551897Swollmanchar curline[MAXLINESIZE];	/* current read line */
5612798Swpaulchar *where = curline;		/* current point in line */
5712798Swpaulint linenum = 0;		/* current line number */
581897Swollman
59152398Sdwmaloneconst char *infilename;		/* input filename */
601897Swollman
6112798Swpaul#define	NFILES   7
62241737Sedstatic const char *outfiles[NFILES]; /* output file names */
63241737Sedstatic int nfiles;
641897Swollman
6512798SwpaulFILE *fout;			/* file pointer of current output */
6612798SwpaulFILE *fin;			/* file pointer of current input */
671897Swollman
6812798Swpaullist *defined;			/* list of defined things */
691897Swollman
7092921Simpstatic void printwhere( void );
711897Swollman
721897Swollman/*
738874Srgrimes * Reinitialize the world
741897Swollman */
7517142Sjkhvoid
76152398Sdwmalonereinitialize(void)
771897Swollman{
7812798Swpaul	memset(curline, 0, MAXLINESIZE);
791897Swollman	where = curline;
801897Swollman	linenum = 0;
811897Swollman	defined = NULL;
821897Swollman}
831897Swollman
841897Swollman/*
858874Srgrimes * string equality
861897Swollman */
8717142Sjkhint
88152398Sdwmalonestreq(const char *a, const char *b)
891897Swollman{
901897Swollman	return (strcmp(a, b) == 0);
911897Swollman}
921897Swollman
931897Swollman/*
948874Srgrimes * find a value in a list
951897Swollman */
9612798Swpauldefinition *
97152398Sdwmalonefindval(list *lst, const char *val, int (*cmp)(definition *, const char *))
981897Swollman{
991897Swollman	for (; lst != NULL; lst = lst->next) {
1001897Swollman		if ((*cmp) (lst->val, val)) {
1011897Swollman			return (lst->val);
1021897Swollman		}
1031897Swollman	}
1041897Swollman	return (NULL);
1051897Swollman}
1061897Swollman
1071897Swollman/*
1088874Srgrimes * store a value in a list
1091897Swollman */
1101897Swollmanvoid
111152398Sdwmalonestoreval(list **lstp, definition *val)
1121897Swollman{
1131897Swollman	list **l;
1141897Swollman	list *lst;
1151897Swollman
1161897Swollman	for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
117100441Scharnier	lst = XALLOC(list);
1181897Swollman	lst->val = val;
1191897Swollman	lst->next = NULL;
1201897Swollman	*l = lst;
1211897Swollman}
1221897Swollman
12317142Sjkhstatic int
124152398Sdwmalonefindit(definition *def, const char *type)
1251897Swollman{
1261897Swollman	return (streq(def->def_name, type));
1271897Swollman}
1281897Swollman
129152398Sdwmalonestatic const char *
130152398Sdwmalonefixit(const char *type, const char *orig)
1311897Swollman{
1321897Swollman	definition *def;
1331897Swollman
1341897Swollman	def = (definition *) FINDVAL(defined, type, findit);
1351897Swollman	if (def == NULL || def->def_kind != DEF_TYPEDEF) {
1361897Swollman		return (orig);
1371897Swollman	}
1381897Swollman	switch (def->def.ty.rel) {
1391897Swollman	case REL_VECTOR:
14012798Swpaul		if (streq(def->def.ty.old_type, "opaque"))
14112798Swpaul			return ("char");
14212798Swpaul		else
14312798Swpaul			return (def->def.ty.old_type);
14412798Swpaul
1451897Swollman	case REL_ALIAS:
1461897Swollman		return (fixit(def->def.ty.old_type, orig));
1471897Swollman	default:
1481897Swollman		return (orig);
1491897Swollman	}
1501897Swollman}
1511897Swollman
152152398Sdwmaloneconst char *
153152398Sdwmalonefixtype(const char *type)
1541897Swollman{
1551897Swollman	return (fixit(type, type));
1561897Swollman}
1571897Swollman
158152398Sdwmaloneconst char *
159152398Sdwmalonestringfix(const char *type)
1601897Swollman{
1611897Swollman	if (streq(type, "string")) {
1621897Swollman		return ("wrapstring");
1631897Swollman	} else {
1641897Swollman		return (type);
1651897Swollman	}
1661897Swollman}
1671897Swollman
1681897Swollmanvoid
169152398Sdwmaloneptype(const char *prefix, const char *type, int follow)
1701897Swollman{
1711897Swollman	if (prefix != NULL) {
1721897Swollman		if (streq(prefix, "enum")) {
1731897Swollman			f_print(fout, "enum ");
1741897Swollman		} else {
1751897Swollman			f_print(fout, "struct ");
1761897Swollman		}
1771897Swollman	}
1781897Swollman	if (streq(type, "bool")) {
1791897Swollman		f_print(fout, "bool_t ");
1801897Swollman	} else if (streq(type, "string")) {
1811897Swollman		f_print(fout, "char *");
1821897Swollman	} else {
1831897Swollman		f_print(fout, "%s ", follow ? fixtype(type) : type);
1841897Swollman	}
1851897Swollman}
1861897Swollman
18717142Sjkhstatic int
188152398Sdwmalonetypedefed(definition *def, const char *type)
1891897Swollman{
1901897Swollman	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
1911897Swollman		return (0);
1921897Swollman	} else {
1931897Swollman		return (streq(def->def_name, type));
1941897Swollman	}
1951897Swollman}
1961897Swollman
19717142Sjkhint
198152398Sdwmaloneisvectordef(const char *type, relation rel)
1991897Swollman{
2001897Swollman	definition *def;
2011897Swollman
2021897Swollman	for (;;) {
2031897Swollman		switch (rel) {
2041897Swollman		case REL_VECTOR:
2051897Swollman			return (!streq(type, "string"));
2061897Swollman		case REL_ARRAY:
2071897Swollman			return (0);
2081897Swollman		case REL_POINTER:
2091897Swollman			return (0);
2101897Swollman		case REL_ALIAS:
2111897Swollman			def = (definition *) FINDVAL(defined, type, typedefed);
2121897Swollman			if (def == NULL) {
2131897Swollman				return (0);
2141897Swollman			}
2151897Swollman			type = def->def.ty.old_type;
2161897Swollman			rel = def->def.ty.rel;
2171897Swollman		}
2181897Swollman	}
21917142Sjkh
22017142Sjkh	return (0);
2211897Swollman}
2221897Swollman
22312798Swpaulchar *
224152398Sdwmalonelocase(const char *str)
2251897Swollman{
2261897Swollman	char c;
2271897Swollman	static char buf[100];
2281897Swollman	char *p = buf;
2291897Swollman
23017142Sjkh	while ( (c = *str++) ) {
2311897Swollman		*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
2321897Swollman	}
2331897Swollman	*p = 0;
2341897Swollman	return (buf);
2351897Swollman}
2361897Swollman
23712798Swpaulvoid
238152398Sdwmalonepvname_svc(const char *pname, const char *vnum)
23912798Swpaul{
24012798Swpaul	f_print(fout, "%s_%s_svc", locase(pname), vnum);
24112798Swpaul}
2421897Swollman
2431897Swollmanvoid
244152398Sdwmalonepvname(const char *pname, const char *vnum)
2451897Swollman{
2461897Swollman	f_print(fout, "%s_%s", locase(pname), vnum);
2471897Swollman}
2481897Swollman
2491897Swollman/*
2508874Srgrimes * print a useful (?) error message, and then die
2511897Swollman */
2521897Swollmanvoid
253152398Sdwmaloneerror(const char *msg)
2541897Swollman{
2551897Swollman	printwhere();
25627935Scharnier	warnx("%s, line %d: %s", infilename, linenum, msg);
2571897Swollman	crash();
2581897Swollman}
2591897Swollman
2601897Swollman/*
2611897Swollman * Something went wrong, unlink any files that we may have created and then
2628874Srgrimes * die.
2631897Swollman */
26417142Sjkhvoid
265152398Sdwmalonecrash(void)
2661897Swollman{
2671897Swollman	int i;
2681897Swollman
2691897Swollman	for (i = 0; i < nfiles; i++) {
2701897Swollman		(void) unlink(outfiles[i]);
2711897Swollman	}
2721897Swollman	exit(1);
2731897Swollman}
2741897Swollman
2751897Swollmanvoid
276152398Sdwmalonerecord_open(const char *file)
2771897Swollman{
2781897Swollman	if (nfiles < NFILES) {
2791897Swollman		outfiles[nfiles++] = file;
2801897Swollman	} else {
28127935Scharnier		warnx("too many files");
2821897Swollman		crash();
2831897Swollman	}
2841897Swollman}
2851897Swollman
2861897Swollmanstatic char expectbuf[100];
287152398Sdwmalonestatic const char *toktostr(tok_kind kind);
2881897Swollman
2891897Swollman/*
2908874Srgrimes * error, token encountered was not the expected one
2911897Swollman */
2921897Swollmanvoid
293152398Sdwmaloneexpected1(tok_kind exp1)
2941897Swollman{
2951897Swollman	s_print(expectbuf, "expected '%s'",
2961897Swollman		toktostr(exp1));
2971897Swollman	error(expectbuf);
2981897Swollman}
2991897Swollman
3001897Swollman/*
3018874Srgrimes * error, token encountered was not one of two expected ones
3021897Swollman */
3031897Swollmanvoid
304152398Sdwmaloneexpected2(tok_kind exp1, tok_kind exp2)
3051897Swollman{
3061897Swollman	s_print(expectbuf, "expected '%s' or '%s'",
3071897Swollman		toktostr(exp1),
3081897Swollman		toktostr(exp2));
3091897Swollman	error(expectbuf);
3101897Swollman}
3111897Swollman
3121897Swollman/*
3138874Srgrimes * error, token encountered was not one of 3 expected ones
3141897Swollman */
3151897Swollmanvoid
316152398Sdwmaloneexpected3(tok_kind exp1, tok_kind exp2, tok_kind exp3)
3171897Swollman{
3181897Swollman	s_print(expectbuf, "expected '%s', '%s' or '%s'",
3191897Swollman		toktostr(exp1),
3201897Swollman		toktostr(exp2),
3211897Swollman		toktostr(exp3));
3221897Swollman	error(expectbuf);
3231897Swollman}
3241897Swollman
3251897Swollmanvoid
326152398Sdwmalonetabify(FILE *f, int tab)
3271897Swollman{
3281897Swollman	while (tab--) {
3291897Swollman		(void) fputc('\t', f);
3301897Swollman	}
3311897Swollman}
3321897Swollman
3331897Swollman
3341897Swollmanstatic token tokstrings[] = {
33512798Swpaul			{TOK_IDENT, "identifier"},
33612798Swpaul			{TOK_CONST, "const"},
33712798Swpaul			{TOK_RPAREN, ")"},
33812798Swpaul			{TOK_LPAREN, "("},
33912798Swpaul			{TOK_RBRACE, "}"},
34012798Swpaul			{TOK_LBRACE, "{"},
34112798Swpaul			{TOK_LBRACKET, "["},
34212798Swpaul			{TOK_RBRACKET, "]"},
34312798Swpaul			{TOK_STAR, "*"},
34412798Swpaul			{TOK_COMMA, ","},
34512798Swpaul			{TOK_EQUAL, "="},
34612798Swpaul			{TOK_COLON, ":"},
34712798Swpaul			{TOK_SEMICOLON, ";"},
34812798Swpaul			{TOK_UNION, "union"},
34912798Swpaul			{TOK_STRUCT, "struct"},
35012798Swpaul			{TOK_SWITCH, "switch"},
35112798Swpaul			{TOK_CASE, "case"},
35212798Swpaul			{TOK_DEFAULT, "default"},
35312798Swpaul			{TOK_ENUM, "enum"},
35412798Swpaul			{TOK_TYPEDEF, "typedef"},
35512798Swpaul			{TOK_INT, "int"},
35612798Swpaul			{TOK_SHORT, "short"},
35712798Swpaul			{TOK_LONG, "long"},
35812798Swpaul			{TOK_UNSIGNED, "unsigned"},
35912798Swpaul			{TOK_DOUBLE, "double"},
36012798Swpaul			{TOK_FLOAT, "float"},
36112798Swpaul			{TOK_CHAR, "char"},
36212798Swpaul			{TOK_STRING, "string"},
36312798Swpaul			{TOK_OPAQUE, "opaque"},
36412798Swpaul			{TOK_BOOL, "bool"},
36512798Swpaul			{TOK_VOID, "void"},
36612798Swpaul			{TOK_PROGRAM, "program"},
36712798Swpaul			{TOK_VERSION, "version"},
36812798Swpaul			{TOK_EOF, "??????"}
3691897Swollman};
3701897Swollman
371152398Sdwmalonestatic const char *
372152398Sdwmalonetoktostr(tok_kind kind)
3731897Swollman{
3741897Swollman	token *sp;
3751897Swollman
3761897Swollman	for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
3771897Swollman	return (sp->str);
3781897Swollman}
3791897Swollman
38017142Sjkhstatic void
381152398Sdwmaloneprintbuf(void)
3821897Swollman{
3831897Swollman	char c;
3841897Swollman	int i;
3851897Swollman	int cnt;
3861897Swollman
3871897Swollman#	define TABSIZE 4
3881897Swollman
38917142Sjkh	for (i = 0; (c = curline[i]); i++) {
3901897Swollman		if (c == '\t') {
3911897Swollman			cnt = 8 - (i % TABSIZE);
3921897Swollman			c = ' ';
3931897Swollman		} else {
3941897Swollman			cnt = 1;
3951897Swollman		}
3961897Swollman		while (cnt--) {
3971897Swollman			(void) fputc(c, stderr);
3981897Swollman		}
3991897Swollman	}
4001897Swollman}
4011897Swollman
40217142Sjkhstatic void
403152398Sdwmaloneprintwhere(void)
4041897Swollman{
4051897Swollman	int i;
4061897Swollman	char c;
4071897Swollman	int cnt;
4081897Swollman
4091897Swollman	printbuf();
4101897Swollman	for (i = 0; i < where - curline; i++) {
4111897Swollman		c = curline[i];
4121897Swollman		if (c == '\t') {
4131897Swollman			cnt = 8 - (i % TABSIZE);
4141897Swollman		} else {
4151897Swollman			cnt = 1;
4161897Swollman		}
4171897Swollman		while (cnt--) {
4181897Swollman			(void) fputc('^', stderr);
4191897Swollman		}
4201897Swollman	}
4211897Swollman	(void) fputc('\n', stderr);
4221897Swollman}
42312798Swpaul
42412798Swpaulchar *
425152398Sdwmalonemake_argname(const char *pname, const char *vname)
42612798Swpaul{
42712798Swpaul	char *name;
42812798Swpaul
429100441Scharnier	name = xmalloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
43012798Swpaul	sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
43112798Swpaul	return (name);
43212798Swpaul}
43312798Swpaul
43412798Swpaulbas_type *typ_list_h;
43512798Swpaulbas_type *typ_list_t;
43612798Swpaul
43717142Sjkhvoid
438152398Sdwmaloneadd_type(int len, const char *type)
43912798Swpaul{
44012798Swpaul	bas_type *ptr;
44112798Swpaul
442100441Scharnier	ptr = XALLOC(bas_type);
44312798Swpaul
44412798Swpaul	ptr->name = type;
44512798Swpaul	ptr->length = len;
44612798Swpaul	ptr->next = NULL;
44712798Swpaul	if (typ_list_t == NULL)
44812798Swpaul	{
44912798Swpaul
45012798Swpaul		typ_list_t = ptr;
45112798Swpaul		typ_list_h = ptr;
45212798Swpaul	}
45312798Swpaul	else
45412798Swpaul	{
45512798Swpaul		typ_list_t->next = ptr;
45612798Swpaul		typ_list_t = ptr;
45712798Swpaul	};
45812798Swpaul}
45912798Swpaul
46012798Swpaul
461152398Sdwmalonebas_type *
462152398Sdwmalonefind_type(const char *type)
46312798Swpaul{
46412798Swpaul	bas_type * ptr;
46512798Swpaul
46612798Swpaul	ptr = typ_list_h;
46712798Swpaul	while (ptr != NULL)
46812798Swpaul	{
46912798Swpaul		if (strcmp(ptr->name, type) == 0)
47012798Swpaul			return (ptr);
47112798Swpaul		else
47212798Swpaul			ptr = ptr->next;
47312798Swpaul	};
47412798Swpaul	return (NULL);
47512798Swpaul}
476100441Scharnier
477100441Scharniervoid *
478100441Scharnierxmalloc(size_t size)
479100441Scharnier{
480100441Scharnier	void *p;
481100441Scharnier
482100441Scharnier	if ((p = malloc(size)) == NULL) {
483100441Scharnier		warnx("malloc failed");
484100441Scharnier		crash();
485100441Scharnier	}
486100441Scharnier	return (p);
487100441Scharnier}
488100441Scharnier
489100441Scharniervoid *
490100441Scharnierxrealloc(void *ptr, size_t size)
491100441Scharnier{
492100441Scharnier	void *p;
493100441Scharnier
494100441Scharnier	if ((p = realloc(ptr, size)) == NULL) {
495100441Scharnier		warnx("realloc failed");
496100441Scharnier		crash();
497100441Scharnier	}
498100441Scharnier	return (p);
499100441Scharnier}
500100441Scharnier
501100441Scharnierchar *
502100441Scharnierxstrdup(const char *str)
503100441Scharnier{
504100441Scharnier	char *p;
505100441Scharnier
506100441Scharnier	if ((p = strdup(str)) == NULL) {
507100441Scharnier		warnx("strdup failed");
508100441Scharnier		crash();
509100441Scharnier	}
510100441Scharnier	return (p);
511100441Scharnier}
512