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