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