2004-03-20 Joseph S. Myers <jsm@polyomino.org.uk>
[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 int define_printed (proc_list * stop, version_list * start);
52 static void pprogramdef (definition * def);
53 static void parglist (proc_list * proc, const char *addargtype);
54 static void penumdef (definition * def);
55 static void ptypedef (definition * def);
56 static int undefined2 (const char *type, const char *stop);
57
58 /* store away enough information to allow the XDR functions to be spat
59     out at the end of the file */
60
61 static void
62 storexdrfuncdecl (const char *name, int pointerp)
63 {
64   xdrfunc * xdrptr;
65
66   xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc));
67
68   xdrptr->name = (char *)name;
69   xdrptr->pointerp = pointerp;
70   xdrptr->next = NULL;
71
72   if (xdrfunc_tail == NULL)
73     {
74       xdrfunc_head = xdrptr;
75       xdrfunc_tail = xdrptr;
76     }
77   else
78     {
79       xdrfunc_tail->next = xdrptr;
80       xdrfunc_tail = xdrptr;
81     }
82 }
83
84 /*
85  * Print the C-version of an xdr definition
86  */
87 void
88 print_datadef (definition *def)
89 {
90
91   if (def->def_kind == DEF_PROGRAM)     /* handle data only */
92     return;
93
94   if (def->def_kind != DEF_CONST)
95     {
96       f_print (fout, "\n");
97     }
98   switch (def->def_kind)
99     {
100     case DEF_STRUCT:
101       pstructdef (def);
102       break;
103     case DEF_UNION:
104       puniondef (def);
105       break;
106     case DEF_ENUM:
107       penumdef (def);
108       break;
109     case DEF_TYPEDEF:
110       ptypedef (def);
111       break;
112     case DEF_PROGRAM:
113       pprogramdef (def);
114       break;
115     case DEF_CONST:
116       pconstdef (def);
117       break;
118     }
119   if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST)
120     {
121       storexdrfuncdecl(def->def_name,
122                        def->def_kind != DEF_TYPEDEF ||
123                        !isvectordef(def->def.ty.old_type,
124                                     def->def.ty.rel));
125     }
126 }
127
128
129 void
130 print_funcdef (definition *def)
131 {
132   switch (def->def_kind)
133     {
134     case DEF_PROGRAM:
135       f_print (fout, "\n");
136       pprogramdef (def);
137       break;
138     default:
139       break;
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, 1);
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 int
255 define_printed (proc_list *stop, version_list *start)
256 {
257   version_list *vers;
258   proc_list *proc;
259
260   for (vers = start; vers != NULL; vers = vers->next)
261     {
262       for (proc = vers->procs; proc != NULL; proc = proc->next)
263         {
264           if (proc == stop)
265             {
266               return 0;
267             }
268           else if (streq (proc->proc_name, stop->proc_name))
269             {
270               return 1;
271             }
272         }
273     }
274   abort ();
275   /* NOTREACHED */
276 }
277
278 static void
279 pfreeprocdef (const char *name, const char *vers, int mode)
280 {
281   f_print (fout, "extern int ");
282   pvname (name, vers);
283   if (mode == 1)
284     f_print (fout,"_freeresult (SVCXPRT *, xdrproc_t, caddr_t);\n");
285   else
286     f_print (fout,"_freeresult ();\n");
287 }
288
289 static void
290 pprogramdef (definition *def)
291 {
292   version_list *vers;
293   proc_list *proc;
294   int i;
295   const char *ext;
296
297   pargdef (def);
298
299   pdefine (def->def_name, def->def.pr.prog_num);
300   for (vers = def->def.pr.versions; vers != NULL; vers = vers->next)
301     {
302       if (tblflag)
303         {
304           f_print (fout, "extern struct rpcgen_table %s_%s_table[];\n",
305                    locase (def->def_name), vers->vers_num);
306           f_print (fout, "extern %s_%s_nproc;\n",
307                    locase (def->def_name), vers->vers_num);
308         }
309       pdefine (vers->vers_name, vers->vers_num);
310
311       /*
312        * Print out 2 definitions, one for ANSI-C, another for
313        * old K & R C
314        */
315
316       if(!Cflag)
317         {
318           ext = "extern  ";
319           for (proc = vers->procs; proc != NULL;
320                proc = proc->next)
321             {
322               if (!define_printed(proc, def->def.pr.versions))
323                 {
324                   pdefine (proc->proc_name, proc->proc_num);
325                 }
326               f_print (fout, "%s", ext);
327               pprocdef (proc, vers, NULL, 0, 2);
328
329               if (mtflag)
330                 {
331                   f_print(fout, "%s", ext);
332                   pprocdef (proc, vers, NULL, 1, 2);
333                 }
334             }
335           pfreeprocdef (def->def_name, vers->vers_num, 2);
336         }
337       else
338         {
339           for (i = 1; i < 3; i++)
340             {
341               if (i == 1)
342                 {
343                   f_print (fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
344                   ext = "extern  ";
345                 }
346               else
347                 {
348                   f_print (fout, "\n#else /* K&R C */\n");
349                   ext = "extern  ";
350                 }
351
352               for (proc = vers->procs; proc != NULL; proc = proc->next)
353                 {
354                   if (!define_printed(proc, def->def.pr.versions))
355                     {
356                       pdefine(proc->proc_name, proc->proc_num);
357                     }
358                   f_print (fout, "%s", ext);
359                   pprocdef (proc, vers, "CLIENT *", 0, i);
360                   f_print (fout, "%s", ext);
361                   pprocdef (proc, vers, "struct svc_req *", 1, i);
362                 }
363               pfreeprocdef (def->def_name, vers->vers_num, i);
364             }
365           f_print (fout, "#endif /* K&R C */\n");
366         }
367     }
368 }
369
370 void
371 pprocdef (proc_list * proc, version_list * vp,
372           const char *addargtype, int server_p, int mode)
373 {
374   if (mtflag)
375     {/* Print MT style stubs */
376       if (server_p)
377         f_print (fout, "bool_t ");
378       else
379         f_print (fout, "enum clnt_stat ");
380     }
381   else
382     {
383       ptype (proc->res_prefix, proc->res_type, 1);
384       f_print (fout, "* ");
385     }
386   if (server_p)
387     pvname_svc (proc->proc_name, vp->vers_num);
388   else
389     pvname (proc->proc_name, vp->vers_num);
390
391   /*
392    * mode  1 = ANSI-C, mode 2 = K&R C
393    */
394   if (mode == 1)
395     parglist (proc, addargtype);
396   else
397     f_print (fout, "();\n");
398 }
399
400 /* print out argument list of procedure */
401 static void
402 parglist (proc_list *proc, const char *addargtype)
403 {
404   decl_list *dl;
405
406   f_print(fout,"(");
407   if (proc->arg_num < 2 && newstyle &&
408       streq (proc->args.decls->decl.type, "void"))
409     {
410       /* 0 argument in new style:  do nothing */
411     }
412   else
413     {
414       for (dl = proc->args.decls; dl != NULL; dl = dl->next)
415         {
416           ptype (dl->decl.prefix, dl->decl.type, 1);
417           if (!newstyle)
418             f_print (fout, "*");        /* old style passes by reference */
419
420           f_print (fout, ", ");
421         }
422     }
423   if (mtflag)
424     {
425       ptype(proc->res_prefix, proc->res_type, 1);
426       f_print(fout, "*, ");
427     }
428
429   f_print (fout, "%s);\n", addargtype);
430 }
431
432 static void
433 penumdef (definition *def)
434 {
435   const char *name = def->def_name;
436   enumval_list *l;
437   const char *last = NULL;
438   int count = 0;
439
440   f_print (fout, "enum %s {\n", name);
441   for (l = def->def.en.vals; l != NULL; l = l->next)
442     {
443       f_print (fout, "\t%s", l->name);
444       if (l->assignment)
445         {
446           f_print (fout, " = %s", l->assignment);
447           last = l->assignment;
448           count = 1;
449         }
450       else
451         {
452           if (last == NULL)
453             {
454               f_print (fout, " = %d", count++);
455             }
456           else
457             {
458               f_print (fout, " = %s + %d", last, count++);
459             }
460         }
461       f_print (fout, ",\n");
462     }
463   f_print (fout, "};\n");
464   f_print (fout, "typedef enum %s %s;\n", name, name);
465 }
466
467 static void
468 ptypedef (definition *def)
469 {
470   const char *name = def->def_name;
471   const char *old = def->def.ty.old_type;
472   char prefix[8];         /* enough to contain "struct ", including NUL */
473   relation rel = def->def.ty.rel;
474
475   if (!streq (name, old))
476     {
477       if (streq (old, "string"))
478         {
479           old = "char";
480           rel = REL_POINTER;
481         }
482       else if (streq (old, "opaque"))
483         {
484           old = "char";
485         }
486       else if (streq (old, "bool"))
487         {
488           old = "bool_t";
489         }
490       if (undefined2 (old, name) && def->def.ty.old_prefix)
491         {
492           s_print (prefix, "%s ", def->def.ty.old_prefix);
493         }
494       else
495         {
496           prefix[0] = 0;
497         }
498       f_print (fout, "typedef ");
499       switch (rel)
500         {
501         case REL_ARRAY:
502           f_print (fout, "struct {\n");
503           f_print (fout, "\tu_int %s_len;\n", name);
504           f_print (fout, "\t%s%s *%s_val;\n", prefix, old, name);
505           f_print (fout, "} %s", name);
506           break;
507         case REL_POINTER:
508           f_print (fout, "%s%s *%s", prefix, old, name);
509           break;
510         case REL_VECTOR:
511           f_print (fout, "%s%s %s[%s]", prefix, old, name,
512                    def->def.ty.array_max);
513           break;
514         case REL_ALIAS:
515           f_print (fout, "%s%s %s", prefix, old, name);
516           break;
517         }
518       f_print (fout, ";\n");
519     }
520 }
521
522 void
523 pdeclaration (const char *name, declaration * dec, int tab,
524               const char *separator)
525 {
526   char buf[8];                  /* enough to hold "struct ", include NUL */
527   const char *prefix;
528   const char *type;
529
530   if (streq (dec->type, "void"))
531     {
532       return;
533     }
534   tabify (fout, tab);
535   if (streq (dec->type, name) && !dec->prefix)
536     {
537       f_print (fout, "struct ");
538     }
539   if (streq (dec->type, "string"))
540     {
541       f_print (fout, "char *%s", dec->name);
542     }
543   else
544     {
545       prefix = "";
546       if (streq (dec->type, "bool"))
547         {
548           type = "bool_t";
549         }
550       else if (streq (dec->type, "opaque"))
551         {
552           type = "char";
553         }
554       else
555         {
556           if (dec->prefix)
557             {
558               s_print (buf, "%s ", dec->prefix);
559               prefix = buf;
560             }
561           type = dec->type;
562         }
563       switch (dec->rel)
564         {
565         case REL_ALIAS:
566           f_print (fout, "%s%s %s", prefix, type, dec->name);
567           break;
568         case REL_VECTOR:
569           f_print (fout, "%s%s %s[%s]", prefix, type, dec->name,
570                    dec->array_max);
571           break;
572         case REL_POINTER:
573           f_print (fout, "%s%s *%s", prefix, type, dec->name);
574           break;
575         case REL_ARRAY:
576           f_print (fout, "struct {\n");
577           tabify (fout, tab);
578           f_print (fout, "\tu_int %s_len;\n", dec->name);
579           tabify (fout, tab);
580           f_print (fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
581           tabify (fout, tab);
582           f_print (fout, "} %s", dec->name);
583           break;
584         }
585     }
586   f_print (fout, separator);
587 }
588
589 static int
590 undefined2 (const char *type, const char *stop)
591 {
592   list *l;
593   definition *def;
594
595   for (l = defined; l != NULL; l = l->next)
596     {
597       def = (definition *) l->val;
598       if (def->def_kind != DEF_PROGRAM)
599         {
600           if (streq (def->def_name, stop))
601             {
602               return 1;
603             }
604           else if (streq (def->def_name, type))
605             {
606               return 0;
607             }
608         }
609     }
610   return 1;
611 }