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