.
[kopensolaris-gnu/glibc.git] / sunrpc / rpc_clntout.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_clntout.c 1.11 89/02/22 (C) 1987 SMI
33  */
34 #if defined(LIBC_SCCS) && !defined(lint)
35 static const char clntout_rcsid[] =
36   "$Id$";
37 #endif
38
39 /*
40  * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
41  * Copyright (C) 1987, Sun Microsystems, Inc.
42  */
43 #include <stdio.h>
44 #include <string.h>
45 #include <rpc/types.h>
46 #include "rpc_parse.h"
47 #include "rpc_util.h"
48 #include "proto.h"
49
50 #define DEFAULT_TIMEOUT 25      /* in seconds */
51 static const char RESULT[] = "clnt_res";
52
53 static void write_program (definition * def);
54 static void printbody (proc_list * proc);
55 static const char *ampr (const char *type);
56 static void printbody (proc_list * proc);
57
58
59 void
60 write_stubs (void)
61 {
62   list *l;
63   definition *def;
64
65   fprintf (fout,
66            "\n/* Default timeout can be changed using clnt_control() */\n");
67   fprintf (fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
68            DEFAULT_TIMEOUT);
69   for (l = defined; l != NULL; l = l->next)
70     {
71       def = (definition *) l->val;
72       if (def->def_kind == DEF_PROGRAM)
73         {
74           write_program (def);
75         }
76     }
77 }
78
79 static void
80 write_program (definition * def)
81 {
82   version_list *vp;
83   proc_list *proc;
84
85   for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
86     {
87       for (proc = vp->procs; proc != NULL; proc = proc->next)
88         {
89           fprintf (fout, "\n");
90           if (mtflag == 0)
91             {
92               ptype (proc->res_prefix, proc->res_type, 1);
93               fprintf (fout, "*\n");
94               pvname (proc->proc_name, vp->vers_num);
95               printarglist (proc, RESULT, "clnt", "CLIENT *");
96             }
97           else
98             {
99               fprintf (fout, "enum clnt_stat \n");
100               pvname (proc->proc_name, vp->vers_num);
101               printarglist (proc, RESULT, "clnt", "CLIENT *");
102             }
103           fprintf (fout, "{\n");
104           printbody (proc);
105           fprintf (fout, "}\n");
106         }
107     }
108 }
109
110 /* Writes out declarations of procedure's argument list.
111    In either ANSI C style, in one of old rpcgen style (pass by reference),
112    or new rpcgen style (multiple arguments, pass by value);
113  */
114
115 /* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
116
117 void
118 printarglist (proc_list * proc,  const char *result,
119               const char *addargname, const char *addargtype)
120 {
121
122   decl_list *l;
123
124   if (!newstyle)
125     { /* old style: always pass argument by reference */
126       if (Cflag)
127         {                       /* C++ style heading */
128           fprintf (fout, "(");
129           ptype (proc->args.decls->decl.prefix,
130                  proc->args.decls->decl.type, 1);
131
132           if (mtflag)
133             {/* Generate result field */
134               fprintf (fout, "*argp, ");
135               ptype(proc->res_prefix, proc->res_type, 1);
136               fprintf (fout, "*%s, %s%s)\n", result, addargtype, addargname);
137             }
138           else
139             fprintf (fout, "*argp, %s%s)\n", addargtype, addargname);
140         }
141       else
142         {
143           if (!mtflag)
144             fprintf (fout, "(argp, %s)\n", addargname);
145           else
146             fprintf (fout, "(argp, %s, %s)\n", result, addargname);
147           fprintf (fout, "\t");
148           ptype (proc->args.decls->decl.prefix,
149                  proc->args.decls->decl.type, 1);
150           fprintf (fout, "*argp;\n");
151           if (mtflag)
152             {
153               fprintf (fout, "\t");
154               ptype (proc->res_prefix, proc->res_type, 1);
155               fprintf (fout, "*%s;\n", result);
156             }
157         }
158     }
159   else if (streq (proc->args.decls->decl.type, "void"))
160     {
161       /* newstyle, 0 argument */
162       if (mtflag)
163         {
164           fprintf (fout, "(");
165           if (Cflag)
166             {
167               ptype(proc->res_prefix, proc->res_type, 1);
168               fprintf (fout, "*%s, %s%s)\n", result, addargtype, addargname);
169             }
170           else
171             fprintf (fout, "(%s)\n", addargname);
172         }
173       else if (Cflag)
174         fprintf (fout, "(%s%s)\n", addargtype, addargname);
175       else
176         fprintf (fout, "(%s)\n", addargname);
177     }
178   else
179     {
180       /* new style, 1 or multiple arguments */
181       if (!Cflag)
182         {
183           fprintf (fout, "(");
184           for (l = proc->args.decls; l != NULL; l = l->next)
185             fprintf (fout, "%s, ", l->decl.name);
186           if (mtflag)
187             fprintf (fout, "%s, ", result);
188           fprintf (fout, "%s)\n", addargname);
189           for (l = proc->args.decls; l != NULL; l = l->next)
190             {
191               pdeclaration (proc->args.argname, &l->decl, 1, ";\n");
192             }
193           if (mtflag)
194             {
195               fprintf (fout, "\t");
196               ptype (proc->res_prefix, proc->res_type, 1);
197               fprintf (fout, "*%s;\n", result);
198             }
199         }
200       else
201         {                       /* C++ style header */
202           fprintf (fout, "(");
203           for (l = proc->args.decls; l != NULL; l = l->next)
204             {
205               pdeclaration (proc->args.argname, &l->decl, 0, ", ");
206             }
207           if (mtflag)
208             {
209               ptype (proc->res_prefix, proc->res_type, 1);
210               fprintf (fout, "*%s, ", result);
211             }
212           fprintf (fout, " %s%s)\n", addargtype, addargname);
213         }
214     }
215
216   if (!Cflag)
217     fprintf (fout, "\t%s%s;\n", addargtype, addargname);
218 }
219
220
221 static
222 const char *
223 ampr (const char *type)
224 {
225   if (isvectordef (type, REL_ALIAS))
226     {
227       return "";
228     }
229   else
230     {
231       return "&";
232     }
233 }
234
235 static void
236 printbody (proc_list * proc)
237 {
238   decl_list *l;
239   bool_t args2 = (proc->arg_num > 1);
240 /*  int i; */
241
242   /* For new style with multiple arguments, need a structure in which
243      to stuff the arguments. */
244   if (newstyle && args2)
245     {
246       fprintf (fout, "\t%s", proc->args.argname);
247       fprintf (fout, " arg;\n");
248     }
249   if (!mtflag)
250     {
251       fprintf (fout, "\tstatic ");
252       if (streq (proc->res_type, "void"))
253         {
254           fprintf (fout, "char ");
255         }
256       else
257         {
258           ptype (proc->res_prefix, proc->res_type, 0);
259         }
260       fprintf (fout, "%s;\n", RESULT);
261       fprintf (fout, "\n");
262       fprintf (fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n",
263                ampr (proc->res_type), RESULT, RESULT);
264     }
265   if (newstyle && !args2 && (streq (proc->args.decls->decl.type, "void")))
266     {
267       /* newstyle, 0 arguments */
268       if (mtflag)
269         fprintf (fout, "\t return ");
270       else
271         fprintf (fout, "\t if ");
272       fprintf (fout,
273                "(clnt_call (clnt, %s, (xdrproc_t) xdr_void, ", proc->proc_name);
274
275       fprintf (fout,
276                "(caddr_t) NULL,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
277                stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
278                RESULT);
279       if (mtflag)
280         fprintf (fout, "\n\t\tTIMEOUT));\n\n");
281       else
282         fprintf (fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
283     }
284   else if (newstyle && args2)
285     {
286       /* newstyle, multiple arguments:  stuff arguments into structure */
287       for (l = proc->args.decls; l != NULL; l = l->next)
288         {
289           fprintf (fout, "\targ.%s = %s;\n",
290                    l->decl.name, l->decl.name);
291         }
292       if (mtflag)
293         fprintf (fout, "\treturn ");
294       else
295         fprintf (fout, "\tif ");
296
297       fprintf (fout,
298                "(clnt_call (clnt, %s, (xdrproc_t) xdr_%s", proc->proc_name,
299                proc->args.argname);
300       fprintf (fout,
301                ", (caddr_t) &arg,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
302                stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
303                RESULT);
304       if (mtflag)
305         fprintf (fout, "\n\t\tTIMEOUT));\n");
306       else
307         fprintf (fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
308     }
309   else
310     {                           /* single argument, new or old style */
311       if (!mtflag)
312         fprintf (fout,
313                  "\tif (clnt_call (clnt, %s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\tTIMEOUT) != RPC_SUCCESS) {\n",
314                  proc->proc_name,
315                  stringfix (proc->args.decls->decl.type),
316                  (newstyle ? "&" : ""),
317                  (newstyle ? proc->args.decls->decl.name : "argp"),
318                  stringfix (proc->res_type), ampr (proc->res_type),
319                  RESULT);
320       else
321         fprintf(fout,
322                 "\treturn (clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\tTIMEOUT));\n",
323                 proc->proc_name,
324                 stringfix (proc->args.decls->decl.type),
325                 (newstyle ? "&" : ""),
326                 (newstyle ? proc->args.decls->decl.name : "argp"),
327                 stringfix (proc->res_type), "",
328                 RESULT);
329     }
330   if (!mtflag)
331     {
332       fprintf (fout, "\t\treturn (NULL);\n");
333       fprintf (fout, "\t}\n");
334       if (streq (proc->res_type, "void"))
335         {
336           fprintf (fout, "\treturn ((void *)%s%s);\n",
337                    ampr (proc->res_type), RESULT);
338         }
339       else
340         {
341           fprintf (fout, "\treturn (%s%s);\n", ampr (proc->res_type), RESULT);
342         }
343     }
344 }