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