#ifndef lint
static char sccsid[] = "@(#)rpc←cout.c 1.1 90/10/29 (C) 1987 SMI";
#endif
/*
* rpc←cout.c, XDR routine outputter for the RPC protocol compiler
* Copyright (C) 1987, Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <strings.h>
#include "rpc←util.h"
#include "rpc←parse.h"
/*
* Emit the interface for the given definition
*/
void
emitDefn(def)
definition *def;
{
if (def->def←kind == DEF←PROGRAM || def->def←kind == DEF←CONST) {
return;
}
f←print(fout,
"Get%s: PROC[h: Handle] RETURNS [res: %s.%s];\n",
def->def←name, svcName, def->def←name);
f←print(fout,
"Put%s: PROC[h: Handle, in: %s.%s];\n\n",
def->def←name, svcName, def->def←name);
}
/*
* Emit the implementation for the given definition
*/
void
emitImpl(def)
definition *def;
{
enumval←list *l;
if (def->def←kind == DEF←PROGRAM || def->def←kind == DEF←CONST) {
return;
}
else if (def->def←kind == DEF←ENUM) {
if (FillEnumAssignments(def->def.en.vals)) {
f←print(fout, "%sNames: PUBLIC ARRAY %s.%s OF ROPE ← [\n",
def->def←name, svcName, def->def←name);
for (l = def->def.en.vals; l != NULL; l = l->next) {
f←print(fout, "\t\"%s\"", l->name);
if (l->next != NULL) f←print(fout, ",\n");
else f←print(fout, "\n");
}
f←print(fout, "\t];\n\n");
}
}
f←print(fout,
"Get%s: PUBLIC PROC[h: Handle] RETURNS [res: %s.%s] = {\n",
def->def←name, svcName, def->def←name);
switch (def->def←kind) {
case DEF←UNION:
emit←union←get(def);
break;
case DEF←ENUM:
emit←enum←get(def);
break;
case DEF←STRUCT:
emit←struct←get(def);
break;
case DEF←TYPEDEF:
emit←typedef←get(def);
break;
}
f←print(fout, " };\n\n");
f←print(fout,
"Put%s: PUBLIC PROC[h: Handle, in: %s.%s] = {\n",
def->def←name, svcName, def->def←name);
switch (def->def←kind) {
case DEF←UNION:
emit←union←put(def);
break;
case DEF←ENUM:
emit←enum←put(def);
break;
case DEF←STRUCT:
emit←struct←put(def);
break;
case DEF←TYPEDEF:
emit←typedef←put(def);
break;
}
f←print(fout, " };\n\n");
}
/* ARGSUSED */
static
emit←enum←get(def)
definition *def;
{
f←print(fout, " res ← VAL[%s.GetInt32[h]];\n", SunRPC);
}
static
emit←enum←put(def)
definition *def;
{
f←print(fout, " %s.PutInt32[h, ORD[in]];\n", SunRPC);
}
static emit←union←get←default(def, dflt, objPrefix)
definition *def;
declaration *dflt;
char *objPrefix;
{
char *defaultEnumElement;
char *namesArray[128];
int i;
defaultEnumElement = DefaultEnumTypes(def, namesArray);
for (i = 0; namesArray[i] != NULL; i++) {
f←print(fout, " %s => {\n", namesArray[i]);
f←print(fout,
" v: REF %s %sObject ← NEW[%s %sObject];\n",
namesArray[i], objPrefix,
namesArray[i], objPrefix);
if (!streq(dflt->type, "void"))
emit←get←stat(dflt, " ", "v", TRUE, "h", def->def←name);
f←print(fout, " res ← v;\n");
f←print(fout, " };\n");
}
f←print(fout, " ENDCASE => NULL;\n");
}
static
emit←union←get(def)
definition *def;
{
case←list *cl;
declaration *cs, *dflt;
char *srcMethod;
char *defaultPrefix = "";
char objPrefix[128];
int numericFlag;
char *mName;
if (NumericEnumType(def->def.un.enum←decl.type))
numericFlag = TRUE;
else
numericFlag = FALSE;
f←print(fout, " tag: %s;\n",
MapToCedarType(def->def.un.enum←decl.type, FALSE));
srcMethod = rpcgenBaseType(def->def.un.enum←decl.type);
if (srcMethod != NULL) {
if (streq(srcMethod, "Int32"))
f←print(fout, " tag ← VAL[%s.Get%s[h]];\n", SunRPC, srcMethod);
else
f←print(fout, " tag ← %s.Get%s[h];\n", SunRPC, srcMethod);
}
else {
mName = ModuleName(def->def.un.enum←decl.type);
f←print(fout, " tag ← %sGet%s[h];\n",
GetPutModuleName(def->def.un.enum←decl.type, TRUE),
StripPrefix(mName, def->def.un.enum←decl.type));
}
sprintf(objPrefix, "%s.%s", svcName, def->def←name);
f←print(fout, " SELECT tag FROM\n");
for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
cs = &cl->case←decl;
if (streq(cl->case←name, "default")) defaultPrefix = "0";
if ((srcMethod != NULL) && streq(srcMethod, "Integer"))
f←print(fout, " %s => {\n", cl->case←name);
else
f←print(fout, " %s => {\n", cl->case←name);
if (PFlag) {
if (numericFlag)
f←print(fout,
" v: REF v%s %sObject ← NEW[v%s %sObject];\n",
cl->case←name, objPrefix,
cl->case←name, objPrefix);
else
f←print(fout,
" v: REF %s %sObject ← NEW[%s %sObject];\n",
cl->case←name, objPrefix,
cl->case←name, objPrefix);
}
else {
f←print(fout, " v: REF %s%s %sObject ← NEW[%s%s %sObject];\n",
def->def←name, cl->case←name, objPrefix,
def->def←name, cl->case←name, objPrefix);
f←print(fout, " v.%s ← tag;\n", def->def.un.enum←decl.name);
}
if (!streq(cs->type, "void"))
emit←get←stat(cs, " ", "v", TRUE, "h", def->def←name);
f←print(fout, " res ← v;\n");
f←print(fout, " };\n");
}
dflt = def->def.un.default←decl;
if (dflt != NULL) {
if (PFlag && !numericFlag) {
emit←union←get←default(def, dflt, objPrefix);
}
else {
f←print(fout, " ENDCASE => {\n");
if (PFlag && numericFlag)
f←print(fout,
" v: REF default %sObject ← NEW[default %sObject];\n",
objPrefix, objPrefix);
else
f←print(fout, " v: REF %s%sDefault %sObject ← NEW[%s%sDefault %sObject];\n",
def->def←name, defaultPrefix, objPrefix,
def->def←name, defaultPrefix, objPrefix);
f←print(fout, " v.%s ← tag;\n", def->def.un.enum←decl.name);
if (!streq(dflt->type, "void"))
emit←get←stat(dflt, " ", "v", TRUE, "h", def->def←name);
f←print(fout, " res ← v;\n");
f←print(fout, " };\n");
}
}
else {
f←print(fout, " ENDCASE => NULL;\n");
}
}
static emit←union←put←default(def, dflt, objPrefix)
definition *def;
declaration *dflt;
char *objPrefix;
{
char *defaultEnumElement;
char *namesArray[128];
int i;
defaultEnumElement = DefaultEnumTypes(def, namesArray);
for (i = 0; namesArray[i] != NULL; i++) {
f←print(fout, " %s => {\n", namesArray[i]);
f←print(fout,
" v: REF %s %sObject ← NARROW[in];\n",
namesArray[i], objPrefix);
if (!streq(dflt->type, "void"))
emit←put←stat(dflt, " ", "v", TRUE, "h");
f←print(fout, " };\n");
}
f←print(fout, " ENDCASE => NULL;\n");
}
static
emit←union←put(def)
definition *def;
{
case←list *cl;
declaration *cs, *dflt;
char *srcMethod;
char *defaultPrefix = "";
char objPrefix[128];
int numericFlag;
char *mName;
srcMethod = rpcgenBaseType(def->def.un.enum←decl.type);
if (srcMethod != NULL) {
if (streq(srcMethod, "Int32"))
f←print(fout, " %s.Put%s[h, ORD[in.%s]];\n",
SunRPC, srcMethod, def->def.un.enum←decl.name);
else
f←print(fout, " %s.Put%s[h, in.%s];\n",
SunRPC, srcMethod, def->def.un.enum←decl.name);
}
else {
mName = ModuleName(def->def.un.enum←decl.type);
f←print(fout, " %sPut%s[h, in.%s];\n",
GetPutModuleName(def->def.un.enum←decl.type, TRUE),
StripPrefix(mName, def->def.un.enum←decl.type),
def->def.un.enum←decl.name);
}
if (NumericEnumType(def->def.un.enum←decl.type))
numericFlag = TRUE;
else
numericFlag = FALSE;
sprintf(objPrefix, "%s.%s", svcName, def->def←name);
f←print(fout, " SELECT in.%s FROM\n", def->def.un.enum←decl.name);
for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
cs = &cl->case←decl;
if (streq(cl->case←name, "default")) defaultPrefix = "0";
if (((srcMethod != NULL) &&
(streq(srcMethod, "Int32") || streq(srcMethod, "Card32"))))
f←print(fout, " %s => {\n", cl->case←name);
else
f←print(fout, " %s => {\n", cl->case←name);
if (PFlag) {
if (numericFlag)
f←print(fout, " v: REF v%s %sObject ← NARROW[in];\n",
cl->case←name, objPrefix);
else
f←print(fout, " v: REF %s %sObject ← NARROW[in];\n",
cl->case←name, objPrefix);
}
else {
f←print(fout, " v: REF %s%s %sObject ← NARROW[in];\n",
def->def←name, cl->case←name, objPrefix);
}
if (!streq(cs->type, "void"))
emit←put←stat(cs, " ", "v", TRUE, "h");
f←print(fout, " };\n");
}
dflt = def->def.un.default←decl;
if (dflt != NULL) {
if (PFlag && !numericFlag) {
emit←union←put←default(def, dflt, objPrefix);
}
else {
f←print(fout, " ENDCASE => {\n");
if (PFlag && numericFlag)
f←print(fout,
" v: REF default %sObject ← NARROW[in];\n",
objPrefix);
else
f←print(fout,
" v: REF %s%sDefault %sObject ← NARROW[in];\n",
def->def←name, defaultPrefix, objPrefix);
if (!streq(dflt->type, "void"))
emit←put←stat(dflt, " ", "v", TRUE, "h");
f←print(fout, " };\n");
}
}
else {
f←print(fout, " ENDCASE => NULL;\n");
}
}
static
emit←struct←get(def)
definition *def;
{
decl←list *dl;
char *srcMethod;
for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
emit←get←stat(&(dl->decl), "", "res", TRUE, "h", def->def←name);
}
}
emit←get←stat(dec, indent, varName, defaultFlag, h, structName)
declaration *dec;
char *indent;
char *varName;
int defaultFlag; /* TRUE => svcName is default in the output
file. */
char *h;
char *structName; /* Contains the name of the struct if dec is
the field of a struct. Not used otherwise. */
{
char decName[128];
char *srcMethod;
char modifier[8];
int endFlag = 0;
relation rel;
StringHashElement elem;
char buf[256];
int inserted;
char *mName;
if (dec->name == NULL || streq(dec->name, ""))
strcpy(decName, "");
else if (streq(varName, ""))
strcpy(decName, dec->name);
else
sprintf(decName, ".%s", dec->name);
if (streq(dec->type, "opaque")) {
if (dec->rel == REL←VECTOR) {
f←print(fout, "%s FOR i: INT IN [0..%s) DO\n",
indent, MapToCedarType(dec->array←max, FALSE));
f←print(fout, "%s %s%s[i] ← %s.GetByte[%s];\n",
indent, varName, decName, SunRPC, h);
f←print(fout, "%s ENDLOOP;\n", indent);
f←print(fout, "%s %s.GetAlign[%s];\n", indent, SunRPC, h);
}
else {
f←print(fout, "%s %s%s ← %s.GetRefText[%s];\n",
indent, varName, decName, SunRPC, h);
}
return;
}
srcMethod = rpcgenBaseType(dec->type);
rel = streq(dec->type, "string") ? REL←ALIAS : dec->rel;
switch (rel) {
case REL←POINTER:
strcpy(modifier, "↑");
f←print(fout, "%s IF %s.GetInt32[%s] # 0 THEN {\n",
indent, SunRPC, h);
f←print(fout, "%s %s%s ← NEW[%s];\n",
indent, varName, decName,
MapToCedarType(dec->type, !defaultFlag));
endFlag = 1;
break;
case REL←VECTOR:
strcpy(modifier, "[i]");
f←print(fout, "%s FOR i: INT IN [0..%s) DO\n",
indent, ArrayMax(dec->array←max, FALSE));
endFlag = 2;
break;
case REL←ARRAY:
strcpy(modifier, "[i]");
f←print(fout, "%s {\n", indent);
f←print(fout, "%s len: INT ← %s.GetInt32[%s];\n", indent, SunRPC, h);
if (dec->name == NULL)
sprintf(buf, "%s", structName);
else
sprintf(buf, "%s.%s", structName, dec->name);
elem = StringHashFind(SeqTypes, buf,
find, &inserted);
if (index(elem->userData, '.') == NULL)
f←print(fout, "%s %s%s ← NEW[%s.%sObject[len]];\n",
indent, varName, decName, svcName,
elem->userData);
else
f←print(fout, "%s %s%s ← NEW[%sObject[len]];\n",
indent, varName, decName, elem->userData);
f←print(fout, "%s FOR i: INT IN [0..len) DO\n", indent);
endFlag = 3;
break;
case REL←ALIAS:
strcpy(modifier, "");
break;
}
if (srcMethod != NULL) {
if (streq(dec->type, "bool"))
f←print(fout, "%s%s %s%s%s ← %s.Get%s[%s] # 0;\n",
indent, endFlag > 0 ? " " : "",
varName, decName, modifier, SunRPC, srcMethod, h);
else if (streq(dec->type, "float") || streq(dec->type, "double")) {
if (PCedarUDP)
f←print(fout, "%s%s %s%s%s ← SunRPCNumbers.Get%s[%s];\n",
indent, endFlag > 0 ? " " : "",
varName, decName, modifier, srcMethod, h);
else /* PCedarTCP or Cedar10 */
f←print(fout, "%s%s %s%s%s ← %s.Get%s[%s];\n",
indent, endFlag > 0 ? " " : "",
varName, decName, modifier, SunRPC, srcMethod, h);
}
else if (streq(srcMethod, "Byte")) {
f←print(fout, "%s%s [] ← %s.GetByte[%s];\n",
indent, endFlag > 0 ? " " : "", SunRPC, h);
f←print(fout, "%s%s [] ← %s.GetByte[%s];\n",
indent, endFlag > 0 ? " " : "", SunRPC, h);
f←print(fout, "%s%s [] ← %s.GetByte[%s];\n",
indent, endFlag > 0 ? " " : "", SunRPC, h);
f←print(fout, "%s%s %s%s%s ← %s.Get%s[%s];\n",
indent, endFlag > 0 ? " " : "",
varName, decName, modifier, SunRPC, srcMethod, h);
}
else
f←print(fout, "%s%s %s%s%s ← %s.Get%s[%s];\n",
indent, endFlag > 0 ? " " : "",
varName, decName, modifier, SunRPC, srcMethod, h);
}
else {
mName = ModuleName(dec->type);
f←print(fout, "%s%s %s%s%s ← %sGet%s[%s];\n",
indent, endFlag > 0 ? " " : "",
varName, decName, modifier,
GetPutModuleName(dec->type, defaultFlag),
StripPrefix(mName, dec->type),
h);
}
if (endFlag == 1) {
f←print(fout, "%s }\n", indent);
f←print(fout, "%s ELSE\n", indent);
f←print(fout, "%s %s%s ← NIL;\n", indent, varName, decName);
}
else if (endFlag == 2) {
f←print(fout, "%s ENDLOOP;\n", indent);
}
else if (endFlag == 3) {
f←print(fout, "%s ENDLOOP;\n", indent);
f←print(fout, "%s };\n", indent);
}
}
static
emit←struct←put(def)
definition *def;
{
decl←list *dl;
char *srcMethod;
for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
emit←put←stat(&(dl->decl), "", "in", TRUE, "h");
}
}
emit←put←stat(dec, indent, varName, defaultFlag, h)
declaration *dec;
char *indent;
char *varName;
int defaultFlag; /* TRUE => svcName is default in the
output file. */
char *h;
{
char decName[128];
char *srcMethod;
char modifier[8];
int endFlag = 0;
relation rel;
char *mName;
if (dec->name == NULL || streq(dec->name, ""))
strcpy(decName, "");
else if (streq(varName, ""))
strcpy(decName, dec->name);
else
sprintf(decName, ".%s", dec->name);
if (streq(dec->type, "opaque")) {
if (dec->rel == REL←VECTOR) {
f←print(fout, "%s FOR i: INT IN [0..%s) DO\n",
indent, MapToCedarType(dec->array←max, FALSE));
f←print(fout, "%s %s.PutByte[%s, %s%s[i]];\n",
indent, SunRPC, h, varName, decName);
f←print(fout, "%s ENDLOOP;\n", indent);
f←print(fout, "%s %s.PutAlign[%s];\n", indent, SunRPC, h);
}
else {
f←print(fout, "%s %s.PutRefText[%s, %s%s];\n",
indent, SunRPC, h, varName, decName);
}
return;
}
srcMethod = rpcgenBaseType(dec->type);
rel = streq(dec->type, "string") ? REL←ALIAS : dec->rel;
switch (rel) {
case REL←POINTER:
strcpy(modifier, "↑");
f←print(fout, "%s IF %s%s = NIL THEN {\n", indent, varName, decName);
f←print(fout, "%s %s.PutInt32[%s, 0];\n", indent, SunRPC, h);
f←print(fout, "%s }\n", indent);
f←print(fout, "%s ELSE {\n", indent);
f←print(fout, "%s %s.PutInt32[%s, 1];\n", indent, SunRPC, h);
endFlag = 1;
break;
case REL←VECTOR:
strcpy(modifier, "[i]");
f←print(fout, "%s FOR i: INT IN [0..%s) DO\n",
indent, ArrayMax(dec->array←max, FALSE));
endFlag = 2;
break;
case REL←ARRAY:
strcpy(modifier, "[i]");
f←print(fout, "%s %s.PutInt32[%s, %s%s.size];\n",
indent, SunRPC, h, varName, decName);
f←print(fout, "%s FOR i: INT IN [0..%s%s.size) DO\n",
indent, varName, decName);
endFlag = 2;
break;
case REL←ALIAS:
strcpy(modifier, "");
break;
}
if (srcMethod != NULL) {
if (streq(dec->type, "bool"))
f←print(fout, "%s%s %s.Put%s[%s, IF %s%s%s THEN 1 ELSE 0];\n",
indent, endFlag > 0 ? " " : "", SunRPC,
srcMethod, h, varName, decName, modifier);
else if (streq(dec->type, "float") || streq(dec->type, "double")) {
if (PCedarUDP)
f←print(fout, "%s%s SunRPCNumbers.Put%s[%s, %s%s%s];\n",
indent, endFlag > 0 ? " " : "",
srcMethod, h, varName, decName, modifier);
else /* PCedarTCP or Cedar10 */
f←print(fout, "%s%s %s.Put%s[%s, %s%s%s];\n",
indent, endFlag > 0 ? " " : "", SunRPC,
srcMethod, h, varName, decName, modifier);
}
else if (streq(srcMethod, "Byte"))
f←print(fout, "%s%s %s.PutInt32[%s, %s%s%s];\n",
indent, endFlag > 0 ? " " : "", SunRPC, h,
varName, decName, modifier);
else
f←print(fout, "%s%s %s.Put%s[%s, %s%s%s];\n",
indent, endFlag > 0 ? " " : "", SunRPC,
srcMethod, h, varName, decName, modifier);
}
else {
mName = ModuleName(dec->type);
f←print(fout, "%s%s %sPut%s[%s, %s%s%s];\n",
indent, endFlag > 0 ? " " : "",
GetPutModuleName(dec->type, defaultFlag),
StripPrefix(mName, dec->type), h,
varName, decName, modifier);
}
if (endFlag == 1) f←print(fout, "%s };\n", indent);
else if (endFlag == 2) f←print(fout, "%s ENDLOOP;\n", indent);
}
static
emit←typedef←get(def)
definition *def;
{
declaration decRec;
decRec.prefix = def->def.ty.old←prefix;
decRec.type = def->def.ty.old←type;
decRec.name = NULL;
decRec.rel = def->def.ty.rel;
decRec.array←max = def->def.ty.array←max;
emit←get←stat(&decRec, "", "res", TRUE, "h", decRec.type);
}
static
emit←typedef←put(def)
definition *def;
{
declaration decRec;
decRec.prefix = def->def.ty.old←prefix;
decRec.type = def->def.ty.old←type;
decRec.name = NULL;
decRec.rel = def->def.ty.rel;
decRec.array←max = def->def.ty.array←max;
emit←put←stat(&decRec, "", "in", TRUE, "h");
}