Home | History | Annotate | Line # | Download | only in rpcgen
rpc_clntout.c revision 1.1.1.1
      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 #ifndef lint
     32 static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
     33 #endif
     34 
     35 /*
     36  * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
     37  * Copyright (C) 1987, Sun Microsytsems, Inc.
     38  */
     39 #include <stdio.h>
     40 #include <string.h>
     41 #include <rpc/types.h>
     42 #include "rpc_parse.h"
     43 #include "rpc_util.h"
     44 
     45 extern pdeclaration();
     46 void printarglist();
     47 
     48 #define DEFAULT_TIMEOUT 25	/* in seconds */
     49 static char RESULT[] = "clnt_res";
     50 
     51 
     52 void
     53 write_stubs()
     54 {
     55 	list *l;
     56 	definition *def;
     57 
     58 	f_print(fout,
     59 		"\n/* Default timeout can be changed using clnt_control() */\n");
     60 	f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
     61 		DEFAULT_TIMEOUT);
     62 	for (l = defined; l != NULL; l = l->next) {
     63 		def = (definition *) l->val;
     64 		if (def->def_kind == DEF_PROGRAM) {
     65 			write_program(def);
     66 		}
     67 	}
     68 }
     69 
     70 static
     71 write_program(def)
     72 	definition *def;
     73 {
     74 	version_list *vp;
     75 	proc_list *proc;
     76 
     77 	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
     78 		for (proc = vp->procs; proc != NULL; proc = proc->next) {
     79 			f_print(fout, "\n");
     80 			ptype(proc->res_prefix, proc->res_type, 1);
     81 			f_print(fout, "*\n");
     82 			pvname(proc->proc_name, vp->vers_num);
     83 			printarglist( proc, "clnt", "CLIENT *" );
     84 			f_print(fout, "{\n");
     85 			printbody(proc);
     86 			f_print(fout, "}\n");
     87 		}
     88 	}
     89 }
     90 
     91 /* Writes out declarations of procedure's argument list.
     92    In either ANSI C style, in one of old rpcgen style (pass by reference),
     93    or new rpcgen style (multiple arguments, pass by value);
     94    */
     95 
     96 /* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
     97 
     98 void printarglist( proc, addargname, addargtype )
     99      proc_list *proc;
    100      char* addargname, * addargtype;
    101 {
    102 
    103   decl_list *l;
    104 
    105   if (!newstyle) {    /* old style: always pass argument by reference */
    106     if (Cflag) {      /* C++ style heading */
    107       f_print(fout, "(");
    108       ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
    109       f_print(fout, "*argp, %s%s)\n", addargtype, addargname );
    110     } else {
    111       f_print(fout, "(argp, %s)\n", addargname);
    112       f_print(fout, "\t");
    113       ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
    114       f_print(fout, "*argp;\n");
    115     }
    116   } else if (streq( proc->args.decls->decl.type, "void")) {
    117     /* newstyle, 0 argument */
    118     if( Cflag )
    119       f_print(fout, "(%s%s)\n", addargtype, addargname );
    120     else
    121       f_print(fout, "(%s)\n", addargname);
    122   } else {
    123     /* new style, 1 or multiple arguments */
    124     if( !Cflag ) {
    125       f_print(fout, "(");
    126       for (l = proc->args.decls;  l != NULL; l = l->next)
    127 	f_print(fout, "%s, ", l->decl.name);
    128       f_print(fout, "%s)\n", addargname );
    129       for (l = proc->args.decls; l != NULL; l = l->next) {
    130 	pdeclaration(proc->args.argname, &l->decl, 1, ";\n" );
    131       }
    132     } else {  /* C++ style header */
    133       f_print(fout, "(");
    134       for(l = proc->args.decls; l != NULL; l = l->next) {
    135 	pdeclaration(proc->args.argname, &l->decl, 0, ", " );
    136       }
    137       f_print(fout, " %s%s)\n", addargtype, addargname );
    138     }
    139   }
    140 
    141   if( !Cflag )
    142     f_print(fout, "\t%s%s;\n", addargtype, addargname );
    143 }
    144 
    145 
    146 
    147 static char *
    148 ampr(type)
    149 	char *type;
    150 {
    151 	if (isvectordef(type, REL_ALIAS)) {
    152 		return ("");
    153 	} else {
    154 		return ("&");
    155 	}
    156 }
    157 
    158 static
    159 printbody(proc)
    160 	proc_list *proc;
    161 {
    162   decl_list *l;
    163   bool_t args2 = (proc->arg_num > 1);
    164   int i;
    165 
    166   /* For new style with multiple arguments, need a structure in which
    167      to stuff the arguments. */
    168 	if ( newstyle && args2) {
    169 		f_print(fout, "\t%s", proc->args.argname);
    170 		f_print(fout, " arg;\n");
    171 	}
    172 	f_print(fout, "\tstatic ");
    173 	if (streq(proc->res_type, "void")) {
    174 		f_print(fout, "char ");
    175 	} else {
    176 		ptype(proc->res_prefix, proc->res_type, 0);
    177 	}
    178 	f_print(fout, "%s;\n",RESULT);
    179 	f_print(fout, "\n");
    180         f_print(fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n",
    181 		ampr(proc->res_type ), RESULT, RESULT);
    182 	if (newstyle && !args2 && (streq( proc->args.decls->decl.type, "void"))) {
    183 	  /* newstyle, 0 arguments */
    184 	  f_print(fout,
    185 		    "\tif (clnt_call(clnt, %s, xdr_void", proc->proc_name);
    186 	  f_print(fout,
    187  		  ", NULL, xdr_%s, %s,%s, TIMEOUT) != RPC_SUCCESS) {\n",
    188  		  stringfix(proc->res_type), ampr(proc->res_type), RESULT);
    189 
    190 	} else if ( newstyle && args2) {
    191 	  /* newstyle, multiple arguments:  stuff arguments into structure */
    192 	  for (l = proc->args.decls;  l != NULL; l = l->next) {
    193 	    f_print(fout, "\targ.%s = %s;\n",
    194 		    l->decl.name, l->decl.name);
    195 	  }
    196 	  f_print(fout,
    197 		  "\tif (clnt_call(clnt, %s, xdr_%s", proc->proc_name,
    198 		  proc->args.argname);
    199 	  f_print(fout,
    200  		      ", &arg, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
    201  		  stringfix(proc->res_type), ampr(proc->res_type), RESULT);
    202 	} else {  /* single argument, new or old style */
    203 	      f_print(fout,
    204  		      "\tif (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
    205 		      proc->proc_name,
    206 		      stringfix(proc->args.decls->decl.type),
    207 		      (newstyle ? "&" : ""),
    208 		      (newstyle ? proc->args.decls->decl.name : "argp"),
    209 		      stringfix(proc->res_type), ampr(proc->res_type),RESULT);
    210 	    }
    211 	f_print(fout, "\t\treturn (NULL);\n");
    212 	f_print(fout, "\t}\n");
    213 	if (streq(proc->res_type, "void")) {
    214 		f_print(fout, "\treturn ((void *)%s%s);\n",
    215 			ampr(proc->res_type),RESULT);
    216 	} else {
    217 		f_print(fout, "\treturn (%s%s);\n", ampr(proc->res_type),RESULT);
    218 	}
    219 }
    220 
    221