pull-prototypes-to-head-20020821
[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("$Header$");
39
40 #include <stdio.h>
41 #ifdef HAVE_STRING_H
42 #include <string.h>
43 #else
44 #ifdef HAVE_STRINGS_H
45 #include <strings.h>
46 #endif
47 #endif
48 #ifdef HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif
51 #ifdef HAVE_STDLIB_H
52 #include <stdlib.h>
53 #endif
54 #include "rpc_scan.h"
55 #include "rpc_parse.h"
56 #include "rpc_util.h"
57
58 char curline[MAXLINESIZE];      /* current read line */
59 char *where = curline;  /* current point in line */
60 int linenum = 0;        /* current line number */
61
62 char *infilename;       /* input filename */
63
64 #define NFILES 6
65 char *outfiles[NFILES]; /* output file names */
66 int nfiles;
67
68 FILE *fout;     /* file pointer of current output */
69 FILE *fin;      /* file pointer of current input */
70
71 list *defined;  /* list of defined things */
72
73 /* static prototypes */
74 static int findit(definition *def, char *type);
75 static char *fixit(char *type, char *orig);
76 static int typedefed(definition *def, char *type);
77 static char *locase(char *str);
78 static char *toktostr(tok_kind kind);
79 static void printbuf(void);
80 static void printwhere(void);
81
82
83 /*
84  * Reinitialize the world 
85  */
86 void reinitialize(void)
87 {
88     int i;
89         memset(curline, 0, MAXLINESIZE);
90         where = curline;
91         linenum = 0;
92         defined = NULL;
93         special_defined = typedef_defined = uniondef_defined = NULL;
94         PackageIndex = -1;
95         master_opcodenumber= 99999;
96         master_highest_opcode = 0;
97         no_of_stat_funcs = 0;
98         for(i=0;i<MAX_PACKAGES;i++) {
99             no_of_stat_funcs_header[i] = 0;
100         }
101 }
102
103 /*
104  * string equality 
105  */
106 int streq(char *a, char *b)
107 {
108         return (strcmp(a, b) == 0);
109 }
110
111 /*
112  * find a value in a list 
113  */
114 char *findval(list *lst, char *val, int (*cmp)(definition *def, char *type))
115 {
116         for (; lst != NULL; lst = lst->next) {
117                 if ((*cmp) ((definition *) lst->val, val)) {
118                         return (lst->val);
119                 }
120         }
121         return (NULL);
122 }
123
124 /*
125  * store a value in a list 
126  */
127 void storeval(list **lstp, char *val)
128 {
129         list **l;
130         list *lst;
131
132         for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
133         lst = ALLOC(list);
134         lst->val = val;
135         lst->next = NULL;
136         *l = lst;
137 }
138
139
140 static int findit(definition *def, char *type)
141 {
142         return (streq(def->def_name, type));
143 }
144
145
146 static char *fixit(char *type, char *orig)
147 {
148         definition *def;
149
150         def = (definition *) FINDVAL(defined, type, findit);
151         if (def == NULL || def->def_kind != DEF_TYPEDEF) {
152                 return (orig);
153         }
154         switch (def->def.ty.rel) {
155         case REL_VECTOR:
156                 return (def->def.ty.old_type);
157         case REL_ALIAS:
158                 return (fixit(def->def.ty.old_type, orig));
159         default:
160                 return (orig);
161         }
162 }
163
164 char *fixtype(char *type)
165 {
166         return (fixit(type, type));
167 }
168
169 char *stringfix(char *type)
170 {
171         if (streq(type, "string")) {
172                 return ("wrapstring");
173         } else {
174                 return (type);
175         }
176 }
177
178 void ptype(char *prefix, char *type, int follow)
179 {
180         if (prefix != NULL) {
181                 if (streq(prefix, "enum")) {
182                         f_print(fout, "enum ");
183                 } else {
184                         f_print(fout, "struct ");
185                 }
186         }
187         if (streq(type, "bool")) {
188                 f_print(fout, "bool_t ");
189         } else if (streq(type, "string")) {
190                 f_print(fout, "char *");
191         } else {
192                 f_print(fout, "%s ", follow ? fixtype(type) : type);
193         }
194 }
195
196
197 static int typedefed(definition *def, char *type)
198 {
199         if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
200                 return (0);
201         } else {
202                 return (streq(def->def_name, type));
203         }
204 }
205
206 int isvectordef(char *type, relation rel)
207 {
208         definition *def;
209
210         for (;;) {
211                 switch (rel) {
212                 case REL_VECTOR:
213                         return (!streq(type, "string"));
214                 case REL_ARRAY:
215                         return (0);
216                 case REL_POINTER:
217                         return (0);
218                 case REL_ALIAS:
219                         def = (definition *) FINDVAL(defined, type, typedefed);
220                         if (def == NULL) {
221                                 return (0);
222                         }
223                         type = def->def.ty.old_type;
224                         rel = def->def.ty.rel;
225                 }
226         }
227 }
228
229
230 static char *locase(char *str)
231 {
232         char c;
233         static char buf[100];
234         char *p = buf;
235
236         while ((c = *str++)) {
237                 *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
238         }
239         *p = 0;
240         return (buf);
241 }
242
243
244 void pvname(char *pname, char *vnum)
245 {
246         f_print(fout, "%s_%s", locase(pname), vnum);
247 }
248
249
250 /*
251  * print a useful (?) error message, and then die 
252  */
253 void error(char *msg)
254 {
255         printwhere();
256         f_print(stderr, "%s, line %d: ", infilename, linenum);
257         f_print(stderr, "%s\n", msg);
258         crash();
259 }
260
261 /*
262  * Something went wrong, unlink any files that we may have created and then
263  * die. 
264  */
265 void 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
276 void record_open(char *file)
277 {
278         if (nfiles < NFILES) {
279                 outfiles[nfiles++] = file;
280         } else {
281                 f_print(stderr, "too many files!\n");
282                 crash();
283         }
284 }
285
286 /* buffer shared for all of the expected* routines */
287 static char expectbuf[100];
288
289 /*
290  * error, token encountered was not the expected one 
291  */
292 void expected1(tok_kind exp1)
293 {
294         s_print(expectbuf, "expected '%s'",
295                 toktostr(exp1));
296         error(expectbuf);
297 }
298
299 /*
300  * error, token encountered was not one of two expected ones 
301  */
302 void 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 {
315         s_print(expectbuf, "expected '%s', '%s' or '%s'",
316                 toktostr(exp1),
317                 toktostr(exp2),
318                 toktostr(exp3));
319         error(expectbuf);
320 }
321
322
323 /*
324  * error, token encountered was not one of 4 expected ones
325  */
326 void expected4(tok_kind exp1, tok_kind exp2, tok_kind exp3, tok_kind exp4)
327 {
328         sprintf(expectbuf,"expected '%s', '%s', '%s', or '%s'",
329                 toktostr(exp1),
330                 toktostr(exp2),
331                 toktostr(exp3),
332                 toktostr(exp4));
333         error(expectbuf);
334 }
335
336 void tabify(FILE *f, int tab)
337 {
338         if (scan_print)
339         while (tab--) {
340                 (void) fputc('\t', f);
341         }
342 }
343
344 static token tokstrings[] = {
345         { TOK_IDENT, "identifier"},
346         { TOK_CONST, "const"},
347         { TOK_RPAREN, ")"},
348         { TOK_LPAREN, "("},
349         { TOK_RBRACE, "}"},
350         { TOK_LBRACE, "{"},
351         { TOK_LBRACKET, "["},
352         { TOK_RBRACKET, "]"},
353         { TOK_STAR, "*"},
354         { TOK_COMMA, ","},
355         { TOK_EQUAL, "="},
356         { TOK_COLON, ":"},
357         { TOK_SEMICOLON, ";"},
358         { TOK_UNION, "union"},
359         { TOK_STRUCT, "struct"},
360         { TOK_SWITCH, "switch"},
361         { TOK_CASE, "case"},
362         { TOK_DEFAULT, "default"},
363         { TOK_ENUM, "enum"},
364         { TOK_TYPEDEF, "typedef"},
365         { TOK_INT, "int"},
366         { TOK_SHORT, "short"},
367         { TOK_INT32, "afs_int32"},      /* XXX */
368         { TOK_UNSIGNED, "unsigned"},
369         { TOK_DOUBLE, "double"},
370         { TOK_FLOAT, "float"},
371         { TOK_CHAR, "char"},
372         { TOK_STRING, "string"},
373         { TOK_OPAQUE, "opaque"},
374         { TOK_BOOL, "bool"},
375         { TOK_VOID, "void"},
376         { TOK_PROGRAM, "program"},
377         { TOK_VERSION, "version"},
378         { TOK_PACKAGE, "package" },
379         { TOK_PREFIX, "prefix" },
380         { TOK_STATINDEX, "statindex" },
381         { TOK_SPECIAL, "special" },
382         { TOK_STARTINGOPCODE, "startingopcode" },
383         { TOK_CUSTOMIZED, "customized" },
384         { TOK_PROC, "proc" },
385         { TOK_SPLITPREFIX, "splitprefix" },
386         { TOK_SPLIT, "split" },
387         { TOK_MULTI, "multi" },
388         { TOK_IN,   "IN" },
389         { TOK_OUT,  "OUT" },
390         { TOK_INOUT, "INOUT" },
391         { TOK_AFSUUID, "afsUUID" },
392         { TOK_EOF, "??????"}
393 };
394
395 static char *toktostr(tok_kind kind)
396 {
397         token *sp;
398
399         for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
400         return (sp->str);
401 }
402
403
404
405 static void printbuf(void)
406 {
407         char c;
408         int i;
409         int cnt;
410
411 #       define TABSIZE 4
412
413         for (i = 0; (c = curline[i]); i++) {
414                 if (c == '\t') {
415                         cnt = 8 - (i % TABSIZE);
416                         c = ' ';
417                 } else {
418                         cnt = 1;
419                 }
420                 while (cnt--) {
421                         fputc(c, stderr);
422                 }
423         }
424 }
425
426
427 static void printwhere(void)
428 {
429         int i;
430         char c;
431         int cnt;
432
433         printbuf();
434         for (i = 0; i < where - curline; i++) {
435                 c = curline[i];
436                 if (c == '\t') {
437                         cnt = 8 - (i % TABSIZE);
438                 } else {
439                         cnt = 1;
440                 }
441                 while (cnt--) {
442                         fputc('^', stderr);
443                 }
444         }
445         fputc('\n', stderr);
446 }