#ifndef lint
static char sccsid[] = "@(#)rpc←clntout.c 1.1 90/10/29 (C) 1987 SMI";
#endif
/*
* rpc←clntout.c, Client-stub outputter for the RPC protocol compiler
* Copyright (C) 1987, Sun Microsytsems, Inc.
*/
#include <stdio.h>
#include <strings.h>
#include "rpc←parse.h"
#include "rpc←util.h"
void
write←stubs(svcName)
char *svcName;
{
list *l;
definition *def;
for (l = CurrentContext->defined; l != NULL; l = l->next) {
def = (definition *) l->val;
if (def->def←kind == DEF←PROGRAM) {
write←program(svcName, def);
}
}
}
static
EmitProcSignature(vp, proc, pvName, defStruct, o, res, recoverySuffix)
version←list *vp;
proc←list *proc;
char *pvName;
definition *defStruct;
char *o, *res;
char *recoverySuffix;
{
decl←list *dl;
f←print(fout, "\n");
if (BadProgNameFlag[CurrentProgNameFlag]) {
f←print(fout,
"%s%s: PROC[%s: %s.%s%s",
locase(proc->proc←name), vp->vers←num,
o, svcName, svcName, pvName);
}
else {
f←print(fout,
"%s%s: PROC[%s: %s.%s",
locase(proc->proc←name), vp->vers←num,
o, svcName, pvName);
}
if (ExpandProcArgs && defStruct != NULL &&
defStruct->def←kind == DEF←STRUCT) {
f←print(fout, ",\n");
for (dl = defStruct->def.st.decls;
dl != NULL;
dl = dl->next) {
pdeclaration(defStruct->def←name, &(dl->decl), 16, FALSE);
if (dl->next == NULL)
f←print(fout, "]");
else
f←print(fout, ",\n");
}
}
else {
if (!streq(proc->arg←type, "void")) {
f←print(fout, ", in: %s]",
MapToCedarType(proc->arg←type, FALSE));
}
else {
f←print(fout, "]");
}
}
if (!streq(proc->res←type, "void"))
f←print(fout,
"\n\t\tRETURNS [%s: %s] = {\n", res,
MapToCedarType(proc->res←type, FALSE));
else
f←print(fout, " = {\n");
}
static
write←program(svcName, def)
char *svcName;
definition *def;
{
version←list *vp;
proc←list *proc;
char pvName[256];
int inArg, outArg;
char *srcMethod;
definition *defStruct;
decl←list *dl;
int expandFlag;
extern definition *FindStructDefn();
char *o, *res;
char rpcHandle[256];
char *recoverySuffix = "";
char *mName;
char *sp;
CurrentProgNameFlag++;
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
strcpy(pvName, def->def←name);
strcat(pvName, vp->vers←num);
if (PCedar) {
f←print(fout,
"\nImportByName%s: PUBLIC PROC[name: ROPE]\n",
pvName);
f←print(fout, "\t\tRETURNS [h: %s.%s] = {\n",
svcName, pvName);
f←print(fout, " };\n\n");
if (PCedarUDP) {
f←print(fout,
"Import%s: PUBLIC PROC[b: %s.Address ← %s.nullAddress]\n",
pvName, SunRPC, SunRPC);
}
else { /* PCedarTCP */
f←print(fout,
"ImportStream%s: PUBLIC PROC[b: %s.Address ← %s.nullAddress]\n",
pvName, SunRPC, SunRPC);
}
f←print(fout, "\t\tRETURNS [h: %s.%s] = {\n",
svcName, pvName);
f←print(fout, " rh: %s.Handle;\n", SunRPC);
f←print(fout,
" rhPM: SunRPC.Handle ← SunRPC.Create[b, Basics.HFromCard16[SunPMap.udpPort]];\n");
f←print(fout,
" c: SunRPCAuth.Conversation ← SunRPCAuth.Initiate[];\n");
f←print(fout,
" port: CARDINAL ← SunPMapClient.GetPort[rhPM, c,\n");
if (PCedarUDP) {
f←print(fout,
"\t\t%s.%s, %s, SunPMap.ipProtocolUDP];\n\n",
svcName, def->def←name, vp->vers←num);
}
else { /* PCedarTCP */
f←print(fout,
"\t\t%s.%s, %s, SunPMap.ipProtocolTCP];\n\n",
svcName, def->def←name, vp->vers←num);
f←print(fout,
"remoteAddress: ROPE ← Rope.Cat[Convert.RopeFromArpaAddress[b], \":\", Convert.RopeFromCard[port]];\n");
}
f←print(fout, " IF port = 0 THEN ERROR;\n");
if (PCedarUDP) {
f←print(fout, " rh ← %s.SetRemote[rhPM, b, Basics.HFromCard16[Basics.LowHalf[port]]];\n",
SunRPC);
}
else { /* PCedarTCP */
f←print(fout,
" rh ← %s.Create[$ARPA, remoteAddress];\n",
SunRPC, SunRPC);
}
f←print(fout, " h ← NEW[%s.%sObject];\n",
svcName, pvName);
f←print(fout, " h.rpcHandle ← rh;\n");
f←print(fout, " h.rpcConversation ← c;\n");
for (proc = vp->procs; proc != NULL; proc = proc->next) {
f←print(fout, " h.%s ← %s%s;\n",
locase(proc->proc←name),
locase(proc->proc←name), vp->vers←num);
}
f←print(fout, " };\n\n");
}
else {
if (BadProgNameFlag[CurrentProgNameFlag]) {
f←print(fout,
"Make%s%sClient: PUBLIC PROC [h: %s.Handle,\n",
svcName, pvName, SunRPC);
f←print(fout,
"\tc: SunRPCAuth.Conversation] RETURNS [%s.%s%s] ~ {\n",
svcName, svcName, pvName);
f←print(fout,
" RETURN [NEW[%s.%s%sObject ← [\n",
svcName, svcName, pvName);
}
else {
f←print(fout,
"Make%sClient: PUBLIC PROC [h: %s.Handle,\n",
pvName, SunRPC);
f←print(fout,
"\tc: SunRPCAuth.Conversation] RETURNS [%s.%s] ~ {\n",
svcName, pvName);
f←print(fout,
" RETURN [NEW[%s.%sObject ← [\n",
svcName, pvName);
}
for (proc = vp->procs; proc != NULL; proc = proc->next) {
f←print(fout, "\t%s%s",
locase(proc->proc←name), vp->vers←num);
f←print(fout, ",\n");
}
f←print(fout, "\th, c, NIL]]];\n");
f←print(fout, " };\n\n");
}
for (proc = vp->procs; proc != NULL; proc = proc->next) {
expandFlag = FALSE;
o = "o";
res = "res";
if (ExpandProcArgs) {
defStruct = FindStructDefn(proc->arg←type);
if (defStruct != NULL) {
o = FindUniqueName("o", defStruct->def.st.decls);
sprintf(rpcHandle, "%s.rpcHandle", o);
res = FindUniqueName("res", defStruct->def.st.decls);
}
}
if (ExpandProcArgs && defStruct != NULL &&
defStruct->def←kind == DEF←STRUCT) {
inArg = TRUE;
expandFlag = TRUE;
}
else {
if (!streq(proc->arg←type, "void"))
inArg = TRUE;
else
inArg = FALSE;
}
if (!streq(proc->res←type, "void")) {
outArg = TRUE;
}
else {
outArg = FALSE;
}
EmitProcSignature(vp, proc, pvName, defStruct, o, res, "");
f←print(fout, " %s.StartCall[%s.rpcHandle, %s.rpcConversation,\n",
SunRPC, o, o);
if (BadProgNameFlag[CurrentProgNameFlag]) {
f←print(fout, " %s.%sPrognum, %s, %s];\n",
svcName, svcName, vp->vers←num,
proc->proc←num);
}
else {
f←print(fout, " %s.%s, %s, %s];\n",
svcName, def->def←name, vp->vers←num,
proc->proc←num);
}
if (inArg) {
if (expandFlag) {
for (dl = defStruct->def.st.decls;
dl != NULL;
dl = dl->next) {
emit←put←stat(&(dl->decl), "", "", FALSE, rpcHandle);
}
}
else {
srcMethod = rpcgenBaseType(proc->arg←type);
if (srcMethod != NULL)
f←print(fout,
" %s.Put%s[%s.rpcHandle,in];\n",
SunRPC, srcMethod, o);
else {
mName = ModuleName(proc->arg←type);
f←print(fout,
" %sGetPut.Put%s[%s.rpcHandle, in];\n",
mName, StripPrefix(mName, proc->arg←type), o);
}
}
}
if (PCedarTCP) {
f←print(fout,
" [] ← %s.SendCallAndReceiveReply[%s.rpcHandle];\n",
SunRPC, o);
}
else { /* Either PCedarUDP or Cedar10 case. */
f←print(fout,
" [] ← %s.SendCallAndReceiveReply[%s.rpcHandle, defaultTimeout, defaultRetries];\n",
SunRPC, o);
}
if (outArg) {
srcMethod = rpcgenBaseType(proc->res←type);
if (srcMethod != NULL)
f←print(fout,
" %s ← %s.Get%s[%s.rpcHandle];\n",
res, SunRPC, srcMethod, o);
else {
mName = ModuleName(proc->res←type);
if (streq(mName, svcName))
sp = proc->res←type;
else
sp = StripPrefix(mName, proc->res←type);
f←print(fout,
" %s ← %sGetPut.Get%s[%s.rpcHandle];\n",
res, mName, sp, o);
}
}
f←print(fout, " %s.ReleaseReply[%s.rpcHandle];\n", SunRPC, o);
f←print(fout, " };\n");
}
}
}