* sunrpc/etc.rpc (fedfs_admin): Add entry.
[platform/upstream/glibc.git] / sunrpc / rpc_util.c
1 /*
2  * From: @(#)rpc_util.c 1.11 89/02/22
3  *
4  * Copyright (c) 2010, Oracle America, Inc.
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials
14  *       provided with the distribution.
15  *     * Neither the name of the "Oracle America, Inc." nor the names of its
16  *       contributors may be used to endorse or promote products derived
17  *       from this software without specific prior written permission.
18  *
19  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
26  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /*
34  * rpc_util.c, Utility routines for the RPC protocol compiler
35  */
36 #include <stdio.h>
37 #include <ctype.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include "rpc_scan.h"
41 #include "rpc_parse.h"
42 #include "rpc_util.h"
43 #include "proto.h"
44
45 #define ARGEXT "argument"
46
47 char curline[MAXLINESIZE];      /* current read line */
48 const char *where = curline;    /* current point in line */
49 int linenum = 0;                /* current line number */
50
51 const char *infilename;         /* input filename */
52
53 #define NFILES 7
54 const char *outfiles[NFILES];   /* output file names */
55 int nfiles;
56
57 FILE *fout;                     /* file pointer of current output */
58 FILE *fin;                      /* file pointer of current input */
59
60 list *defined;                  /* list of defined things */
61
62 static int findit (const definition * def, const char *type);
63 static const char *fixit (const char *type, const char *orig);
64 static int typedefed (const definition * def, const char *type);
65 static const char *toktostr (tok_kind kind);
66 static void printbuf (void);
67 static void printwhere (void);
68
69 /*
70  * Reinitialize the world
71  */
72 void
73 reinitialize (void)
74 {
75   memset (curline, 0, MAXLINESIZE);
76   where = curline;
77   linenum = 0;
78   defined = NULL;
79 }
80
81 /*
82  * string equality
83  */
84 int
85 streq (const char *a, const char *b)
86 {
87   return strcmp (a, b) == 0;
88 }
89
90 /*
91  * find a value in a list
92  */
93 definition *
94 findval (list *lst, const char *val,
95          int (*cmp) (const definition *, const char *))
96 {
97
98   for (; lst != NULL; lst = lst->next)
99     {
100       if (cmp (lst->val, val))
101         {
102           return lst->val;
103         }
104     }
105   return NULL;
106 }
107
108 /*
109  * store a value in a list
110  */
111 void
112 storeval (list **lstp, definition *val)
113 {
114   list **l;
115   list *lst;
116
117
118   for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
119   lst = ALLOC (list);
120   lst->val = val;
121   lst->next = NULL;
122   *l = lst;
123 }
124
125 static int
126 findit (const definition * def, const char *type)
127 {
128   return streq (def->def_name, type);
129 }
130
131 static const char *
132 fixit (const char *type, const char *orig)
133 {
134   definition *def;
135
136   def = findval (defined, type, findit);
137   if (def == NULL || def->def_kind != DEF_TYPEDEF)
138     {
139       return orig;
140     }
141   switch (def->def.ty.rel)
142     {
143     case REL_VECTOR:
144       if (streq (def->def.ty.old_type, "opaque"))
145         return ("char");
146       else
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 const char *
156 fixtype (const char *type)
157 {
158   return fixit (type, type);
159 }
160
161 const char *
162 stringfix (const char *type)
163 {
164   if (streq (type, "string"))
165     {
166       return "wrapstring";
167     }
168   else
169     {
170       return type;
171     }
172 }
173
174 void
175 ptype (const char *prefix, const char *type, int follow)
176 {
177   if (prefix != NULL)
178     {
179       if (streq (prefix, "enum"))
180         {
181           f_print (fout, "enum ");
182         }
183       else
184         {
185           f_print (fout, "struct ");
186         }
187     }
188   if (streq (type, "bool"))
189     {
190       f_print (fout, "bool_t ");
191     }
192   else if (streq (type, "string"))
193     {
194       f_print (fout, "char *");
195     }
196   else
197     {
198       f_print (fout, "%s ", follow ? fixtype (type) : type);
199     }
200 }
201
202 static int
203 typedefed (const definition * def, const char *type)
204 {
205   if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL)
206     {
207       return 0;
208     }
209   else
210     {
211       return streq (def->def_name, type);
212     }
213 }
214
215 int
216 isvectordef (const char *type, relation rel)
217 {
218   definition *def;
219
220   for (;;)
221     {
222       switch (rel)
223         {
224         case REL_VECTOR:
225           return !streq (type, "string");
226         case REL_ARRAY:
227           return 0;
228         case REL_POINTER:
229           return 0;
230         case REL_ALIAS:
231           def = findval (defined, type, typedefed);
232           if (def == NULL)
233             {
234               return 0;
235             }
236           type = def->def.ty.old_type;
237           rel = def->def.ty.rel;
238         }
239     }
240 }
241
242 char *
243 locase (const char *str)
244 {
245   char c;
246   static char buf[100];
247   char *p = buf;
248
249   while ((c = *str++) != 0)
250     {
251       *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
252     }
253   *p = 0;
254   return buf;
255 }
256
257 void
258 pvname_svc (const char *pname, const char *vnum)
259 {
260   f_print (fout, "%s_%s_svc", locase (pname), vnum);
261 }
262
263 void
264 pvname (const char *pname, const char *vnum)
265 {
266   f_print (fout, "%s_%s", locase (pname), vnum);
267 }
268
269 /*
270  * print a useful (?) error message, and then die
271  */
272 void
273 error (const 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 void
286 crash (void)
287 {
288   int i;
289
290   for (i = 0; i < nfiles; i++)
291     {
292       unlink (outfiles[i]);
293     }
294   exit (1);
295 }
296
297 void
298 record_open (const char *file)
299 {
300   if (nfiles < NFILES)
301     {
302       outfiles[nfiles++] = file;
303     }
304   else
305     {
306       f_print (stderr, "too many files!\n");
307       crash ();
308     }
309 }
310
311 static char expectbuf[100];
312
313 /*
314  * error, token encountered was not the expected one
315  */
316 void
317 expected1 (tok_kind exp1)
318 {
319   s_print (expectbuf, "expected '%s'",
320            toktostr (exp1));
321   error (expectbuf);
322 }
323
324 /*
325  * error, token encountered was not one of two expected ones
326  */
327 void
328 expected2 (tok_kind exp1, tok_kind 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 (tok_kind exp1, tok_kind exp2, tok_kind exp3)
341 {
342   s_print (expectbuf, "expected '%s', '%s' or '%s'",
343            toktostr (exp1),
344            toktostr (exp2),
345            toktostr (exp3));
346   error (expectbuf);
347 }
348
349 void
350 tabify (FILE * f, int tab)
351 {
352   while (tab--)
353     {
354       (void) fputc ('\t', f);
355     }
356 }
357
358
359 static const token tokstrings[] =
360 {
361   {TOK_IDENT, "identifier"},
362   {TOK_CONST, "const"},
363   {TOK_RPAREN, ")"},
364   {TOK_LPAREN, "("},
365   {TOK_RBRACE, "}"},
366   {TOK_LBRACE, "{"},
367   {TOK_LBRACKET, "["},
368   {TOK_RBRACKET, "]"},
369   {TOK_STAR, "*"},
370   {TOK_COMMA, ","},
371   {TOK_EQUAL, "="},
372   {TOK_COLON, ":"},
373   {TOK_SEMICOLON, ";"},
374   {TOK_UNION, "union"},
375   {TOK_STRUCT, "struct"},
376   {TOK_SWITCH, "switch"},
377   {TOK_CASE, "case"},
378   {TOK_DEFAULT, "default"},
379   {TOK_ENUM, "enum"},
380   {TOK_TYPEDEF, "typedef"},
381   {TOK_INT, "int"},
382   {TOK_SHORT, "short"},
383   {TOK_LONG, "long"},
384   {TOK_UNSIGNED, "unsigned"},
385   {TOK_DOUBLE, "double"},
386   {TOK_FLOAT, "float"},
387   {TOK_CHAR, "char"},
388   {TOK_STRING, "string"},
389   {TOK_OPAQUE, "opaque"},
390   {TOK_BOOL, "bool"},
391   {TOK_VOID, "void"},
392   {TOK_PROGRAM, "program"},
393   {TOK_VERSION, "version"},
394   {TOK_EOF, "??????"}
395 };
396
397 static const char *
398 toktostr (tok_kind kind)
399 {
400   const token *sp;
401
402   for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
403   return sp->str;
404 }
405
406 static void
407 printbuf (void)
408 {
409   char c;
410   int i;
411   int cnt;
412
413 #define TABSIZE 4
414
415   for (i = 0; (c = curline[i]) != 0; i++)
416     {
417       if (c == '\t')
418         {
419           cnt = 8 - (i % TABSIZE);
420           c = ' ';
421         }
422       else
423         {
424           cnt = 1;
425         }
426       while (cnt--)
427         {
428           (void) fputc (c, stderr);
429         }
430     }
431 }
432
433 static void
434 printwhere (void)
435 {
436   int i;
437   char c;
438   int cnt;
439
440   printbuf ();
441   for (i = 0; i < where - curline; i++)
442     {
443       c = curline[i];
444       if (c == '\t')
445         {
446           cnt = 8 - (i % TABSIZE);
447         }
448       else
449         {
450           cnt = 1;
451         }
452       while (cnt--)
453         {
454           (void) fputc ('^', stderr);
455         }
456     }
457   (void) fputc ('\n', stderr);
458 }
459
460 char *
461 make_argname (const char *pname, const char *vname)
462 {
463   char *name;
464
465   name = malloc (strlen (pname) + strlen (vname) + strlen (ARGEXT) + 3);
466   if (!name)
467     {
468       fprintf (stderr, "failed in malloc");
469       exit (1);
470     }
471   sprintf (name, "%s_%s_%s", locase (pname), vname, ARGEXT);
472   return name;
473 }
474
475 bas_type *typ_list_h;
476 bas_type *typ_list_t;
477
478 void
479 add_type (int len, const char *type)
480 {
481   bas_type *ptr;
482
483
484   if ((ptr = malloc (sizeof (bas_type))) == NULL)
485     {
486       fprintf (stderr, "failed in malloc");
487       exit (1);
488     }
489
490   ptr->name = type;
491   ptr->length = len;
492   ptr->next = NULL;
493   if (typ_list_t == NULL)
494     {
495
496       typ_list_t = ptr;
497       typ_list_h = ptr;
498     }
499   else
500     {
501
502       typ_list_t->next = ptr;
503       typ_list_t = ptr;
504     }
505
506 }
507
508
509 bas_type *
510 find_type (const char *type)
511 {
512   bas_type *ptr;
513
514   ptr = typ_list_h;
515
516
517   while (ptr != NULL)
518     {
519       if (strcmp (ptr->name, type) == 0)
520         return ptr;
521       else
522         ptr = ptr->next;
523     };
524   return NULL;
525 }