Add more changes from TI-RPC 2.3 for rpcgen to fix include/C++ bug and
[kopensolaris-gnu/glibc.git] / sunrpc / rpc_hout.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_hout.c 1.12 89/02/22 (C) 1987 SMI
33  */
34 char hout_rcsid[] =
35   "$Id$";
36
37 /*
38  * rpc_hout.c, Header file outputter for the RPC protocol compiler
39  */
40 #include <stdio.h>
41 #include <ctype.h>
42 #include "rpc_parse.h"
43 #include "rpc_util.h"
44 #include "proto.h"
45
46 static void pconstdef (definition * def);
47 static void pargdef (definition * def);
48 static void pstructdef (definition * def);
49 static void puniondef (definition * def);
50 static void pdefine (const char *name, const char *num);
51 static void puldefine (const char *name, const char *num);
52 static int define_printed (proc_list * stop, version_list * start);
53 static void pprogramdef (definition * def);
54 static void parglist (proc_list * proc, const char *addargtype);
55 static void penumdef (definition * def);
56 static void ptypedef (definition * def);
57 static int undefined2 (const char *type, const char *stop);
58
59 /* store away enough information to allow the XDR functions to be spat
60     out at the end of the file */
61
62 void
63 storexdrfuncdecl (const char *name, int pointerp)
64 {
65   xdrfunc * xdrptr;
66
67   xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc));
68
69   xdrptr->name = (char *)name;
70   xdrptr->pointerp = pointerp;
71   xdrptr->next = NULL;
72
73   if (xdrfunc_tail == NULL)
74     {
75       xdrfunc_head = xdrptr;
76       xdrfunc_tail = xdrptr;
77     }
78   else
79     {
80       xdrfunc_tail->next = xdrptr;
81       xdrfunc_tail = xdrptr;
82     }
83 }
84
85 /*
86  * Print the C-version of an xdr definition
87  */
88 void
89 print_datadef (definition *def)
90 {
91
92   if (def->def_kind == DEF_PROGRAM)     /* handle data only */
93     return;
94
95   if (def->def_kind != DEF_CONST)
96     {
97       f_print (fout, "\n");
98     }
99   switch (def->def_kind)
100     {
101     case DEF_STRUCT:
102       pstructdef (def);
103       break;
104     case DEF_UNION:
105       puniondef (def);
106       break;
107     case DEF_ENUM:
108       penumdef (def);
109       break;
110     case DEF_TYPEDEF:
111       ptypedef (def);
112       break;
113     case DEF_PROGRAM:
114       pprogramdef (def);
115       break;
116     case DEF_CONST:
117       pconstdef (def);
118       break;
119     }
120   if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST)
121     {
122       storexdrfuncdecl(def->def_name,
123                        def->def_kind != DEF_TYPEDEF ||
124                        !isvectordef(def->def.ty.old_type,
125                                     def->def.ty.rel));
126     }
127 }
128
129
130 void
131 print_funcdef (definition *def)
132 {
133   switch (def->def_kind)
134     {
135     case DEF_PROGRAM:
136       f_print (fout, "\n");
137       pprogramdef (def);
138       break;
139     default:
140       /* ?... shouldn't happen I guess */
141     }
142 }
143
144 void
145 print_xdr_func_def (char *name, int pointerp, int i)
146 {
147   if (i == 2)
148     {
149       f_print (fout, "extern bool_t xdr_%s ();\n", name);
150       return;
151     }
152   else
153     f_print(fout, "extern  bool_t xdr_%s (XDR *, %s%s);\n", name,
154             name, pointerp ? "*" : "");
155 }
156
157 static void
158 pconstdef (definition *def)
159 {
160   pdefine (def->def_name, def->def.co);
161 }
162
163 /* print out the definitions for the arguments of functions in the
164    header file
165  */
166 static void
167 pargdef (definition * def)
168 {
169   decl_list *l;
170   version_list *vers;
171   const char *name;
172   proc_list *plist;
173
174   for (vers = def->def.pr.versions; vers != NULL; vers = vers->next)
175     {
176       for (plist = vers->procs; plist != NULL;
177            plist = plist->next)
178         {
179
180           if (!newstyle || plist->arg_num < 2)
181             {
182               continue;         /* old style or single args */
183             }
184           name = plist->args.argname;
185           f_print (fout, "struct %s {\n", name);
186           for (l = plist->args.decls;
187                l != NULL; l = l->next)
188             {
189               pdeclaration (name, &l->decl, 1, ";\n");
190             }
191           f_print (fout, "};\n");
192           f_print (fout, "typedef struct %s %s;\n", name, name);
193           storexdrfuncdecl (name, 0);
194           f_print (fout, "\n");
195         }
196     }
197
198 }
199
200 static void
201 pstructdef (definition *def)
202 {
203   decl_list *l;
204   const char *name = def->def_name;
205
206   f_print (fout, "struct %s {\n", name);
207   for (l = def->def.st.decls; l != NULL; l = l->next)
208     {
209       pdeclaration (name, &l->decl, 1, ";\n");
210     }
211   f_print (fout, "};\n");
212   f_print (fout, "typedef struct %s %s;\n", name, name);
213 }
214
215 static void
216 puniondef (definition *def)
217 {
218   case_list *l;
219   const char *name = def->def_name;
220   declaration *decl;
221
222   f_print (fout, "struct %s {\n", name);
223   decl = &def->def.un.enum_decl;
224   if (streq (decl->type, "bool"))
225     {
226       f_print (fout, "\tbool_t %s;\n", decl->name);
227     }
228   else
229     {
230       f_print (fout, "\t%s %s;\n", decl->type, decl->name);
231     }
232   f_print (fout, "\tunion {\n");
233   for (l = def->def.un.cases; l != NULL; l = l->next)
234     {
235       if (l->contflag == 0)
236         pdeclaration (name, &l->case_decl, 2, ";\n");
237     }
238   decl = def->def.un.default_decl;
239   if (decl && !streq (decl->type, "void"))
240     {
241       pdeclaration (name, decl, 2, ";\n");
242     }
243   f_print (fout, "\t} %s_u;\n", name);
244   f_print (fout, "};\n");
245   f_print (fout, "typedef struct %s %s;\n", name, name);
246 }
247
248 static void
249 pdefine (const char *name, const char *num)
250 {
251   f_print (fout, "#define %s %s\n", name, num);
252 }
253
254 static void
255 puldefine (const char *name, const char *num)
256 {
257   f_print (fout, "#define %s ((u_long)%s)\n", name, num);
258 }
259
260 static int
261 define_printed (proc_list *stop, version_list *start)
262 {
263   version_list *vers;
264   proc_list *proc;
265
266   for (vers = start; vers != NULL; vers = vers->next)
267     {
268       for (proc = vers->procs; proc != NULL; proc = proc->next)
269         {
270           if (proc == stop)
271             {
272               return 0;
273             }
274           else if (streq (proc->proc_name, stop->proc_name))
275             {
276               return 1;
277             }
278         }
279     }
280   abort ();
281   /* NOTREACHED */
282 }
283
284 static void
285 pfreeprocdef (const char *name, const char *vers, int mode)
286 {
287   f_print (fout, "extern int ");
288   pvname (name, vers);
289   if (mode == 1)
290     f_print (fout,"_freeresult (SVCXPRT *, xdrproc_t, caddr_t);\n");
291   else
292     f_print (fout,"_freeresult ();\n");
293 }
294
295 static void
296 pprogramdef (definition *def)
297 {
298   version_list *vers;
299   proc_list *proc;
300   int i;
301   const char *ext;
302
303   pargdef (def);
304
305   puldefine (def->def_name, def->def.pr.prog_num);
306   for (vers = def->def.pr.versions; vers != NULL; vers = vers->next)
307     {
308       if (tblflag)
309         {
310           f_print (fout, "extern struct rpcgen_table %s_%s_table[];\n",
311                    locase (def->def_name), vers->vers_num);
312           f_print (fout, "extern %s_%s_nproc;\n",
313                    locase (def->def_name), vers->vers_num);
314         }
315       puldefine (vers->vers_name, vers->vers_num);
316
317       /*
318        * Print out 2 definitions, one for ANSI-C, another for
319        * old K & R C
320        */
321
322       if(!Cflag)
323         {
324           ext = "extern  ";
325           for (proc = vers->procs; proc != NULL;
326                proc = proc->next)
327             {
328               if (!define_printed(proc, def->def.pr.versions))
329                 {
330                   puldefine (proc->proc_name, proc->proc_num);
331                 }
332               f_print (fout, "%s", ext);
333               pprocdef (proc, vers, NULL, 0, 2);
334
335               if (mtflag)
336                 {
337                   f_print(fout, "%s", ext);
338                   pprocdef (proc, vers, NULL, 1, 2);
339                 }
340             }
341           pfreeprocdef (def->def_name, vers->vers_num, 2);
342         }
343       else
344         {
345           for (i = 1; i < 3; i++)
346             {
347               if (i == 1)
348                 {
349                   f_print (fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
350                   ext = "extern  ";
351                 }
352               else
353                 {
354                   f_print (fout, "\n#else /* K&R C */\n");
355                   ext = "extern  ";
356                 }
357
358               for (proc = vers->procs; proc != NULL; proc = proc->next)
359                 {
360                   if (!define_printed(proc, def->def.pr.versions))
361                     {
362                       puldefine(proc->proc_name, proc->proc_num);
363                     }
364                   f_print (fout, "%s", ext);
365                   pprocdef (proc, vers, "CLIENT *", 0, i);
366                   f_print (fout, "%s", ext);
367                   pprocdef (proc, vers, "struct svc_req *", 1, i);
368                 }
369               pfreeprocdef (def->def_name, vers->vers_num, i);
370             }
371           f_print (fout, "#endif /* K&R C */\n");
372         }
373     }
374 }
375
376 void
377 pprocdef (proc_list * proc, version_list * vp,
378           const char *addargtype, int server_p, int mode)
379 {
380   if (mtflag)
381     {/* Print MT style stubs */
382       if (server_p)
383         f_print (fout, "bool_t ");
384       else
385         f_print (fout, "enum clnt_stat ");
386     }
387   else
388     {
389       ptype (proc->res_prefix, proc->res_type, 1);
390       f_print (fout, "* ");
391     }
392   if (server_p)
393     pvname_svc (proc->proc_name, vp->vers_num);
394   else
395     pvname (proc->proc_name, vp->vers_num);
396
397   /*
398    * mode  1 = ANSI-C, mode 2 = K&R C
399    */
400   if (mode == 1)
401     parglist (proc, addargtype);
402   else
403     f_print (fout, "();\n");
404 }
405
406 /* print out argument list of procedure */
407 static void
408 parglist (proc_list *proc, const char *addargtype)
409 {
410   decl_list *dl;
411
412   f_print(fout,"(");
413   if (proc->arg_num < 2 && newstyle &&
414       streq (proc->args.decls->decl.type, "void"))
415     {
416       /* 0 argument in new style:  do nothing */
417     }
418   else
419     {
420       for (dl = proc->args.decls; dl != NULL; dl = dl->next)
421         {
422           ptype (dl->decl.prefix, dl->decl.type, 1);
423           if (!newstyle)
424             f_print (fout, "*");        /* old style passes by reference */
425
426           f_print (fout, ", ");
427         }
428     }
429   if (mtflag)
430     {
431       ptype(proc->res_prefix, proc->res_type, 1);
432       f_print(fout, "*, ");
433     }
434
435   f_print (fout, "%s);\n", addargtype);
436 }
437
438 static void
439 penumdef (definition *def)
440 {
441   const char *name = def->def_name;
442   enumval_list *l;
443   const char *last = NULL;
444   int count = 0;
445
446   f_print (fout, "enum %s {\n", name);
447   for (l = def->def.en.vals; l != NULL; l = l->next)
448     {
449       f_print (fout, "\t%s", l->name);
450       if (l->assignment)
451         {
452           f_print (fout, " = %s", l->assignment);
453           last = l->assignment;
454           count = 1;
455         }
456       else
457         {
458           if (last == NULL)
459             {
460               f_print (fout, " = %d", count++);
461             }
462           else
463             {
464               f_print (fout, " = %s + %d", last, count++);
465             }
466         }
467       f_print (fout, ",\n");
468     }
469   f_print (fout, "};\n");
470   f_print (fout, "typedef enum %s %s;\n", name, name);
471 }
472
473 static void
474 ptypedef (definition *def)
475 {
476   const char *name = def->def_name;
477   const char *old = def->def.ty.old_type;
478   char prefix[8];         /* enough to contain "struct ", including NUL */
479   relation rel = def->def.ty.rel;
480
481   if (!streq (name, old))
482     {
483       if (streq (old, "string"))
484         {
485           old = "char";
486           rel = REL_POINTER;
487         }
488       else if (streq (old, "opaque"))
489         {
490           old = "char";
491         }
492       else if (streq (old, "bool"))
493         {
494           old = "bool_t";
495         }
496       if (undefined2 (old, name) && def->def.ty.old_prefix)
497         {
498           s_print (prefix, "%s ", def->def.ty.old_prefix);
499         }
500       else
501         {
502           prefix[0] = 0;
503         }
504       f_print (fout, "typedef ");
505       switch (rel)
506         {
507         case REL_ARRAY:
508           f_print (fout, "struct {\n");
509           f_print (fout, "\tu_int %s_len;\n", name);
510           f_print (fout, "\t%s%s *%s_val;\n", prefix, old, name);
511           f_print (fout, "} %s", name);
512           break;
513         case REL_POINTER:
514           f_print (fout, "%s%s *%s", prefix, old, name);
515           break;
516         case REL_VECTOR:
517           f_print (fout, "%s%s %s[%s]", prefix, old, name,
518                    def->def.ty.array_max);
519           break;
520         case REL_ALIAS:
521           f_print (fout, "%s%s %s", prefix, old, name);
522           break;
523         }
524       f_print (fout, ";\n");
525     }
526 }
527
528 void
529 pdeclaration (const char *name, declaration * dec, int tab,
530               const char *separator)
531 {
532   char buf[8];                  /* enough to hold "struct ", include NUL */
533   const char *prefix;
534   const char *type;
535
536   if (streq (dec->type, "void"))
537     {
538       return;
539     }
540   tabify (fout, tab);
541   if (streq (dec->type, name) && !dec->prefix)
542     {
543       f_print (fout, "struct ");
544     }
545   if (streq (dec->type, "string"))
546     {
547       f_print (fout, "char *%s", dec->name);
548     }
549   else
550     {
551       prefix = "";
552       if (streq (dec->type, "bool"))
553         {
554           type = "bool_t";
555         }
556       else if (streq (dec->type, "opaque"))
557         {
558           type = "char";
559         }
560       else
561         {
562           if (dec->prefix)
563             {
564               s_print (buf, "%s ", dec->prefix);
565               prefix = buf;
566             }
567           type = dec->type;
568         }
569       switch (dec->rel)
570         {
571         case REL_ALIAS:
572           f_print (fout, "%s%s %s", prefix, type, dec->name);
573           break;
574         case REL_VECTOR:
575           f_print (fout, "%s%s %s[%s]", prefix, type, dec->name,
576                    dec->array_max);
577           break;
578         case REL_POINTER:
579           f_print (fout, "%s%s *%s", prefix, type, dec->name);
580           break;
581         case REL_ARRAY:
582           f_print (fout, "struct {\n");
583           tabify (fout, tab);
584           f_print (fout, "\tu_int %s_len;\n", dec->name);
585           tabify (fout, tab);
586           f_print (fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
587           tabify (fout, tab);
588           f_print (fout, "} %s", dec->name);
589           break;
590         }
591     }
592   f_print (fout, separator);
593 }
594
595 static int
596 undefined2 (const char *type, const char *stop)
597 {
598   list *l;
599   definition *def;
600
601   for (l = defined; l != NULL; l = l->next)
602     {
603       def = (definition *) l->val;
604       if (def->def_kind != DEF_PROGRAM)
605         {
606           if (streq (def->def_name, stop))
607             {
608               return 1;
609             }
610           else if (streq (def->def_name, type))
611             {
612               return 0;
613             }
614         }
615     }
616   return 1;
617 }