rpc_clntout.c revision 92921
11897Swollman/*
21897Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
31897Swollman * unrestricted use provided that this legend is included on all tape
41897Swollman * media and as a part of the software program in whole or part.  Users
51897Swollman * may copy or modify Sun RPC without charge, but are not authorized
61897Swollman * to license or distribute it to anyone else except as part of a product or
71897Swollman * program developed by the user.
812798Swpaul *
91897Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
101897Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
111897Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1212798Swpaul *
131897Swollman * Sun RPC is provided with no support and without any obligation on the
141897Swollman * part of Sun Microsystems, Inc. to assist in its use, correction,
151897Swollman * modification or enhancement.
1612798Swpaul *
171897Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
181897Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
191897Swollman * OR ANY PART THEREOF.
2012798Swpaul *
211897Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue
221897Swollman * or profits or other special, indirect and consequential damages, even if
231897Swollman * Sun has been advised of the possibility of such damages.
2412798Swpaul *
251897Swollman * Sun Microsystems, Inc.
261897Swollman * 2550 Garcia Avenue
271897Swollman * Mountain View, California  94043
2892921Simp *
2992921Simp * $FreeBSD: head/usr.bin/rpcgen/rpc_clntout.c 92921 2002-03-22 01:33:25Z imp $
301897Swollman */
3112798Swpaul
3212798Swpaul#ident	"@(#)rpc_clntout.c	1.15	94/04/25 SMI"
3312798Swpaul
341897Swollman#ifndef lint
3512798Swpaulstatic char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
361897Swollman#endif
371897Swollman
381897Swollman/*
391897Swollman * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
401897Swollman * Copyright (C) 1987, Sun Microsytsems, Inc.
411897Swollman */
421897Swollman#include <stdio.h>
4312798Swpaul#include <string.h>
4412798Swpaul#include <rpc/types.h>
451897Swollman#include "rpc_parse.h"
461897Swollman#include "rpc_util.h"
471897Swollman
4892921Simpextern void pdeclaration( char *, declaration *, int, char * );
4992921Simpvoid printarglist( proc_list *, char *, char *, char *);
5092921Simpstatic void write_program( definition * );
5192921Simpstatic void printbody( proc_list * );
5212798Swpaul
5312798Swpaulstatic char RESULT[] = "clnt_res";
5412798Swpaul
5512798Swpaul
561897Swollman#define DEFAULT_TIMEOUT 25	/* in seconds */
571897Swollman
581897Swollman
591897Swollmanvoid
601897Swollmanwrite_stubs()
611897Swollman{
621897Swollman	list *l;
631897Swollman	definition *def;
641897Swollman
6512798Swpaul	f_print(fout,
6612798Swpaul		"\n/* Default timeout can be changed using clnt_control() */\n");
6712798Swpaul	f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
681897Swollman		DEFAULT_TIMEOUT);
691897Swollman	for (l = defined; l != NULL; l = l->next) {
701897Swollman		def = (definition *) l->val;
711897Swollman		if (def->def_kind == DEF_PROGRAM) {
721897Swollman			write_program(def);
731897Swollman		}
741897Swollman	}
751897Swollman}
761897Swollman
7717142Sjkhstatic void
781897Swollmanwrite_program(def)
791897Swollman	definition *def;
801897Swollman{
811897Swollman	version_list *vp;
821897Swollman	proc_list *proc;
831897Swollman
841897Swollman	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
851897Swollman		for (proc = vp->procs; proc != NULL; proc = proc->next) {
861897Swollman			f_print(fout, "\n");
8712798Swpaul			if (mtflag == 0) {
8812798Swpaul				ptype(proc->res_prefix, proc->res_type, 1);
8912798Swpaul				f_print(fout, "*\n");
9012798Swpaul				pvname(proc->proc_name, vp->vers_num);
9112798Swpaul				printarglist(proc, RESULT, "clnt", "CLIENT *");
9212798Swpaul			} else {
9312798Swpaul				f_print(fout, "enum clnt_stat \n");
9412798Swpaul				pvname(proc->proc_name, vp->vers_num);
9512798Swpaul				printarglist(proc, RESULT,  "clnt", "CLIENT *");
9612798Swpaul
9712798Swpaul			}
981897Swollman			f_print(fout, "{\n");
991897Swollman			printbody(proc);
10012798Swpaul
10112798Swpaul			f_print(fout, "}\n");
1021897Swollman		}
1031897Swollman	}
1041897Swollman}
1051897Swollman
10612798Swpaul/*
10712798Swpaul * Writes out declarations of procedure's argument list.
10812798Swpaul * In either ANSI C style, in one of old rpcgen style (pass by reference),
10912798Swpaul * or new rpcgen style (multiple arguments, pass by value);
11012798Swpaul */
11112798Swpaul
11212798Swpaul/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
11312798Swpaul
11412798Swpaulvoid printarglist(proc, result, addargname, addargtype)
11512798Swpaul	proc_list *proc;
11612798Swpaul	char *result;
11712798Swpaul	char* addargname, * addargtype;
11812798Swpaul{
11912798Swpaul
12012798Swpaul	decl_list *l;
12112798Swpaul
12212798Swpaul	if (!newstyle) {
12312798Swpaul		/* old style: always pass argument by reference */
12412798Swpaul		if (Cflag) {	/* C++ style heading */
12512798Swpaul			f_print(fout, "(");
12612798Swpaul			ptype(proc->args.decls->decl.prefix,
12712798Swpaul			      proc->args.decls->decl.type, 1);
12812798Swpaul
12912798Swpaul			if (mtflag) {/* Generate result field */
13012798Swpaul				f_print(fout, "*argp, ");
13112798Swpaul				ptype(proc->res_prefix, proc->res_type, 1);
13212798Swpaul				f_print(fout, "*%s, %s%s)\n",
13312798Swpaul					result, addargtype, addargname);
13412798Swpaul			} else
13512798Swpaul				f_print(fout, "*argp, %s%s)\n", addargtype, addargname);
13612798Swpaul		} else {
13712798Swpaul			if (!mtflag)
13812798Swpaul				f_print(fout, "(argp, %s)\n", addargname);
13912798Swpaul			else
14012798Swpaul				f_print(fout, "(argp, %s, %s)\n",
14112798Swpaul					result, addargname);
14212798Swpaul			f_print(fout, "\t");
14312798Swpaul			ptype(proc->args.decls->decl.prefix,
14412798Swpaul			      proc->args.decls->decl.type, 1);
14512798Swpaul			f_print(fout, "*argp;\n");
14612798Swpaul			if (mtflag) {
14712798Swpaul				f_print(fout, "\t");
14812798Swpaul				ptype(proc->res_prefix, proc->res_type, 1);
14912798Swpaul				f_print(fout, "*%s;\n", result);
15012798Swpaul			}
15112798Swpaul		}
15212798Swpaul	} else if (streq(proc->args.decls->decl.type, "void")) {
15312798Swpaul		/* newstyle, 0 argument */
15412798Swpaul		if (mtflag) {
15512798Swpaul				f_print(fout, "(");
15612798Swpaul
15712798Swpaul
15812798Swpaul			if (Cflag) {
15912798Swpaul				ptype(proc->res_prefix, proc->res_type, 1);
16012798Swpaul				f_print(fout, "*%s, %s%s)\n",
16112798Swpaul					result, addargtype, addargname);
16212798Swpaul			}
16312798Swpaul			else
16412798Swpaul				f_print(fout, "(%s)\n", addargname);
16512798Swpaul
16612798Swpaul		} else
16712798Swpaul		if (Cflag)
16812798Swpaul			f_print(fout, "(%s%s)\n", addargtype, addargname);
16912798Swpaul		else
17012798Swpaul			f_print(fout, "(%s)\n", addargname);
17112798Swpaul	} else {
17212798Swpaul		/* new style, 1 or multiple arguments */
17312798Swpaul		if (!Cflag) {
17412798Swpaul			f_print(fout, "(");
17512798Swpaul			for (l = proc->args.decls;  l != NULL; l = l->next)
17612798Swpaul				f_print(fout, "%s, ", l->decl.name);
17712798Swpaul			if (mtflag)
17812798Swpaul				f_print(fout, "%s, ", result);
17912798Swpaul
18012798Swpaul			f_print(fout, "%s)\n", addargname);
18112798Swpaul			for (l = proc->args.decls; l != NULL; l = l->next) {
18212798Swpaul				pdeclaration(proc->args.argname,
18312798Swpaul					     &l->decl, 1, ";\n");
18412798Swpaul			}
18512798Swpaul			if (mtflag) {
18612798Swpaul				f_print(fout, "\t");
18712798Swpaul				ptype(proc->res_prefix, proc->res_type, 1);
18812798Swpaul				f_print(fout, "*%s;\n", result);
18912798Swpaul			}
19012798Swpaul
19112798Swpaul		} else {	/* C++ style header */
19212798Swpaul			f_print(fout, "(");
19312798Swpaul			for (l = proc->args.decls; l != NULL; l = l->next) {
19412798Swpaul				pdeclaration(proc->args.argname, &l->decl, 0,
19512798Swpaul					     ", ");
19612798Swpaul			}
19712798Swpaul			if (mtflag) {
19812798Swpaul				ptype(proc->res_prefix, proc->res_type, 1);
19912798Swpaul				f_print(fout, "*%s, ", result);
20012798Swpaul
20112798Swpaul			}
20212798Swpaul			f_print(fout, "%s%s)\n", addargtype, addargname);
20312798Swpaul		}
20412798Swpaul	}
20512798Swpaul
20612798Swpaul	if (!Cflag)
20712798Swpaul		f_print(fout, "\t%s%s;\n", addargtype, addargname);
20812798Swpaul}
20912798Swpaul
21012798Swpaul
21112798Swpaul
2121897Swollmanstatic char *
2131897Swollmanampr(type)
2141897Swollman	char *type;
2151897Swollman{
2161897Swollman	if (isvectordef(type, REL_ALIAS)) {
2171897Swollman		return ("");
2181897Swollman	} else {
2191897Swollman		return ("&");
2201897Swollman	}
2211897Swollman}
2221897Swollman
22317142Sjkhstatic void
2241897Swollmanprintbody(proc)
2251897Swollman	proc_list *proc;
2261897Swollman{
22712798Swpaul	decl_list *l;
22812798Swpaul	bool_t args2 = (proc->arg_num > 1);
22912798Swpaul
23012798Swpaul	/*
23112798Swpaul	 * For new style with multiple arguments, need a structure in which
23212798Swpaul	 *  to stuff the arguments.
23312798Swpaul	 */
23412798Swpaul
23512798Swpaul
23612798Swpaul	if (newstyle && args2) {
23712798Swpaul		f_print(fout, "\t%s", proc->args.argname);
23812798Swpaul		f_print(fout, " arg;\n");
2391897Swollman	}
24012798Swpaul	if (!mtflag) {
24112798Swpaul		f_print(fout, "\tstatic ");
24212798Swpaul		if (streq(proc->res_type, "void")) {
24312798Swpaul			f_print(fout, "char ");
24412798Swpaul		} else {
24512798Swpaul			ptype(proc->res_prefix, proc->res_type, 0);
24612798Swpaul		}
24712798Swpaul		f_print(fout, "%s;\n", RESULT);
24812798Swpaul		f_print(fout, "\n");
24912798Swpaul		f_print(fout, "\tmemset((char *)%s%s, 0, sizeof (%s));\n",
25012798Swpaul			ampr(proc->res_type), RESULT, RESULT);
25112798Swpaul
2521897Swollman	}
25312798Swpaul	if (newstyle && !args2 &&
25412798Swpaul	    (streq(proc->args.decls->decl.type, "void"))) {
25512798Swpaul		/* newstyle, 0 arguments */
25612798Swpaul
25712798Swpaul		if (mtflag)
25812798Swpaul			f_print(fout, "\t return ");
25912798Swpaul		else
26012798Swpaul			f_print(fout, "\t if ");
26112798Swpaul
26212798Swpaul		f_print(fout,
26312798Swpaul			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_void, ",
26412798Swpaul			proc->proc_name);
26512798Swpaul		f_print(fout,
26612798Swpaul			"(caddr_t) NULL,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
26712798Swpaul			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
26812798Swpaul			RESULT);
26912798Swpaul
27012798Swpaul		if (mtflag)
27139642Sobrien			f_print(fout, "\n\t\tTIMEOUT));\n");
27212798Swpaul		else
27312798Swpaul			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
27412798Swpaul
27512798Swpaul	} else if (newstyle && args2) {
27612798Swpaul		/*
27712798Swpaul		 * Newstyle, multiple arguments
27812798Swpaul		 * stuff arguments into structure
27912798Swpaul		 */
28012798Swpaul		for (l = proc->args.decls;  l != NULL; l = l->next) {
28112798Swpaul			f_print(fout, "\targ.%s = %s;\n",
28212798Swpaul				l->decl.name, l->decl.name);
28312798Swpaul		}
28412798Swpaul		if (mtflag)
28512798Swpaul			f_print(fout, "\treturn ");
28612798Swpaul		else
28712798Swpaul			f_print(fout, "\tif ");
28812798Swpaul		f_print(fout,
28912798Swpaul			"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s",
29012798Swpaul			proc->proc_name,proc->args.argname);
29112798Swpaul		f_print(fout,
29212798Swpaul			", (caddr_t) &arg,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
29312798Swpaul			stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
29412798Swpaul			RESULT);
29512798Swpaul		if (mtflag)
29612798Swpaul			f_print(fout, "\n\t\tTIMEOUT));\n");
29712798Swpaul		else
29812798Swpaul			f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
29912798Swpaul	} else {		/* single argument, new or old style */
30012798Swpaul		if (!mtflag)
30112798Swpaul			f_print(fout,
30212798Swpaul			"\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",
30312798Swpaul			proc->proc_name,
30412798Swpaul			stringfix(proc->args.decls->decl.type),
30512798Swpaul			(newstyle ? "&" : ""),
30612798Swpaul			(newstyle ? proc->args.decls->decl.name : "argp"),
30712798Swpaul			stringfix(proc->res_type), ampr(proc->res_type),
30812798Swpaul			RESULT);
30912798Swpaul		else
31012798Swpaul
31112798Swpaul		f_print(fout,
31212798Swpaul			"\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",
31312798Swpaul			proc->proc_name,
31412798Swpaul			stringfix(proc->args.decls->decl.type),
31512798Swpaul			(newstyle ? "&" : ""),
31612798Swpaul			(newstyle ? proc->args.decls->decl.name : "argp"),
31712798Swpaul			stringfix(proc->res_type), "",
31812798Swpaul			RESULT);
31912798Swpaul	}
32012798Swpaul	if (!mtflag) {
32112798Swpaul		f_print(fout, "\t\treturn (NULL);\n");
32212798Swpaul		f_print(fout, "\t}\n");
32312798Swpaul
32412798Swpaul		if (streq(proc->res_type, "void")) {
32512798Swpaul			f_print(fout, "\treturn ((void *)%s%s);\n",
32612798Swpaul				ampr(proc->res_type), RESULT);
32712798Swpaul		} else {
32812798Swpaul			f_print(fout, "\treturn (%s%s);\n",
32912798Swpaul				ampr(proc->res_type), RESULT);
33012798Swpaul		}
33112798Swpaul	}
3321897Swollman}
333