update from main archive 961016
[kopensolaris-gnu/glibc.git] / sunrpc / rpc_util.c
1 /*
2  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3  * unrestricted use provided that this legend is included on all tape
4  * media and as a part of the software program in whole or part.  Users
5  * may copy or modify Sun RPC without charge, but are not authorized
6  * to license or distribute it to anyone else except as part of a product or
7  * program developed by the user or with the express written consent of
8  * Sun Microsystems, Inc.
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  * From: @(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI
33  */
34 char util_rcsid[] =
35   "$Id$";
36
37 /*
38  * rpc_util.c, Utility routines for the RPC protocol compiler 
39  */
40 #include <stdio.h>
41 #include <ctype.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include "rpc_scan.h"
45 #include "rpc_parse.h"
46 #include "rpc_util.h"
47 #include "proto.h"
48
49 #define ARGEXT "argument"
50
51 char curline[MAXLINESIZE];      /* current read line */
52 const char *where = curline;    /* current point in line */
53 int linenum = 0;                /* current line number */
54
55 const char *infilename;         /* input filename */
56
57 #define NFILES 7
58 const char *outfiles[NFILES];   /* output file names */
59 int nfiles;
60
61 FILE *fout;                     /* file pointer of current output */
62 FILE *fin;                      /* file pointer of current input */
63
64 list *defined;                  /* list of defined things */
65
66 static int findit(const definition *def, const char *type);
67 static const char *fixit(const char *type, const char *orig);
68 static int typedefed(const definition *def, const char *type);
69 static const char *toktostr(tok_kind kind);
70 static void printbuf(void);
71 static void printwhere(void);
72
73 /*
74  * Reinitialize the world 
75  */
76 void
77 reinitialize(void)
78 {
79         memset(curline, 0, MAXLINESIZE);
80         where = curline;
81         linenum = 0;
82         defined = NULL;
83 }
84
85 /*
86  * string equality 
87  */
88 int
89 streq(const char *a, const char *b)
90 {
91         return (strcmp(a, b) == 0);
92 }
93
94 /*
95  * find a value in a list 
96  */
97 definition *
98 findval(list *lst, const char *val, 
99         int (*cmp)(const definition *, const char *))
100 {
101          
102         for (; lst != NULL; lst = lst->next) {
103                 if (cmp(lst->val, val)) {
104                         return (lst->val);
105                 }
106         }
107         return NULL;
108 }
109
110 /*
111  * store a value in a list 
112  */
113 void
114 storeval(list **lstp, definition *val)
115 {
116         list **l;
117         list *lst;
118
119         
120         for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
121         lst = ALLOC(list);
122         lst->val = val;
123         lst->next = NULL;
124         *l = lst;
125 }
126
127 static int
128 findit(const definition *def, const char *type)
129 {
130         return (streq(def->def_name, type));
131 }
132
133 static const char *
134 fixit(const char *type, const char *orig)
135 {
136         definition *def;
137
138         def = findval(defined, type, findit);
139         if (def == NULL || def->def_kind != DEF_TYPEDEF) {
140                 return (orig);
141         }
142         switch (def->def.ty.rel) {
143         case REL_VECTOR:
144                 return (def->def.ty.old_type);
145         case REL_ALIAS:
146                 return (fixit(def->def.ty.old_type, orig));
147         default:
148                 return (orig);
149         }
150 }
151
152 const char *
153 fixtype(const char *type)
154 {
155         return (fixit(type, type));
156 }
157
158 const char *
159 stringfix(const char *type)
160 {
161         if (streq(type, "string")) {
162                 return "wrapstring";
163         } 
164         else {
165                 return type;
166         }
167 }
168
169 void
170 ptype(const char *prefix, const char *type, int follow)
171 {
172         if (prefix != NULL) {
173                 if (streq(prefix, "enum")) {
174                         f_print(fout, "enum ");
175                 } else {
176                         f_print(fout, "struct ");
177                 }
178         }
179         if (streq(type, "bool")) {
180                 f_print(fout, "bool_t ");
181         } else if (streq(type, "string")) {
182                 f_print(fout, "char *");
183         } else {
184                 f_print(fout, "%s ", follow ? fixtype(type) : type);
185         }
186 }
187
188 static int
189 typedefed(const definition *def, const char *type)
190 {
191         if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
192                 return (0);
193         } else {
194                 return (streq(def->def_name, type));
195         }
196 }
197
198 int
199 isvectordef(const char *type, relation rel)
200 {
201         definition *def;
202
203         for (;;) {
204                 switch (rel) {
205                 case REL_VECTOR:
206                         return (!streq(type, "string"));
207                 case REL_ARRAY:
208                         return (0);
209                 case REL_POINTER:
210                         return (0);
211                 case REL_ALIAS:
212                         def = findval(defined, type, typedefed);
213                         if (def == NULL) {
214                                 return (0);
215                         }
216                         type = def->def.ty.old_type;
217                         rel = def->def.ty.rel;
218                 }
219         }
220 }
221
222 char *
223 locase(const char *str)
224 {
225         char c;
226         static char buf[100];
227         char *p = buf;
228
229         while ((c = *str++)!=0) {
230                 *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
231         }
232         *p = 0;
233         return (buf);
234 }
235
236 void
237 pvname_svc(const char *pname, const char *vnum)
238 {
239         f_print(fout, "%s_%s_svc", locase(pname), vnum);
240 }
241
242 void
243 pvname(const char *pname, const char *vnum)
244 {
245         f_print(fout, "%s_%s", locase(pname), vnum);
246 }
247
248 /*
249  * print a useful (?) error message, and then die 
250  */
251 void
252 error(const char *msg)
253 {
254         printwhere();
255         f_print(stderr, "%s, line %d: ", infilename, linenum);
256         f_print(stderr, "%s\n", msg);
257         crash();
258 }
259
260 /*
261  * Something went wrong, unlink any files that we may have created and then
262  * die. 
263  */
264 void
265 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 void
276 record_open(const char *file)
277 {
278         if (nfiles < NFILES) {
279                 outfiles[nfiles++] = file;
280         } 
281         else {
282                 f_print(stderr, "too many files!\n");
283                 crash();
284         }
285 }
286
287 static char expectbuf[100];
288
289 /*
290  * error, token encountered was not the expected one 
291  */
292 void
293 expected1(tok_kind exp1)
294 {
295         s_print(expectbuf, "expected '%s'",
296                 toktostr(exp1));
297         error(expectbuf);
298 }
299
300 /*
301  * error, token encountered was not one of two expected ones 
302  */
303 void
304 expected2(tok_kind exp1, tok_kind exp2)
305 {
306         s_print(expectbuf, "expected '%s' or '%s'",
307                 toktostr(exp1),
308                 toktostr(exp2));
309         error(expectbuf);
310 }
311
312 /*
313  * error, token encountered was not one of 3 expected ones 
314  */
315 void
316 expected3(tok_kind exp1, tok_kind exp2, tok_kind exp3)
317 {
318         s_print(expectbuf, "expected '%s', '%s' or '%s'",
319                 toktostr(exp1),
320                 toktostr(exp2),
321                 toktostr(exp3));
322         error(expectbuf);
323 }
324
325 void
326 tabify(FILE *f, int tab)
327 {
328         while (tab--) {
329                 (void) fputc('\t', f);
330         }
331 }
332
333
334 static token tokstrings[] = {
335                              {TOK_IDENT, "identifier"},
336                              {TOK_CONST, "const"},
337                              {TOK_RPAREN, ")"},
338                              {TOK_LPAREN, "("},
339                              {TOK_RBRACE, "}"},
340                              {TOK_LBRACE, "{"},
341                              {TOK_LBRACKET, "["},
342                              {TOK_RBRACKET, "]"},
343                              {TOK_STAR, "*"},
344                              {TOK_COMMA, ","},
345                              {TOK_EQUAL, "="},
346                              {TOK_COLON, ":"},
347                              {TOK_SEMICOLON, ";"},
348                              {TOK_UNION, "union"},
349                              {TOK_STRUCT, "struct"},
350                              {TOK_SWITCH, "switch"},
351                              {TOK_CASE, "case"},
352                              {TOK_DEFAULT, "default"},
353                              {TOK_ENUM, "enum"},
354                              {TOK_TYPEDEF, "typedef"},
355                              {TOK_INT, "int"},
356                              {TOK_SHORT, "short"},
357                              {TOK_LONG, "long"},
358                              {TOK_UNSIGNED, "unsigned"},
359                              {TOK_DOUBLE, "double"},
360                              {TOK_FLOAT, "float"},
361                              {TOK_CHAR, "char"},
362                              {TOK_STRING, "string"},
363                              {TOK_OPAQUE, "opaque"},
364                              {TOK_BOOL, "bool"},
365                              {TOK_VOID, "void"},
366                              {TOK_PROGRAM, "program"},
367                              {TOK_VERSION, "version"},
368                              {TOK_EOF, "??????"}
369 };
370
371 static const char *
372 toktostr(tok_kind kind)
373 {
374         token *sp;
375
376         for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
377         return (sp->str);
378 }
379
380 static void
381 printbuf(void)
382 {
383         char c;
384         int i;
385         int cnt;
386
387 #       define TABSIZE 4
388
389         for (i = 0; (c = curline[i])!=0; i++) {
390                 if (c == '\t') {
391                         cnt = 8 - (i % TABSIZE);
392                         c = ' ';
393                 } else {
394                         cnt = 1;
395                 }
396                 while (cnt--) {
397                         (void) fputc(c, stderr);
398                 }
399         }
400 }
401
402 static void
403 printwhere(void)
404 {
405         int i;
406         char c;
407         int cnt;
408
409         printbuf();
410         for (i = 0; i < where - curline; i++) {
411                 c = curline[i];
412                 if (c == '\t') {
413                         cnt = 8 - (i % TABSIZE);
414                 } else {
415                         cnt = 1;
416                 }
417                 while (cnt--) {
418                         (void) fputc('^', stderr);
419                 }
420         }
421         (void) fputc('\n', stderr);
422 }
423
424 char * 
425 make_argname(const char *pname, const char *vname) 
426 {
427         char *name;
428         
429         name = malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
430         if (!name) {
431                 fprintf(stderr, "failed in malloc");
432                 exit(1);
433         }
434         sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
435         return name;
436 }
437
438 bas_type *typ_list_h;
439 bas_type *typ_list_t;
440
441 void
442 add_type(int len, const char *type)
443 {
444   bas_type *ptr;
445
446
447   if ((ptr = malloc(sizeof(bas_type))) == NULL) {
448       fprintf(stderr, "failed in malloc");
449       exit(1);
450   }
451
452   ptr->name=type;
453   ptr->length=len;
454   ptr->next=NULL;
455   if(typ_list_t == NULL)
456     {
457
458       typ_list_t=ptr;
459       typ_list_h=ptr;
460     }
461   else
462     {
463
464     typ_list_t->next=ptr;
465     typ_list_t=ptr;
466     }
467
468 }
469
470
471 bas_type *find_type(const char *type)
472 {
473   bas_type *ptr;
474
475   ptr=typ_list_h;
476
477
478   while(ptr != NULL)
479     {
480     if(strcmp(ptr->name,type) == 0)
481            return(ptr);
482     else
483       ptr=ptr->next;
484     };
485 return(NULL);
486 }
487