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