Localize rpcgen
[platform/upstream/glibc.git] / sunrpc / rpc_parse.c
1 /*
2  * From: @(#)rpc_parse.c 1.8 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_parse.c, Parser for the RPC protocol compiler
35  * Copyright (C) 1987 Sun Microsystems, Inc.
36  */
37 #include <stdio.h>
38 #include <string.h>
39 #include "rpc/types.h"
40 #include "rpc_scan.h"
41 #include "rpc_parse.h"
42 #include "rpc_util.h"
43 #include "proto.h"
44
45 #define ARGNAME "arg"
46
47 static void isdefined (definition * defp);
48 static void def_struct (definition * defp);
49 static void def_program (definition * defp);
50 static void def_enum (definition * defp);
51 static void def_const (definition * defp);
52 static void def_union (definition * defp);
53 static void check_type_name (const char *name, int new_type);
54 static void def_typedef (definition * defp);
55 static void get_declaration (declaration * dec, defkind dkind);
56 static void get_prog_declaration (declaration * dec, defkind dkind, int num);
57 static void get_type (const char **prefixp, const char **typep, defkind dkind);
58 static void unsigned_dec (const char **typep);
59
60 /*
61  * return the next definition you see
62  */
63 definition *
64 get_definition (void)
65 {
66   definition *defp;
67   token tok;
68
69   defp = ALLOC (definition);
70   get_token (&tok);
71   switch (tok.kind)
72     {
73     case TOK_STRUCT:
74       def_struct (defp);
75       break;
76     case TOK_UNION:
77       def_union (defp);
78       break;
79     case TOK_TYPEDEF:
80       def_typedef (defp);
81       break;
82     case TOK_ENUM:
83       def_enum (defp);
84       break;
85     case TOK_PROGRAM:
86       def_program (defp);
87       break;
88     case TOK_CONST:
89       def_const (defp);
90       break;
91     case TOK_EOF:
92       free (defp);
93       return (NULL);
94     default:
95       error ("definition keyword expected");
96     }
97   scan (TOK_SEMICOLON, &tok);
98   isdefined (defp);
99   return (defp);
100 }
101
102 static void
103 isdefined (definition * defp)
104 {
105   STOREVAL (&defined, defp);
106 }
107
108 static void
109 def_struct (definition * defp)
110 {
111   token tok;
112   declaration dec;
113   decl_list *decls;
114   decl_list **tailp;
115
116   defp->def_kind = DEF_STRUCT;
117
118   scan (TOK_IDENT, &tok);
119   defp->def_name = tok.str;
120   scan (TOK_LBRACE, &tok);
121   tailp = &defp->def.st.decls;
122   do
123     {
124       get_declaration (&dec, DEF_STRUCT);
125       decls = ALLOC (decl_list);
126       decls->decl = dec;
127       *tailp = decls;
128       tailp = &decls->next;
129       scan (TOK_SEMICOLON, &tok);
130       peek (&tok);
131     }
132   while (tok.kind != TOK_RBRACE);
133   get_token (&tok);
134   *tailp = NULL;
135 }
136
137 static void
138 def_program (definition * defp)
139 {
140   token tok;
141   declaration dec;
142   decl_list *decls;
143   decl_list **tailp;
144   version_list *vlist;
145   version_list **vtailp;
146   proc_list *plist;
147   proc_list **ptailp;
148   int num_args;
149   bool_t isvoid = FALSE;        /* whether first argument is void */
150   defp->def_kind = DEF_PROGRAM;
151   scan (TOK_IDENT, &tok);
152   defp->def_name = tok.str;
153   scan (TOK_LBRACE, &tok);
154   vtailp = &defp->def.pr.versions;
155   tailp = &defp->def.st.decls;
156   scan (TOK_VERSION, &tok);
157   do
158     {
159       scan (TOK_IDENT, &tok);
160       vlist = ALLOC (version_list);
161       vlist->vers_name = tok.str;
162       scan (TOK_LBRACE, &tok);
163       ptailp = &vlist->procs;
164       do
165         {
166           /* get result type */
167           plist = ALLOC (proc_list);
168           get_type (&plist->res_prefix, &plist->res_type,
169                     DEF_PROGRAM);
170           if (streq (plist->res_type, "opaque"))
171             {
172               error ("illegal result type");
173             }
174           scan (TOK_IDENT, &tok);
175           plist->proc_name = tok.str;
176           scan (TOK_LPAREN, &tok);
177           /* get args - first one */
178           num_args = 1;
179           isvoid = FALSE;
180           /* type of DEF_PROGRAM in the first
181            * get_prog_declaration and DEF_STURCT in the next
182            * allows void as argument if it is the only argument
183            */
184           get_prog_declaration (&dec, DEF_PROGRAM, num_args);
185           if (streq (dec.type, "void"))
186             isvoid = TRUE;
187           decls = ALLOC (decl_list);
188           plist->args.decls = decls;
189           decls->decl = dec;
190           tailp = &decls->next;
191           /* get args */
192           while (peekscan (TOK_COMMA, &tok))
193             {
194               num_args++;
195               get_prog_declaration (&dec, DEF_STRUCT,
196                                     num_args);
197               decls = ALLOC (decl_list);
198               decls->decl = dec;
199               *tailp = decls;
200               if (streq (dec.type, "void"))
201                 isvoid = TRUE;
202               tailp = &decls->next;
203             }
204           /* multiple arguments are only allowed in newstyle */
205           if (!newstyle && num_args > 1)
206             {
207               error ("only one argument is allowed");
208             }
209           if (isvoid && num_args > 1)
210             {
211               error ("illegal use of void in program definition");
212             }
213           *tailp = NULL;
214           scan (TOK_RPAREN, &tok);
215           scan (TOK_EQUAL, &tok);
216           scan_num (&tok);
217           scan (TOK_SEMICOLON, &tok);
218           plist->proc_num = tok.str;
219           plist->arg_num = num_args;
220           *ptailp = plist;
221           ptailp = &plist->next;
222           peek (&tok);
223         }
224       while (tok.kind != TOK_RBRACE);
225       *ptailp = NULL;
226       *vtailp = vlist;
227       vtailp = &vlist->next;
228       scan (TOK_RBRACE, &tok);
229       scan (TOK_EQUAL, &tok);
230       scan_num (&tok);
231       vlist->vers_num = tok.str;
232       /* make the argument structure name for each arg */
233       for (plist = vlist->procs; plist != NULL;
234            plist = plist->next)
235         {
236           plist->args.argname = make_argname (plist->proc_name,
237                                               vlist->vers_num);
238           /* free the memory ?? */
239         }
240       scan (TOK_SEMICOLON, &tok);
241       scan2 (TOK_VERSION, TOK_RBRACE, &tok);
242     }
243   while (tok.kind == TOK_VERSION);
244   scan (TOK_EQUAL, &tok);
245   scan_num (&tok);
246   defp->def.pr.prog_num = tok.str;
247   *vtailp = NULL;
248 }
249
250
251 static void
252 def_enum (definition * defp)
253 {
254   token tok;
255   enumval_list *elist;
256   enumval_list **tailp;
257
258   defp->def_kind = DEF_ENUM;
259   scan (TOK_IDENT, &tok);
260   defp->def_name = tok.str;
261   scan (TOK_LBRACE, &tok);
262   tailp = &defp->def.en.vals;
263   do
264     {
265       scan (TOK_IDENT, &tok);
266       elist = ALLOC (enumval_list);
267       elist->name = tok.str;
268       elist->assignment = NULL;
269       scan3 (TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
270       if (tok.kind == TOK_EQUAL)
271         {
272           scan_num (&tok);
273           elist->assignment = tok.str;
274           scan2 (TOK_COMMA, TOK_RBRACE, &tok);
275         }
276       *tailp = elist;
277       tailp = &elist->next;
278     }
279   while (tok.kind != TOK_RBRACE);
280   *tailp = NULL;
281 }
282
283 static void
284 def_const (definition * defp)
285 {
286   token tok;
287
288   defp->def_kind = DEF_CONST;
289   scan (TOK_IDENT, &tok);
290   defp->def_name = tok.str;
291   scan (TOK_EQUAL, &tok);
292   scan2 (TOK_IDENT, TOK_STRCONST, &tok);
293   defp->def.co = tok.str;
294 }
295
296 static void
297 def_union (definition *defp)
298 {
299   token tok;
300   declaration dec;
301   case_list *cases;
302 /*  case_list *tcase; */
303   case_list **tailp;
304 #if 0
305   int flag;
306 #endif
307
308   defp->def_kind = DEF_UNION;
309   scan (TOK_IDENT, &tok);
310   defp->def_name = tok.str;
311   scan (TOK_SWITCH, &tok);
312   scan (TOK_LPAREN, &tok);
313   get_declaration (&dec, DEF_UNION);
314   defp->def.un.enum_decl = dec;
315   tailp = &defp->def.un.cases;
316   scan (TOK_RPAREN, &tok);
317   scan (TOK_LBRACE, &tok);
318   scan (TOK_CASE, &tok);
319   while (tok.kind == TOK_CASE)
320     {
321       scan2 (TOK_IDENT, TOK_CHARCONST, &tok);
322       cases = ALLOC (case_list);
323       cases->case_name = tok.str;
324       scan (TOK_COLON, &tok);
325       /* now peek at next token */
326 #if 0
327       flag = 0;
328 #endif
329       if (peekscan (TOK_CASE, &tok))
330         {
331
332           do
333             {
334               scan2 (TOK_IDENT, TOK_CHARCONST, &tok);
335               cases->contflag = 1;      /* continued case statement */
336               *tailp = cases;
337               tailp = &cases->next;
338               cases = ALLOC (case_list);
339               cases->case_name = tok.str;
340               scan (TOK_COLON, &tok);
341
342             }
343           while (peekscan (TOK_CASE, &tok));
344         }
345 #if 0
346       else if (flag)
347         {
348
349           *tailp = cases;
350           tailp = &cases->next;
351           cases = ALLOC (case_list);
352         };
353 #endif
354
355       get_declaration (&dec, DEF_UNION);
356       cases->case_decl = dec;
357       cases->contflag = 0;      /* no continued case statement */
358       *tailp = cases;
359       tailp = &cases->next;
360       scan (TOK_SEMICOLON, &tok);
361
362       scan3 (TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
363     }
364   *tailp = NULL;
365   if (tok.kind == TOK_DEFAULT)
366     {
367       scan (TOK_COLON, &tok);
368       get_declaration (&dec, DEF_UNION);
369       defp->def.un.default_decl = ALLOC (declaration);
370       *defp->def.un.default_decl = dec;
371       scan (TOK_SEMICOLON, &tok);
372       scan (TOK_RBRACE, &tok);
373     }
374   else
375     {
376       defp->def.un.default_decl = NULL;
377     }
378 }
379
380 static const char *reserved_words[] =
381 {
382   "array",
383   "bytes",
384   "destroy",
385   "free",
386   "getpos",
387   "inline",
388   "pointer",
389   "reference",
390   "setpos",
391   "sizeof",
392   "union",
393   "vector",
394   NULL
395 };
396
397 static const char *reserved_types[] =
398 {
399   "opaque",
400   "string",
401   NULL
402 };
403
404 /*
405  * check that the given name is not one that would eventually result in
406  * xdr routines that would conflict with internal XDR routines.
407  */
408 static void
409 check_type_name (const char *name, int new_type)
410 {
411   int i;
412   char tmp[100];
413
414   for (i = 0; reserved_words[i] != NULL; i++)
415     {
416       if (strcmp (name, reserved_words[i]) == 0)
417         {
418           sprintf (tmp,
419                 "illegal (reserved) name :\'%s\' in type definition", name);
420           error (tmp);
421         }
422     }
423   if (new_type)
424     {
425       for (i = 0; reserved_types[i] != NULL; i++)
426         {
427           if (strcmp (name, reserved_types[i]) == 0)
428             {
429               sprintf (tmp,
430                 "illegal (reserved) name :\'%s\' in type definition", name);
431               error (tmp);
432             }
433         }
434     }
435 }
436
437
438
439 static void
440 def_typedef (definition * defp)
441 {
442   declaration dec;
443
444   defp->def_kind = DEF_TYPEDEF;
445   get_declaration (&dec, DEF_TYPEDEF);
446   defp->def_name = dec.name;
447   check_type_name (dec.name, 1);
448   defp->def.ty.old_prefix = dec.prefix;
449   defp->def.ty.old_type = dec.type;
450   defp->def.ty.rel = dec.rel;
451   defp->def.ty.array_max = dec.array_max;
452 }
453
454 static void
455 get_declaration (declaration * dec, defkind dkind)
456 {
457   token tok;
458
459   get_type (&dec->prefix, &dec->type, dkind);
460   dec->rel = REL_ALIAS;
461   if (streq (dec->type, "void"))
462     {
463       return;
464     }
465
466   check_type_name (dec->type, 0);
467
468   scan2 (TOK_STAR, TOK_IDENT, &tok);
469   if (tok.kind == TOK_STAR)
470     {
471       dec->rel = REL_POINTER;
472       scan (TOK_IDENT, &tok);
473     }
474   dec->name = tok.str;
475   if (peekscan (TOK_LBRACKET, &tok))
476     {
477       if (dec->rel == REL_POINTER)
478         {
479           error ("no array-of-pointer declarations -- use typedef");
480         }
481       dec->rel = REL_VECTOR;
482       scan_num (&tok);
483       dec->array_max = tok.str;
484       scan (TOK_RBRACKET, &tok);
485     }
486   else if (peekscan (TOK_LANGLE, &tok))
487     {
488       if (dec->rel == REL_POINTER)
489         {
490           error ("no array-of-pointer declarations -- use typedef");
491         }
492       dec->rel = REL_ARRAY;
493       if (peekscan (TOK_RANGLE, &tok))
494         {
495           dec->array_max = "~0";        /* unspecified size, use max */
496         }
497       else
498         {
499           scan_num (&tok);
500           dec->array_max = tok.str;
501           scan (TOK_RANGLE, &tok);
502         }
503     }
504   if (streq (dec->type, "opaque"))
505     {
506       if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR)
507         {
508           error ("array declaration expected");
509         }
510     }
511   else if (streq (dec->type, "string"))
512     {
513       if (dec->rel != REL_ARRAY)
514         {
515           error ("variable-length array declaration expected");
516         }
517     }
518 }
519
520 static void
521 get_prog_declaration (declaration * dec, defkind dkind, int num /* arg number */ )
522 {
523   token tok;
524   char name[10];                /* argument name */
525
526   if (dkind == DEF_PROGRAM)
527     {
528       peek (&tok);
529       if (tok.kind == TOK_RPAREN)
530         {                       /* no arguments */
531           dec->rel = REL_ALIAS;
532           dec->type = "void";
533           dec->prefix = NULL;
534           dec->name = NULL;
535           return;
536         }
537     }
538   get_type (&dec->prefix, &dec->type, dkind);
539   dec->rel = REL_ALIAS;
540   if (peekscan (TOK_IDENT, &tok))       /* optional name of argument */
541     strcpy (name, tok.str);
542   else
543     sprintf (name, "%s%d", ARGNAME, num);       /* default name of argument */
544
545   dec->name = (char *) strdup (name);
546
547   if (streq (dec->type, "void"))
548     {
549       return;
550     }
551
552   if (streq (dec->type, "opaque"))
553     {
554       error ("opaque -- illegal argument type");
555     }
556   if (peekscan (TOK_STAR, &tok))
557     {
558       if (streq (dec->type, "string"))
559         {
560           error ("pointer to string not allowed in program arguments\n");
561         }
562       dec->rel = REL_POINTER;
563       if (peekscan (TOK_IDENT, &tok))   /* optional name of argument */
564         dec->name = strdup (tok.str);
565     }
566   if (peekscan (TOK_LANGLE, &tok))
567     {
568       if (!streq (dec->type, "string"))
569         {
570           error ("arrays cannot be declared as arguments to procedures -- use typedef");
571         }
572       dec->rel = REL_ARRAY;
573       if (peekscan (TOK_RANGLE, &tok))
574         {
575           dec->array_max = "~0";        /* unspecified size, use max */
576         }
577       else
578         {
579           scan_num (&tok);
580           dec->array_max = tok.str;
581           scan (TOK_RANGLE, &tok);
582         }
583     }
584   if (streq (dec->type, "string"))
585     {
586       if (dec->rel != REL_ARRAY)
587         {                       /* .x specifies just string as
588                                  * type of argument
589                                  * - make it string<>
590                                  */
591           dec->rel = REL_ARRAY;
592           dec->array_max = "~0";        /* unspecified size, use max */
593         }
594     }
595 }
596
597 static void
598 get_type (const char **prefixp, const char **typep, defkind dkind)
599 {
600   token tok;
601
602   *prefixp = NULL;
603   get_token (&tok);
604   switch (tok.kind)
605     {
606     case TOK_IDENT:
607       *typep = tok.str;
608       break;
609     case TOK_STRUCT:
610     case TOK_ENUM:
611     case TOK_UNION:
612       *prefixp = tok.str;
613       scan (TOK_IDENT, &tok);
614       *typep = tok.str;
615       break;
616     case TOK_UNSIGNED:
617       unsigned_dec (typep);
618       break;
619     case TOK_SHORT:
620       *typep = "short";
621       (void) peekscan (TOK_INT, &tok);
622       break;
623     case TOK_LONG:
624       *typep = "long";
625       (void) peekscan (TOK_INT, &tok);
626       break;
627     case TOK_HYPER:
628       *typep = "quad_t";
629       (void) peekscan(TOK_INT, &tok);
630       break;
631     case TOK_VOID:
632       if (dkind != DEF_UNION && dkind != DEF_PROGRAM)
633         {
634           error ("voids allowed only inside union and program definitions with one argument");
635         }
636       *typep = tok.str;
637       break;
638     case TOK_STRING:
639     case TOK_OPAQUE:
640     case TOK_CHAR:
641     case TOK_INT:
642     case TOK_FLOAT:
643     case TOK_DOUBLE:
644     case TOK_BOOL:
645       *typep = tok.str;
646       break;
647     default:
648       error ("expected type specifier");
649     }
650 }
651
652 static void
653 unsigned_dec (const char **typep)
654 {
655   token tok;
656
657   peek (&tok);
658   switch (tok.kind)
659     {
660     case TOK_CHAR:
661       get_token (&tok);
662       *typep = "u_char";
663       break;
664     case TOK_SHORT:
665       get_token (&tok);
666       *typep = "u_short";
667       (void) peekscan (TOK_INT, &tok);
668       break;
669     case TOK_LONG:
670       get_token (&tok);
671       *typep = "u_long";
672       (void) peekscan (TOK_INT, &tok);
673       break;
674     case TOK_HYPER:
675       get_token (&tok);
676       *typep = "u_quad_t";
677       (void) peekscan(TOK_INT, &tok);
678       break;
679     case TOK_INT:
680       get_token (&tok);
681       *typep = "u_int";
682       break;
683     default:
684       *typep = "u_int";
685       break;
686     }
687 }