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