Home | History | Annotate | Line # | Download | only in rpcgen
rpc_util.c revision 1.12
      1 /*	$NetBSD: rpc_util.c,v 1.12 2013/08/11 08:03:10 dholland Exp $	*/
      2 /*
      3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
      4  * unrestricted use provided that this legend is included on all tape
      5  * media and as a part of the software program in whole or part.  Users
      6  * may copy or modify Sun RPC without charge, but are not authorized
      7  * to license or distribute it to anyone else except as part of a product or
      8  * program developed by the user or with the express written consent of
      9  * Sun Microsystems, Inc.
     10  *
     11  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
     12  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
     13  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
     14  *
     15  * Sun RPC is provided with no support and without any obligation on the
     16  * part of Sun Microsystems, Inc. to assist in its use, correction,
     17  * modification or enhancement.
     18  *
     19  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
     20  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
     21  * OR ANY PART THEREOF.
     22  *
     23  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
     24  * or profits or other special, indirect and consequential damages, even if
     25  * Sun has been advised of the possibility of such damages.
     26  *
     27  * Sun Microsystems, Inc.
     28  * 2550 Garcia Avenue
     29  * Mountain View, California  94043
     30  */
     31 
     32 #if HAVE_NBTOOL_CONFIG_H
     33 #include "nbtool_config.h"
     34 #endif
     35 
     36 #include <sys/cdefs.h>
     37 #if defined(__RCSID) && !defined(lint)
     38 #if 0
     39 static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
     40 #else
     41 __RCSID("$NetBSD: rpc_util.c,v 1.12 2013/08/11 08:03:10 dholland Exp $");
     42 #endif
     43 #endif
     44 
     45 /*
     46  * rpc_util.c, Utility routines for the RPC protocol compiler
     47  */
     48 #include <stdio.h>
     49 #include <stdlib.h>
     50 #include <unistd.h>
     51 #include <string.h>
     52 #include <ctype.h>
     53 #include "rpc_scan.h"
     54 #include "rpc_parse.h"
     55 #include "rpc_util.h"
     56 
     57 #define ARGEXT "argument"
     58 
     59 static void printwhere __P((void));
     60 
     61 char    curline[MAXLINESIZE];	/* current read line */
     62 char   *where = curline;	/* current point in line */
     63 int     linenum = 0;		/* current line number */
     64 
     65 const char *infilename;		/* input filename */
     66 
     67 #define NFILES 7
     68 static const char *outfiles[NFILES];	/* output file names */
     69 int     nfiles;
     70 
     71 FILE   *fout;			/* file pointer of current output */
     72 FILE   *fin;			/* file pointer of current input */
     73 
     74 list   *defined;		/* list of defined things */
     75 
     76 static const char *toktostr __P((tok_kind));
     77 static void printbuf __P((void));
     78 static void printwhere __P((void));
     79 static int findit __P((definition *, const char *));
     80 static const char *fixit __P((const char *, const char *));
     81 static int typedefed __P((definition *, const char *));
     82 
     83 /*
     84  * Reinitialize the world
     85  */
     86 void
     87 reinitialize(void)
     88 {
     89 	memset(curline, 0, MAXLINESIZE);
     90 	where = curline;
     91 	linenum = 0;
     92 	defined = NULL;
     93 }
     94 /*
     95  * string equality
     96  */
     97 int
     98 streq(const char *a, const char *b)
     99 {
    100 	return (strcmp(a, b) == 0);
    101 }
    102 /*
    103  * find a value in a list
    104  */
    105 definition *
    106 findval(list *lst, const char *val, int (*cmp)(definition *, const char *))
    107 {
    108 
    109 	for (; lst != NULL; lst = lst->next) {
    110 		if ((*cmp) (lst->val, val)) {
    111 			return (lst->val);
    112 		}
    113 	}
    114 	return (NULL);
    115 }
    116 /*
    117  * store a value in a list
    118  */
    119 void
    120 storeval(list **lstp, definition *val)
    121 {
    122 	list  **l;
    123 	list   *lst;
    124 
    125 
    126 	for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
    127 	lst = ALLOC(list);
    128 	lst->val = val;
    129 	lst->next = NULL;
    130 	*l = lst;
    131 }
    132 
    133 static int
    134 findit(definition *def, const char *type)
    135 {
    136 	return (streq(def->def_name, type));
    137 }
    138 
    139 static const char *
    140 fixit(const char *type, const char *orig)
    141 {
    142 	definition *def;
    143 
    144 	def = (definition *) FINDVAL(defined, type, findit);
    145 	if (def == NULL || def->def_kind != DEF_TYPEDEF) {
    146 		return (orig);
    147 	}
    148 	switch (def->def.ty.rel) {
    149 	case REL_VECTOR:
    150 		return (def->def.ty.old_type);
    151 	case REL_ALIAS:
    152 		return (fixit(def->def.ty.old_type, orig));
    153 	default:
    154 		return (orig);
    155 	}
    156 }
    157 
    158 const char *
    159 fixtype(const char *type)
    160 {
    161 	return (fixit(type, type));
    162 }
    163 
    164 const char *
    165 stringfix(const char *type)
    166 {
    167 	if (streq(type, "string")) {
    168 		return ("wrapstring");
    169 	} else {
    170 		return (type);
    171 	}
    172 }
    173 
    174 void
    175 ptype(const char *prefix, const char *type, int follow)
    176 {
    177 	if (prefix != NULL) {
    178 		if (streq(prefix, "enum")) {
    179 			f_print(fout, "enum ");
    180 		} else {
    181 			f_print(fout, "struct ");
    182 		}
    183 	}
    184 	if (streq(type, "bool")) {
    185 		f_print(fout, "bool_t ");
    186 	} else
    187 		if (streq(type, "string")) {
    188 			f_print(fout, "char *");
    189 		} else {
    190 			f_print(fout, "%s ", follow ? fixtype(type) : type);
    191 		}
    192 }
    193 
    194 static int
    195 typedefed(definition *def, const char *type)
    196 {
    197 	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
    198 		return (0);
    199 	} else {
    200 		return (streq(def->def_name, type));
    201 	}
    202 }
    203 
    204 int
    205 isvectordef(const char *type, relation rel)
    206 {
    207 	definition *def;
    208 
    209 	for (;;) {
    210 		switch (rel) {
    211 		case REL_VECTOR:
    212 			return (!streq(type, "string"));
    213 		case REL_ARRAY:
    214 			return (0);
    215 		case REL_POINTER:
    216 			return (0);
    217 		case REL_ALIAS:
    218 			def = (definition *) FINDVAL(defined, type, typedefed);
    219 			if (def == NULL) {
    220 				return (0);
    221 			}
    222 			type = def->def.ty.old_type;
    223 			rel = def->def.ty.rel;
    224 		}
    225 	}
    226 }
    227 
    228 char   *
    229 locase(const char *str)
    230 {
    231 	char    c;
    232 	static char buf[100];
    233 	char   *p = buf;
    234 
    235 	while ((c = *str++) != '\0') {
    236 		*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
    237 	}
    238 	*p = 0;
    239 	return (buf);
    240 }
    241 
    242 void
    243 pvname_svc(const char *pname, const char *vnum)
    244 {
    245 	f_print(fout, "%s_%s_svc", locase(pname), vnum);
    246 }
    247 
    248 void
    249 pvname(const char *pname, const char *vnum)
    250 {
    251 	f_print(fout, "%s_%s", locase(pname), vnum);
    252 }
    253 /*
    254  * print a useful (?) error message, and then die
    255  */
    256 void
    257 error(const char *msg)
    258 {
    259 	printwhere();
    260 	f_print(stderr, "%s, line %d: ", infilename, linenum);
    261 	f_print(stderr, "%s\n", msg);
    262 	crash();
    263 }
    264 /*
    265  * Something went wrong, unlink any files that we may have created and then
    266  * die.
    267  */
    268 void
    269 crash(void)
    270 {
    271 	int     i;
    272 
    273 	for (i = 0; i < nfiles; i++) {
    274 		(void) unlink(outfiles[i]);
    275 	}
    276 	exit(1);
    277 }
    278 
    279 void
    280 record_open(const char *file)
    281 {
    282 	if (nfiles < NFILES) {
    283 		outfiles[nfiles++] = file;
    284 	} else {
    285 		f_print(stderr, "too many files!\n");
    286 		crash();
    287 	}
    288 }
    289 
    290 static char expectbuf[100];
    291 
    292 /*
    293  * error, token encountered was not the expected one
    294  */
    295 void
    296 expected1(tok_kind exp1)
    297 {
    298 	s_print(expectbuf, "expected '%s'",
    299 	    toktostr(exp1));
    300 	error(expectbuf);
    301 }
    302 /*
    303  * error, token encountered was not one of two expected ones
    304  */
    305 void
    306 expected2(tok_kind exp1, tok_kind exp2)
    307 {
    308 	s_print(expectbuf, "expected '%s' or '%s'",
    309 	    toktostr(exp1),
    310 	    toktostr(exp2));
    311 	error(expectbuf);
    312 }
    313 /*
    314  * error, token encountered was not one of 3 expected ones
    315  */
    316 void
    317 expected3(tok_kind exp1, tok_kind exp2, tok_kind exp3)
    318 {
    319 	s_print(expectbuf, "expected '%s', '%s' or '%s'",
    320 	    toktostr(exp1),
    321 	    toktostr(exp2),
    322 	    toktostr(exp3));
    323 	error(expectbuf);
    324 }
    325 
    326 void
    327 tabify(FILE *f, int tab)
    328 {
    329 	while (tab--) {
    330 		(void) fputc('\t', f);
    331 	}
    332 }
    333 
    334 
    335 static token tokstrings[] = {
    336 	{TOK_IDENT, "identifier"},
    337 	{TOK_CONST, "const"},
    338 	{TOK_RPAREN, ")"},
    339 	{TOK_LPAREN, "("},
    340 	{TOK_RBRACE, "}"},
    341 	{TOK_LBRACE, "{"},
    342 	{TOK_LBRACKET, "["},
    343 	{TOK_RBRACKET, "]"},
    344 	{TOK_STAR, "*"},
    345 	{TOK_COMMA, ","},
    346 	{TOK_EQUAL, "="},
    347 	{TOK_COLON, ":"},
    348 	{TOK_SEMICOLON, ";"},
    349 	{TOK_UNION, "union"},
    350 	{TOK_STRUCT, "struct"},
    351 	{TOK_SWITCH, "switch"},
    352 	{TOK_CASE, "case"},
    353 	{TOK_DEFAULT, "default"},
    354 	{TOK_ENUM, "enum"},
    355 	{TOK_TYPEDEF, "typedef"},
    356 	{TOK_INT, "int"},
    357 	{TOK_SHORT, "short"},
    358 	{TOK_LONG, "long"},
    359 	{TOK_UNSIGNED, "unsigned"},
    360 	{TOK_DOUBLE, "double"},
    361 	{TOK_FLOAT, "float"},
    362 	{TOK_CHAR, "char"},
    363 	{TOK_STRING, "string"},
    364 	{TOK_OPAQUE, "opaque"},
    365 	{TOK_BOOL, "bool"},
    366 	{TOK_VOID, "void"},
    367 	{TOK_PROGRAM, "program"},
    368 	{TOK_VERSION, "version"},
    369 	{TOK_EOF, "??????"}
    370 };
    371 
    372 static const char *
    373 toktostr(tok_kind kind)
    374 {
    375 	token  *sp;
    376 
    377 	for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
    378 	return (sp->str);
    379 }
    380 
    381 static void
    382 printbuf(void)
    383 {
    384 	char    c;
    385 	int     i;
    386 	int     cnt;
    387 
    388 #define TABSIZE 4
    389 
    390 	for (i = 0; (c = curline[i]) != '\0'; i++) {
    391 		if (c == '\t') {
    392 			cnt = 8 - (i % TABSIZE);
    393 			c = ' ';
    394 		} else {
    395 			cnt = 1;
    396 		}
    397 		while (cnt--) {
    398 			(void) fputc(c, stderr);
    399 		}
    400 	}
    401 }
    402 
    403 static void
    404 printwhere(void)
    405 {
    406 	int     i;
    407 	char    c;
    408 	int     cnt;
    409 
    410 	printbuf();
    411 	for (i = 0; i < where - curline; i++) {
    412 		c = curline[i];
    413 		if (c == '\t') {
    414 			cnt = 8 - (i % TABSIZE);
    415 		} else {
    416 			cnt = 1;
    417 		}
    418 		while (cnt--) {
    419 			(void) fputc('^', stderr);
    420 		}
    421 	}
    422 	(void) fputc('\n', stderr);
    423 }
    424 
    425 char   *
    426 make_argname(const char *pname, const char *vname)
    427 {
    428 	char   *name;
    429 	size_t len;
    430 
    431 	len = strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3;
    432 	name = malloc(len);
    433 	if (!name) {
    434 		fprintf(stderr, "failed in malloc");
    435 		exit(1);
    436 	}
    437 	snprintf(name, len, "%s_%s_%s", locase(pname), vname, ARGEXT);
    438 	return (name);
    439 }
    440 
    441 bas_type *typ_list_h;
    442 bas_type *typ_list_t;
    443 
    444 void
    445 add_type(int len, const char *type)
    446 {
    447 	bas_type *ptr;
    448 
    449 	if ((ptr = malloc(sizeof(bas_type))) == NULL) {
    450 		fprintf(stderr, "failed in malloc");
    451 		exit(1);
    452 	}
    453 	ptr->name = type;
    454 	ptr->length = len;
    455 	ptr->next = NULL;
    456 	if (typ_list_t == NULL) {
    457 		typ_list_t = ptr;
    458 		typ_list_h = ptr;
    459 	} else {
    460 		typ_list_t->next = ptr;
    461 		typ_list_t = ptr;
    462 	}
    463 }
    464 
    465 bas_type *
    466 find_type(const char *type)
    467 {
    468 	bas_type *ptr;
    469 
    470 	ptr = typ_list_h;
    471 
    472 
    473 	while (ptr != NULL) {
    474 		if (strcmp(ptr->name, type) == 0)
    475 			return (ptr);
    476 		else
    477 			ptr = ptr->next;
    478 	}
    479 	return (NULL);
    480 }
    481