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