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