rpc_util.c revision 100441
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
3012798Swpaul#ident	"@(#)rpc_util.c	1.14	93/07/05 SMI"
3112798Swpaul
32100441Scharnier#if 0
331897Swollman#ifndef lint
3412798Swpaulstatic char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
351897Swollman#endif
3627935Scharnier#endif
371897Swollman
38100441Scharnier#include <sys/cdefs.h>
39100441Scharnier__FBSDID("$FreeBSD: head/usr.bin/rpcgen/rpc_util.c 100441 2002-07-21 12:55:04Z charnier $");
40100441Scharnier
411897Swollman/*
428874Srgrimes * rpc_util.c, Utility routines for the RPC protocol compiler
4312798Swpaul * Copyright (C) 1989, Sun Microsystems, Inc.
441897Swollman */
4527935Scharnier#include <err.h>
4627935Scharnier#include <ctype.h>
471897Swollman#include <stdio.h>
4817142Sjkh#include <string.h>
4917142Sjkh#include <unistd.h>
501897Swollman#include "rpc_scan.h"
511897Swollman#include "rpc_parse.h"
521897Swollman#include "rpc_util.h"
531897Swollman
5412798Swpaul#define	ARGEXT "argument"
5512798Swpaul
561897Swollmanchar curline[MAXLINESIZE];	/* current read line */
5712798Swpaulchar *where = curline;		/* current point in line */
5812798Swpaulint linenum = 0;		/* current line number */
591897Swollman
6012798Swpaulchar *infilename;		/* input filename */
611897Swollman
6212798Swpaul#define	NFILES   7
6312798Swpaulchar *outfiles[NFILES];		/* output file names */
641897Swollmanint nfiles;
651897Swollman
6612798SwpaulFILE *fout;			/* file pointer of current output */
6712798SwpaulFILE *fin;			/* file pointer of current input */
681897Swollman
6912798Swpaullist *defined;			/* list of defined things */
701897Swollman
7192921Simpstatic void printwhere( void );
721897Swollman
731897Swollman/*
748874Srgrimes * Reinitialize the world
751897Swollman */
7617142Sjkhvoid
771897Swollmanreinitialize()
781897Swollman{
7912798Swpaul	memset(curline, 0, MAXLINESIZE);
801897Swollman	where = curline;
811897Swollman	linenum = 0;
821897Swollman	defined = NULL;
831897Swollman}
841897Swollman
851897Swollman/*
868874Srgrimes * string equality
871897Swollman */
8817142Sjkhint
891897Swollmanstreq(a, b)
901897Swollman	char *a;
911897Swollman	char *b;
921897Swollman{
931897Swollman	return (strcmp(a, b) == 0);
941897Swollman}
951897Swollman
961897Swollman/*
978874Srgrimes * find a value in a list
981897Swollman */
9912798Swpauldefinition *
1001897Swollmanfindval(lst, val, cmp)
1011897Swollman	list *lst;
1021897Swollman	char *val;
1031897Swollman	int (*cmp) ();
1041897Swollman
1051897Swollman{
1061897Swollman	for (; lst != NULL; lst = lst->next) {
1071897Swollman		if ((*cmp) (lst->val, val)) {
1081897Swollman			return (lst->val);
1091897Swollman		}
1101897Swollman	}
1111897Swollman	return (NULL);
1121897Swollman}
1131897Swollman
1141897Swollman/*
1158874Srgrimes * store a value in a list
1161897Swollman */
1171897Swollmanvoid
1181897Swollmanstoreval(lstp, val)
1191897Swollman	list **lstp;
12012798Swpaul	definition *val;
1211897Swollman{
1221897Swollman	list **l;
1231897Swollman	list *lst;
1241897Swollman
1251897Swollman	for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
126100441Scharnier	lst = XALLOC(list);
1271897Swollman	lst->val = val;
1281897Swollman	lst->next = NULL;
1291897Swollman	*l = lst;
1301897Swollman}
1311897Swollman
13217142Sjkhstatic int
1331897Swollmanfindit(def, type)
1341897Swollman	definition *def;
1351897Swollman	char *type;
1361897Swollman{
1371897Swollman	return (streq(def->def_name, type));
1381897Swollman}
1391897Swollman
1401897Swollmanstatic char *
1411897Swollmanfixit(type, orig)
1421897Swollman	char *type;
1431897Swollman	char *orig;
1441897Swollman{
1451897Swollman	definition *def;
1461897Swollman
1471897Swollman	def = (definition *) FINDVAL(defined, type, findit);
1481897Swollman	if (def == NULL || def->def_kind != DEF_TYPEDEF) {
1491897Swollman		return (orig);
1501897Swollman	}
1511897Swollman	switch (def->def.ty.rel) {
1521897Swollman	case REL_VECTOR:
15312798Swpaul		if (streq(def->def.ty.old_type, "opaque"))
15412798Swpaul			return ("char");
15512798Swpaul		else
15612798Swpaul			return (def->def.ty.old_type);
15712798Swpaul
1581897Swollman	case REL_ALIAS:
1591897Swollman		return (fixit(def->def.ty.old_type, orig));
1601897Swollman	default:
1611897Swollman		return (orig);
1621897Swollman	}
1631897Swollman}
1641897Swollman
1651897Swollmanchar *
1661897Swollmanfixtype(type)
1671897Swollman	char *type;
1681897Swollman{
1691897Swollman	return (fixit(type, type));
1701897Swollman}
1711897Swollman
1721897Swollmanchar *
1731897Swollmanstringfix(type)
1741897Swollman	char *type;
1751897Swollman{
1761897Swollman	if (streq(type, "string")) {
1771897Swollman		return ("wrapstring");
1781897Swollman	} else {
1791897Swollman		return (type);
1801897Swollman	}
1811897Swollman}
1821897Swollman
1831897Swollmanvoid
1841897Swollmanptype(prefix, type, follow)
1851897Swollman	char *prefix;
1861897Swollman	char *type;
1871897Swollman	int follow;
1881897Swollman{
1891897Swollman	if (prefix != NULL) {
1901897Swollman		if (streq(prefix, "enum")) {
1911897Swollman			f_print(fout, "enum ");
1921897Swollman		} else {
1931897Swollman			f_print(fout, "struct ");
1941897Swollman		}
1951897Swollman	}
1961897Swollman	if (streq(type, "bool")) {
1971897Swollman		f_print(fout, "bool_t ");
1981897Swollman	} else if (streq(type, "string")) {
1991897Swollman		f_print(fout, "char *");
2001897Swollman	} else {
2011897Swollman		f_print(fout, "%s ", follow ? fixtype(type) : type);
2021897Swollman	}
2031897Swollman}
2041897Swollman
20517142Sjkhstatic int
2061897Swollmantypedefed(def, type)
2071897Swollman	definition *def;
2081897Swollman	char *type;
2091897Swollman{
2101897Swollman	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
2111897Swollman		return (0);
2121897Swollman	} else {
2131897Swollman		return (streq(def->def_name, type));
2141897Swollman	}
2151897Swollman}
2161897Swollman
21717142Sjkhint
2181897Swollmanisvectordef(type, rel)
2191897Swollman	char *type;
2201897Swollman	relation rel;
2211897Swollman{
2221897Swollman	definition *def;
2231897Swollman
2241897Swollman	for (;;) {
2251897Swollman		switch (rel) {
2261897Swollman		case REL_VECTOR:
2271897Swollman			return (!streq(type, "string"));
2281897Swollman		case REL_ARRAY:
2291897Swollman			return (0);
2301897Swollman		case REL_POINTER:
2311897Swollman			return (0);
2321897Swollman		case REL_ALIAS:
2331897Swollman			def = (definition *) FINDVAL(defined, type, typedefed);
2341897Swollman			if (def == NULL) {
2351897Swollman				return (0);
2361897Swollman			}
2371897Swollman			type = def->def.ty.old_type;
2381897Swollman			rel = def->def.ty.rel;
2391897Swollman		}
2401897Swollman	}
24117142Sjkh
24217142Sjkh	return (0);
2431897Swollman}
2441897Swollman
24512798Swpaulchar *
2461897Swollmanlocase(str)
2471897Swollman	char *str;
2481897Swollman{
2491897Swollman	char c;
2501897Swollman	static char buf[100];
2511897Swollman	char *p = buf;
2521897Swollman
25317142Sjkh	while ( (c = *str++) ) {
2541897Swollman		*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
2551897Swollman	}
2561897Swollman	*p = 0;
2571897Swollman	return (buf);
2581897Swollman}
2591897Swollman
26012798Swpaulvoid
26112798Swpaulpvname_svc(pname, vnum)
26212798Swpaul	char *pname;
26312798Swpaul	char *vnum;
26412798Swpaul{
26512798Swpaul	f_print(fout, "%s_%s_svc", locase(pname), vnum);
26612798Swpaul}
2671897Swollman
2681897Swollmanvoid
2691897Swollmanpvname(pname, vnum)
2701897Swollman	char *pname;
2711897Swollman	char *vnum;
2721897Swollman{
2731897Swollman	f_print(fout, "%s_%s", locase(pname), vnum);
2741897Swollman}
2751897Swollman
2761897Swollman/*
2778874Srgrimes * print a useful (?) error message, and then die
2781897Swollman */
2791897Swollmanvoid
2801897Swollmanerror(msg)
2811897Swollman	char *msg;
2821897Swollman{
2831897Swollman	printwhere();
28427935Scharnier	warnx("%s, line %d: %s", infilename, linenum, msg);
2851897Swollman	crash();
2861897Swollman}
2871897Swollman
2881897Swollman/*
2891897Swollman * Something went wrong, unlink any files that we may have created and then
2908874Srgrimes * die.
2911897Swollman */
29217142Sjkhvoid
2931897Swollmancrash()
2941897Swollman{
2951897Swollman	int i;
2961897Swollman
2971897Swollman	for (i = 0; i < nfiles; i++) {
2981897Swollman		(void) unlink(outfiles[i]);
2991897Swollman	}
3001897Swollman	exit(1);
3011897Swollman}
3021897Swollman
3031897Swollmanvoid
3041897Swollmanrecord_open(file)
3051897Swollman	char *file;
3061897Swollman{
3071897Swollman	if (nfiles < NFILES) {
3081897Swollman		outfiles[nfiles++] = file;
3091897Swollman	} else {
31027935Scharnier		warnx("too many files");
3111897Swollman		crash();
3121897Swollman	}
3131897Swollman}
3141897Swollman
3151897Swollmanstatic char expectbuf[100];
3161897Swollmanstatic char *toktostr();
3171897Swollman
3181897Swollman/*
3198874Srgrimes * error, token encountered was not the expected one
3201897Swollman */
3211897Swollmanvoid
3221897Swollmanexpected1(exp1)
3231897Swollman	tok_kind exp1;
3241897Swollman{
3251897Swollman	s_print(expectbuf, "expected '%s'",
3261897Swollman		toktostr(exp1));
3271897Swollman	error(expectbuf);
3281897Swollman}
3291897Swollman
3301897Swollman/*
3318874Srgrimes * error, token encountered was not one of two expected ones
3321897Swollman */
3331897Swollmanvoid
3341897Swollmanexpected2(exp1, exp2)
3351897Swollman	tok_kind exp1, exp2;
3361897Swollman{
3371897Swollman	s_print(expectbuf, "expected '%s' or '%s'",
3381897Swollman		toktostr(exp1),
3391897Swollman		toktostr(exp2));
3401897Swollman	error(expectbuf);
3411897Swollman}
3421897Swollman
3431897Swollman/*
3448874Srgrimes * error, token encountered was not one of 3 expected ones
3451897Swollman */
3461897Swollmanvoid
3471897Swollmanexpected3(exp1, exp2, exp3)
3481897Swollman	tok_kind exp1, exp2, exp3;
3491897Swollman{
3501897Swollman	s_print(expectbuf, "expected '%s', '%s' or '%s'",
3511897Swollman		toktostr(exp1),
3521897Swollman		toktostr(exp2),
3531897Swollman		toktostr(exp3));
3541897Swollman	error(expectbuf);
3551897Swollman}
3561897Swollman
3571897Swollmanvoid
3581897Swollmantabify(f, tab)
3591897Swollman	FILE *f;
3601897Swollman	int tab;
3611897Swollman{
3621897Swollman	while (tab--) {
3631897Swollman		(void) fputc('\t', f);
3641897Swollman	}
3651897Swollman}
3661897Swollman
3671897Swollman
3681897Swollmanstatic token tokstrings[] = {
36912798Swpaul			{TOK_IDENT, "identifier"},
37012798Swpaul			{TOK_CONST, "const"},
37112798Swpaul			{TOK_RPAREN, ")"},
37212798Swpaul			{TOK_LPAREN, "("},
37312798Swpaul			{TOK_RBRACE, "}"},
37412798Swpaul			{TOK_LBRACE, "{"},
37512798Swpaul			{TOK_LBRACKET, "["},
37612798Swpaul			{TOK_RBRACKET, "]"},
37712798Swpaul			{TOK_STAR, "*"},
37812798Swpaul			{TOK_COMMA, ","},
37912798Swpaul			{TOK_EQUAL, "="},
38012798Swpaul			{TOK_COLON, ":"},
38112798Swpaul			{TOK_SEMICOLON, ";"},
38212798Swpaul			{TOK_UNION, "union"},
38312798Swpaul			{TOK_STRUCT, "struct"},
38412798Swpaul			{TOK_SWITCH, "switch"},
38512798Swpaul			{TOK_CASE, "case"},
38612798Swpaul			{TOK_DEFAULT, "default"},
38712798Swpaul			{TOK_ENUM, "enum"},
38812798Swpaul			{TOK_TYPEDEF, "typedef"},
38912798Swpaul			{TOK_INT, "int"},
39012798Swpaul			{TOK_SHORT, "short"},
39112798Swpaul			{TOK_LONG, "long"},
39212798Swpaul			{TOK_UNSIGNED, "unsigned"},
39312798Swpaul			{TOK_DOUBLE, "double"},
39412798Swpaul			{TOK_FLOAT, "float"},
39512798Swpaul			{TOK_CHAR, "char"},
39612798Swpaul			{TOK_STRING, "string"},
39712798Swpaul			{TOK_OPAQUE, "opaque"},
39812798Swpaul			{TOK_BOOL, "bool"},
39912798Swpaul			{TOK_VOID, "void"},
40012798Swpaul			{TOK_PROGRAM, "program"},
40112798Swpaul			{TOK_VERSION, "version"},
40212798Swpaul			{TOK_EOF, "??????"}
4031897Swollman};
4041897Swollman
4051897Swollmanstatic char *
4061897Swollmantoktostr(kind)
4071897Swollman	tok_kind kind;
4081897Swollman{
4091897Swollman	token *sp;
4101897Swollman
4111897Swollman	for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
4121897Swollman	return (sp->str);
4131897Swollman}
4141897Swollman
41517142Sjkhstatic void
4161897Swollmanprintbuf()
4171897Swollman{
4181897Swollman	char c;
4191897Swollman	int i;
4201897Swollman	int cnt;
4211897Swollman
4221897Swollman#	define TABSIZE 4
4231897Swollman
42417142Sjkh	for (i = 0; (c = curline[i]); i++) {
4251897Swollman		if (c == '\t') {
4261897Swollman			cnt = 8 - (i % TABSIZE);
4271897Swollman			c = ' ';
4281897Swollman		} else {
4291897Swollman			cnt = 1;
4301897Swollman		}
4311897Swollman		while (cnt--) {
4321897Swollman			(void) fputc(c, stderr);
4331897Swollman		}
4341897Swollman	}
4351897Swollman}
4361897Swollman
43717142Sjkhstatic void
4381897Swollmanprintwhere()
4391897Swollman{
4401897Swollman	int i;
4411897Swollman	char c;
4421897Swollman	int cnt;
4431897Swollman
4441897Swollman	printbuf();
4451897Swollman	for (i = 0; i < where - curline; i++) {
4461897Swollman		c = curline[i];
4471897Swollman		if (c == '\t') {
4481897Swollman			cnt = 8 - (i % TABSIZE);
4491897Swollman		} else {
4501897Swollman			cnt = 1;
4511897Swollman		}
4521897Swollman		while (cnt--) {
4531897Swollman			(void) fputc('^', stderr);
4541897Swollman		}
4551897Swollman	}
4561897Swollman	(void) fputc('\n', stderr);
4571897Swollman}
45812798Swpaul
45912798Swpaulchar *
46012798Swpaulmake_argname(pname, vname)
46112798Swpaul    char *pname;
46212798Swpaul    char *vname;
46312798Swpaul{
46412798Swpaul	char *name;
46512798Swpaul
466100441Scharnier	name = xmalloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
46712798Swpaul	sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
46812798Swpaul	return (name);
46912798Swpaul}
47012798Swpaul
47112798Swpaulbas_type *typ_list_h;
47212798Swpaulbas_type *typ_list_t;
47312798Swpaul
47417142Sjkhvoid
47512798Swpauladd_type(len, type)
47612798Swpaulint len;
47712798Swpaulchar *type;
47812798Swpaul{
47912798Swpaul	bas_type *ptr;
48012798Swpaul
481100441Scharnier	ptr = XALLOC(bas_type);
48212798Swpaul
48312798Swpaul	ptr->name = type;
48412798Swpaul	ptr->length = len;
48512798Swpaul	ptr->next = NULL;
48612798Swpaul	if (typ_list_t == NULL)
48712798Swpaul	{
48812798Swpaul
48912798Swpaul		typ_list_t = ptr;
49012798Swpaul		typ_list_h = ptr;
49112798Swpaul	}
49212798Swpaul	else
49312798Swpaul	{
49412798Swpaul		typ_list_t->next = ptr;
49512798Swpaul		typ_list_t = ptr;
49612798Swpaul	};
49712798Swpaul}
49812798Swpaul
49912798Swpaul
50012798Swpaulbas_type *find_type(type)
50112798Swpaulchar *type;
50212798Swpaul{
50312798Swpaul	bas_type * ptr;
50412798Swpaul
50512798Swpaul	ptr = typ_list_h;
50612798Swpaul	while (ptr != NULL)
50712798Swpaul	{
50812798Swpaul		if (strcmp(ptr->name, type) == 0)
50912798Swpaul			return (ptr);
51012798Swpaul		else
51112798Swpaul			ptr = ptr->next;
51212798Swpaul	};
51312798Swpaul	return (NULL);
51412798Swpaul}
515100441Scharnier
516100441Scharniervoid *
517100441Scharnierxmalloc(size_t size)
518100441Scharnier{
519100441Scharnier	void *p;
520100441Scharnier
521100441Scharnier	if ((p = malloc(size)) == NULL) {
522100441Scharnier		warnx("malloc failed");
523100441Scharnier		crash();
524100441Scharnier	}
525100441Scharnier	return (p);
526100441Scharnier}
527100441Scharnier
528100441Scharniervoid *
529100441Scharnierxrealloc(void *ptr, size_t size)
530100441Scharnier{
531100441Scharnier	void *p;
532100441Scharnier
533100441Scharnier	if ((p = realloc(ptr, size)) == NULL) {
534100441Scharnier		warnx("realloc failed");
535100441Scharnier		crash();
536100441Scharnier	}
537100441Scharnier	return (p);
538100441Scharnier}
539100441Scharnier
540100441Scharnierchar *
541100441Scharnierxstrdup(const char *str)
542100441Scharnier{
543100441Scharnier	char *p;
544100441Scharnier
545100441Scharnier	if ((p = strdup(str)) == NULL) {
546100441Scharnier		warnx("strdup failed");
547100441Scharnier		crash();
548100441Scharnier	}
549100441Scharnier	return (p);
550100441Scharnier}
551