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