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