Home | History | Annotate | Line # | Download | only in rpcgen
rpc_clntout.c revision 1.10
      1 /*	$NetBSD: rpc_clntout.c,v 1.10 2001/03/21 20:11:01 mycroft Exp $	*/
      2 /*
      3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
      4  * unrestricted use provided that this legend is included on all tape
      5  * media and as a part of the software program in whole or part.  Users
      6  * may copy or modify Sun RPC without charge, but are not authorized
      7  * to license or distribute it to anyone else except as part of a product or
      8  * program developed by the user or with the express written consent of
      9  * Sun Microsystems, Inc.
     10  *
     11  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
     12  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
     13  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
     14  *
     15  * Sun RPC is provided with no support and without any obligation on the
     16  * part of Sun Microsystems, Inc. to assist in its use, correction,
     17  * modification or enhancement.
     18  *
     19  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
     20  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
     21  * OR ANY PART THEREOF.
     22  *
     23  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
     24  * or profits or other special, indirect and consequential damages, even if
     25  * Sun has been advised of the possibility of such damages.
     26  *
     27  * Sun Microsystems, Inc.
     28  * 2550 Garcia Avenue
     29  * Mountain View, California  94043
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 #ifndef lint
     34 #if 0
     35 static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
     36 #else
     37 __RCSID("$NetBSD: rpc_clntout.c,v 1.10 2001/03/21 20:11:01 mycroft Exp $");
     38 #endif
     39 #endif
     40 
     41 /*
     42  * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
     43  * Copyright (C) 1987, Sun Microsytsems, Inc.
     44  */
     45 #include <stdio.h>
     46 #include <string.h>
     47 #include <rpc/types.h>
     48 #include "rpc_scan.h"
     49 #include "rpc_parse.h"
     50 #include "rpc_util.h"
     51 
     52 static void write_program __P((definition *));
     53 static char *ampr __P((char *));
     54 static char *aster __P((char *));
     55 static void printbody __P((proc_list *));
     56 
     57 #define DEFAULT_TIMEOUT 25	/* in seconds */
     58 static char RESULT[] = "clnt_res";
     59 
     60 
     61 void
     62 write_stubs()
     63 {
     64 	list   *l;
     65 	definition *def;
     66 
     67 	f_print(fout,
     68 	    "\n/* Default timeout can be changed using clnt_control() */\n");
     69 	f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
     70 	    DEFAULT_TIMEOUT);
     71 	for (l = defined; l != NULL; l = l->next) {
     72 		def = (definition *) l->val;
     73 		if (def->def_kind == DEF_PROGRAM) {
     74 			write_program(def);
     75 		}
     76 	}
     77 }
     78 
     79 static void
     80 write_program(def)
     81 	definition *def;
     82 {
     83 	version_list *vp;
     84 	proc_list *proc;
     85 
     86 	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
     87 		for (proc = vp->procs; proc != NULL; proc = proc->next) {
     88 			f_print(fout, "\n");
     89 			if (Mflag)
     90 				f_print(fout, "enum clnt_stat\n");
     91 			else {
     92 				ptype(proc->res_prefix, proc->res_type, 1);
     93 				f_print(fout, "*\n");
     94 			}
     95 			pvname(proc->proc_name, vp->vers_num);
     96 			printarglist(proc, RESULT, "clnt", "CLIENT *");
     97 			f_print(fout, "{\n");
     98 			printbody(proc);
     99 			f_print(fout, "}\n");
    100 		}
    101 	}
    102 }
    103 /* Writes out declarations of procedure's argument list.
    104    In either ANSI C style, in one of old rpcgen style (pass by reference),
    105    or new rpcgen style (multiple arguments, pass by value);
    106    */
    107 
    108 /* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
    109 
    110 void
    111 printarglist(proc, result, addargname, addargtype)
    112 	proc_list *proc;
    113 	char   *result, *addargname, *addargtype;
    114 {
    115 
    116 	decl_list *l;
    117 
    118 	if (!newstyle) {	/* old style: always pass argument by
    119 				 * reference */
    120 		if (Cflag) {	/* C++ style heading */
    121 			f_print(fout, "(");
    122 			ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
    123 			f_print(fout, "*argp, ");
    124 			if (Mflag) {
    125 				if (streq(proc->res_type, "void"))
    126 					f_print(fout, "char ");
    127 				else
    128 					ptype(proc->res_prefix, proc->res_type, 0);
    129 				f_print(fout, "%s%s, ", aster(proc->res_type),
    130 				    result);
    131 			}
    132 			f_print(fout, "%s%s)\n", addargtype, addargname);
    133 		} else {
    134 			f_print(fout, "(argp, ");
    135 			if (Mflag)
    136 				f_print(fout, "%s, ", result);
    137 			f_print(fout, "%s)\n", addargname);
    138 			f_print(fout, "\t");
    139 			ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
    140 			f_print(fout, "*argp;\n");
    141 			if (Mflag) {
    142 				f_print(fout, "\t");
    143 				if (streq(proc->res_type, "void"))
    144 					f_print(fout, "char ");
    145 				else
    146 					ptype(proc->res_prefix, proc->res_type, 0);
    147 				f_print(fout, "%s%s;\n", aster(proc->res_type),
    148 				    result);
    149 			}
    150 		}
    151 	} else {
    152 		f_print(fout, "(");
    153 		if (!streq(proc->args.decls->decl.type, "void")) {
    154 			/* new style, 1 or multiple arguments */
    155 			if (!Cflag) {
    156 				for (l = proc->args.decls; l != NULL;
    157 				    l = l->next)
    158 					f_print(fout, "%s, ", l->decl.name);
    159 			} else {/* C++ style header */
    160 				for (l = proc->args.decls; l != NULL;
    161 				    l = l->next)
    162 					pdeclaration(proc->args.argname,
    163 					    &l->decl, 0, ", ");
    164 			}
    165 		}
    166 		if (!Cflag) {
    167 			if (Mflag) {
    168 				f_print(fout, "\t");
    169 				if (streq(proc->res_type, "void"))
    170 					f_print(fout, "char ");
    171 				else
    172 					ptype(proc->res_prefix, proc->res_type, 0);
    173 				f_print(fout, "%s%s;\n", aster(proc->res_type),
    174 				    result);
    175 			}
    176 			f_print(fout, "%s)\n", addargname);
    177 			if (!streq(proc->args.decls->decl.type, "void")) {
    178 				for (l = proc->args.decls; l != NULL;
    179 				    l = l->next)
    180 					pdeclaration(proc->args.argname,
    181 					    &l->decl, 1, ";\n");
    182 			}
    183 		} else {
    184 			if (Mflag) {
    185 				if (streq(proc->res_type, "void"))
    186 					f_print(fout, "char ");
    187 				else
    188 					ptype(proc->res_prefix, proc->res_type, 0);
    189 				f_print(fout, "%s%s, ", aster(proc->res_type),
    190 				    result);
    191 			}
    192 			f_print(fout, "%s%s)\n", addargtype, addargname);
    193 		}
    194 	}
    195 
    196 	if (!Cflag)
    197 		f_print(fout, "\t%s%s;\n", addargtype, addargname);
    198 }
    199 
    200 
    201 static char *
    202 ampr(type)
    203 	char   *type;
    204 {
    205 	if (isvectordef(type, REL_ALIAS)) {
    206 		return ("");
    207 	} else {
    208 		return ("&");
    209 	}
    210 }
    211 
    212 static char *
    213 aster(type)
    214 	char   *type;
    215 {
    216 	if (isvectordef(type, REL_ALIAS)) {
    217 		return ("");
    218 	} else {
    219 		return ("*");
    220 	}
    221 }
    222 
    223 static void
    224 printbody(proc)
    225 	proc_list *proc;
    226 {
    227 	decl_list *l;
    228 	bool_t  args2 = (proc->arg_num > 1);
    229 
    230 	/* For new style with multiple arguments, need a structure in which to
    231 	 * stuff the arguments. */
    232 	if (newstyle && args2) {
    233 		f_print(fout, "\t%s", proc->args.argname);
    234 		f_print(fout, " arg;\n");
    235 	}
    236 	if (!Mflag) {
    237 		f_print(fout, "\tstatic ");
    238 		if (streq(proc->res_type, "void"))
    239 			f_print(fout, "char ");
    240 		else
    241 			ptype(proc->res_prefix, proc->res_type, 0);
    242 		f_print(fout, "%s;\n", RESULT);
    243 	}
    244 	f_print(fout, "\n");
    245 	if (!Mflag)
    246 		f_print(fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n",
    247 		    ampr(proc->res_type), RESULT, RESULT);
    248 	if (newstyle && !args2 && (streq(proc->args.decls->decl.type, "void"))) {
    249 		/* newstyle, 0 arguments */
    250 		if (Mflag) {
    251 			f_print(fout, "\treturn (clnt_call(clnt, %s, xdr_void",
    252 			    proc->proc_name);
    253 			f_print(fout, ", NULL, xdr_%s, %s, TIMEOUT));\n",
    254 			    stringfix(proc->res_type), RESULT);
    255 		} else {
    256 			f_print(fout, "\tif (clnt_call(clnt, %s, xdr_void, ",
    257 			    proc->proc_name);
    258 			f_print(fout,
    259 			    "NULL, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
    260 			    stringfix(proc->res_type), ampr(proc->res_type),
    261 			    RESULT);
    262 		}
    263 	} else {
    264 		if (newstyle && args2) {
    265 			/* newstyle, multiple arguments:  stuff arguments into
    266 			 * structure */
    267 			for (l = proc->args.decls; l != NULL; l = l->next) {
    268 				f_print(fout, "\targ.%s = %s;\n",
    269 				    l->decl.name, l->decl.name);
    270 			}
    271 			if (Mflag) {
    272 				f_print(fout,
    273 				    "\treturn (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %s, TIMEOUT));\n",
    274 				    proc->proc_name, proc->args.argname,
    275 				    stringfix(proc->res_type), RESULT);
    276 			} else {
    277 				f_print(fout,
    278 				    "\tif (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n",
    279 				    proc->proc_name, proc->args.argname,
    280 				    stringfix(proc->res_type),
    281 				    ampr(proc->res_type), RESULT);
    282 			}
    283 		} else {	/* single argument, new or old style */
    284 			if (Mflag) {
    285 				f_print(fout,
    286 				    "\treturn (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s, TIMEOUT));\n",
    287 				    proc->proc_name,
    288 				    stringfix(proc->args.decls->decl.type),
    289 				    (newstyle ? "&" : ""),
    290 				    (newstyle ? proc->args.decls->decl.name : "argp"),
    291 				    stringfix(proc->res_type), RESULT);
    292 			} else {
    293 				f_print(fout,
    294 				    "\tif (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n",
    295 				    proc->proc_name,
    296 				    stringfix(proc->args.decls->decl.type),
    297 				    (newstyle ? "&" : ""),
    298 				    (newstyle ? proc->args.decls->decl.name : "argp"),
    299 				    stringfix(proc->res_type),
    300 				    ampr(proc->res_type), RESULT);
    301 			}
    302 		}
    303 	}
    304 	if (!Mflag) {
    305 		f_print(fout, "\t\treturn (NULL);\n");
    306 		if (streq(proc->res_type, "void"))
    307 			f_print(fout, "\treturn ((void *)%s%s);\n",
    308 			    ampr(proc->res_type), RESULT);
    309 		else
    310 			f_print(fout, "\treturn (%s%s);\n",
    311 			    ampr(proc->res_type), RESULT);
    312 	}
    313 }
    314