entered into RCS
[kopensolaris-gnu/glibc.git] / sunrpc / rpc_util.c
1 /* @(#)rpc_util.c       2.1 88/08/01 4.0 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 #ifndef lint
31 static char sccsid[] = "@(#)rpc_util.c 1.5 87/06/24 (C) 1987 SMI";
32 #endif
33
34 /*
35  * rpc_util.c, Utility routines for the RPC protocol compiler 
36  * Copyright (C) 1987, Sun Microsystems, Inc. 
37  */
38 #include <stdio.h>
39 #include "rpc_scan.h"
40 #include "rpc_parse.h"
41 #include "rpc_util.h"
42
43 char curline[MAXLINESIZE];      /* current read line */
44 char *where = curline;  /* current point in line */
45 int linenum = 0;        /* current line number */
46
47 char *infilename;       /* input filename */
48
49 #define NFILES 4
50 char *outfiles[NFILES]; /* output file names */
51 int nfiles;
52
53 FILE *fout;     /* file pointer of current output */
54 FILE *fin;      /* file pointer of current input */
55
56 list *defined;  /* list of defined things */
57
58 /*
59  * Reinitialize the world 
60  */
61 reinitialize()
62 {
63         bzero(curline, MAXLINESIZE);
64         where = curline;
65         linenum = 0;
66         defined = NULL;
67 }
68
69 /*
70  * string equality 
71  */
72 streq(a, b)
73         char *a;
74         char *b;
75 {
76         return (strcmp(a, b) == 0);
77 }
78
79 /*
80  * find a value in a list 
81  */
82 char *
83 findval(lst, val, cmp)
84         list *lst;
85         char *val;
86         int (*cmp) ();
87
88 {
89         for (; lst != NULL; lst = lst->next) {
90                 if ((*cmp) (lst->val, val)) {
91                         return (lst->val);
92                 }
93         }
94         return (NULL);
95 }
96
97 /*
98  * store a value in a list 
99  */
100 void
101 storeval(lstp, val)
102         list **lstp;
103         char *val;
104 {
105         list **l;
106         list *lst;
107
108         for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
109         lst = ALLOC(list);
110         lst->val = val;
111         lst->next = NULL;
112         *l = lst;
113 }
114
115
116 static
117 findit(def, type)
118         definition *def;
119         char *type;
120 {
121         return (streq(def->def_name, type));
122 }
123
124
125 static char *
126 fixit(type, orig)
127         char *type;
128         char *orig;
129 {
130         definition *def;
131
132         def = (definition *) FINDVAL(defined, type, findit);
133         if (def == NULL || def->def_kind != DEF_TYPEDEF) {
134                 return (orig);
135         }
136         switch (def->def.ty.rel) {
137         case REL_VECTOR:
138                 return (def->def.ty.old_type);
139         case REL_ALIAS:
140                 return (fixit(def->def.ty.old_type, orig));
141         default:
142                 return (orig);
143         }
144 }
145
146 char *
147 fixtype(type)
148         char *type;
149 {
150         return (fixit(type, type));
151 }
152
153 char *
154 stringfix(type)
155         char *type;
156 {
157         if (streq(type, "string")) {
158                 return ("wrapstring");
159         } else {
160                 return (type);
161         }
162 }
163
164 void
165 ptype(prefix, type, follow)
166         char *prefix;
167         char *type;
168         int follow;
169 {
170         if (prefix != NULL) {
171                 if (streq(prefix, "enum")) {
172                         f_print(fout, "enum ");
173                 } else {
174                         f_print(fout, "struct ");
175                 }
176         }
177         if (streq(type, "bool")) {
178                 f_print(fout, "bool_t ");
179         } else if (streq(type, "string")) {
180                 f_print(fout, "char *");
181         } else {
182                 f_print(fout, "%s ", follow ? fixtype(type) : type);
183         }
184 }
185
186
187 static
188 typedefed(def, type)
189         definition *def;
190         char *type;
191 {
192         if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
193                 return (0);
194         } else {
195                 return (streq(def->def_name, type));
196         }
197 }
198
199 isvectordef(type, rel)
200         char *type;
201         relation rel;
202 {
203         definition *def;
204
205         for (;;) {
206                 switch (rel) {
207                 case REL_VECTOR:
208                         return (!streq(type, "string"));
209                 case REL_ARRAY:
210                         return (0);
211                 case REL_POINTER:
212                         return (0);
213                 case REL_ALIAS:
214                         def = (definition *) FINDVAL(defined, type, typedefed);
215                         if (def == NULL) {
216                                 return (0);
217                         }
218                         type = def->def.ty.old_type;
219                         rel = def->def.ty.rel;
220                 }
221         }
222 }
223
224
225 static char *
226 locase(str)
227         char *str;
228 {
229         char c;
230         static char buf[100];
231         char *p = buf;
232
233         while (c = *str++) {
234                 *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
235         }
236         *p = 0;
237         return (buf);
238 }
239
240
241 void
242 pvname(pname, vnum)
243         char *pname;
244         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
254 error(msg)
255         char *msg;
256 {
257         printwhere();
258         f_print(stderr, "%s, line %d: ", infilename, linenum);
259         f_print(stderr, "%s\n", msg);
260         crash();
261 }
262
263 /*
264  * Something went wrong, unlink any files that we may have created and then
265  * die. 
266  */
267 crash()
268 {
269         int i;
270
271         for (i = 0; i < nfiles; i++) {
272                 (void) unlink(outfiles[i]);
273         }
274         exit(1);
275 }
276
277
278 void
279 record_open(file)
280         char *file;
281 {
282         if (nfiles < NFILES) {
283                 outfiles[nfiles++] = file;
284         } else {
285                 f_print(stderr, "too many files!\n");
286                 crash();
287         }
288 }
289
290 static char expectbuf[100];
291 static char *toktostr();
292
293 /*
294  * error, token encountered was not the expected one 
295  */
296 void
297 expected1(exp1)
298         tok_kind exp1;
299 {
300         s_print(expectbuf, "expected '%s'",
301                 toktostr(exp1));
302         error(expectbuf);
303 }
304
305 /*
306  * error, token encountered was not one of two expected ones 
307  */
308 void
309 expected2(exp1, exp2)
310         tok_kind exp1, exp2;
311 {
312         s_print(expectbuf, "expected '%s' or '%s'",
313                 toktostr(exp1),
314                 toktostr(exp2));
315         error(expectbuf);
316 }
317
318 /*
319  * error, token encountered was not one of 3 expected ones 
320  */
321 void
322 expected3(exp1, exp2, exp3)
323         tok_kind exp1, exp2, exp3;
324 {
325         s_print(expectbuf, "expected '%s', '%s' or '%s'",
326                 toktostr(exp1),
327                 toktostr(exp2),
328                 toktostr(exp3));
329         error(expectbuf);
330 }
331
332 void
333 tabify(f, tab)
334         FILE *f;
335         int tab;
336 {
337         while (tab--) {
338                 (void) fputc('\t', f);
339         }
340 }
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_LONG, "long"},
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_EOF, "??????"}
379 };
380
381 static char *
382 toktostr(kind)
383         tok_kind kind;
384 {
385         token *sp;
386
387         for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
388         return (sp->str);
389 }
390
391
392
393 static
394 printbuf()
395 {
396         char c;
397         int i;
398         int cnt;
399
400 #       define TABSIZE 4
401
402         for (i = 0; c = curline[i]; i++) {
403                 if (c == '\t') {
404                         cnt = 8 - (i % TABSIZE);
405                         c = ' ';
406                 } else {
407                         cnt = 1;
408                 }
409                 while (cnt--) {
410                         (void) fputc(c, stderr);
411                 }
412         }
413 }
414
415
416 static
417 printwhere()
418 {
419         int i;
420         char c;
421         int cnt;
422
423         printbuf();
424         for (i = 0; i < where - curline; i++) {
425                 c = curline[i];
426                 if (c == '\t') {
427                         cnt = 8 - (i % TABSIZE);
428                 } else {
429                         cnt = 1;
430                 }
431                 while (cnt--) {
432                         (void) fputc('^', stderr);
433                 }
434         }
435         (void) fputc('\n', stderr);
436 }