#ifndef lint
static char sccsid[] = "@(#)rpc←hout.c 1.1 90/10/29 (C) 1987 SMI";
#endif
/*
* rpc←hout.c, Header file outputter for the RPC protocol compiler
* Copyright (C) 1987, Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include "rpc←util.h"
#include "rpc←parse.h"
list *pstructdef();
list *puniondef();
list *ptypedef();
list *pdeclaration();
char *CreateSeqType();
void
print←datadef(def)
definition *def;
{
list *sequenceDefns = NULL;
list *seqDefn;
switch (def->def←kind) {
case DEF←STRUCT:
sequenceDefns = pstructdef(def);
break;
case DEF←UNION:
sequenceDefns = puniondef(def);
break;
case DEF←ENUM:
penumdef(def);
break;
case DEF←TYPEDEF:
sequenceDefns = ptypedef(def);
break;
case DEF←PROGRAM:
pprogramdef(def);
break;
case DEF←CONST:
pconstdef(def);
break;
}
for (seqDefn = sequenceDefns; seqDefn != NULL; seqDefn = seqDefn->next)
f←print(fout, "\n%s", seqDefn->val);
}
static
pconstdef(def)
definition *def;
{
if (def->def.co[0] == '"')
f←print(fout, "%s: ROPE = %s;\n", def->def←name, def->def.co);
else
f←print(fout, "%s: INT32 = %s;\n", def->def←name, def->def.co);
}
static
list *pstructdef(def)
definition *def;
{
decl←list *l;
char *name = def->def←name;
list *sequenceDefns = NULL;
list *seqDefn;
f←print(fout, "\n%s: TYPE = RECORD [\n", name);
for (l = def->def.st.decls; l != NULL; l = l->next) {
seqDefn = pdeclaration(name, &l->decl, 1, TRUE);
if (seqDefn != NULL) {
seqDefn->next = sequenceDefns;
sequenceDefns = seqDefn;
}
if (l->next != NULL) f←print(fout, ",\n");
else f←print(fout, "\n");
}
f←print(fout, "\t];\n");
return (sequenceDefns);
}
static
list *puniondef(def)
definition *def;
{
case←list *l;
char *name = def->def←name;
declaration *decl;
char *defaultPrefix = "";
list *sequenceDefns = NULL;
list *seqDefn;
int numericFlag;
char *defaultEnumElements;
int endFlag = TRUE;
char *namesArray[128];
f←print(fout, "\n%s: TYPE = REF %sObject;\n", name, name);
f←print(fout, "%sObject: TYPE = RECORD [\n", name);
decl = &def->def.un.enum←decl;
if (NumericEnumType(decl->type))
numericFlag = TRUE;
else
numericFlag = FALSE;
if (PFlag && !numericFlag) {
f←print(fout, "\tunion: SELECT %s: %s FROM\n",
decl->name, MapToCedarType(decl->type, TRUE));
}
else {
if (streq(decl->type, "bool")) {
f←print(fout, "\t%s: BOOLEAN,\n", decl->name);
} else {
f←print(fout, "\t%s: %s,\n",
decl->name, MapToCedarType(decl->type, TRUE));
}
f←print(fout, "\tunion: SELECT uTag: * FROM\n");
}
for (l = def->def.un.cases; l != NULL; l = l->next) {
if (PFlag) {
if (numericFlag)
f←print(fout, "\t v%s => [", l->case←name);
else
f←print(fout, "\t %s => [", l->case←name);
}
else {
f←print(fout, "\t %s%s => [", name, l->case←name);
}
if (!streq(l->case←decl.type, "void")) {
seqDefn = pdeclaration(name, &l->case←decl, 0, TRUE);
if (seqDefn != NULL) {
seqDefn->next = sequenceDefns;
sequenceDefns = seqDefn;
}
}
f←print(fout, "],\n");
if (streq(l->case←name, "default")) {
defaultPrefix = "0";
}
}
decl = def->def.un.default←decl;
if (PFlag) {
if (numericFlag)
f←print(fout, "\t default => [");
else {
defaultEnumElements = DefaultEnumTypes(def, namesArray);
if (streq(defaultEnumElements, ""))
endFlag = FALSE;
else
f←print(fout, "\t %s => [", defaultEnumElements);
}
}
else {
f←print(fout, "\t %s%sDefault => [", name, defaultPrefix);
}
if (decl && !streq(decl->type, "void")) {
seqDefn = pdeclaration(name, decl, 0, TRUE);
if (seqDefn != NULL) {
seqDefn->next = sequenceDefns;
sequenceDefns = seqDefn;
}
}
if (endFlag) f←print(fout, "],\n");
f←print(fout, "\t ENDCASE];\n");
return (sequenceDefns);
}
static
pprogramdef(def)
definition *def;
{
char progName[256];
char progNum[64];
char progNumName[256];
version←list *vers;
proc←list *proc;
definition *defStruct;
decl←list *dl;
int expandFlag;
char *o = "o";
extern definition *FindStructDefn();
BadProgNameFlag[++CurrentProgNameFlag] = FALSE;
strcpy(progNum, def->def.pr.prog←num);
strcpy(progNumName, def->def←name);
if (PFlag && ((progNumName[0] == '\0') || isdigit(progNumName[0]))) {
BadProgNameFlag[CurrentProgNameFlag] = TRUE;
sprintf(progNumName, "%sPrognum", svcName);
}
if ((progNum[0] == '0') && (progNum[1] == 'x'))
f←print(fout, "\n%s: CARDINAL = %sH;\n", progNumName, &(progNum[2]));
else
f←print(fout, "\n%s: CARDINAL = %s;\n", progNumName, progNum);
for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
f←print(fout, "\n%s: CARDINAL = %s;\n\n", vers->vers←name, vers->vers←num);
if (BadProgNameFlag[CurrentProgNameFlag])
sprintf(progName, "%s%s", svcName, vers->vers←num);
else
sprintf(progName, "%s%s", def->def←name, vers->vers←num);
for (proc = vers->procs; proc != NULL; proc = proc->next) {
if (ExpandProcArgs) {
defStruct = FindStructDefn(proc->arg←type);
}
if (ExpandProcArgs && defStruct != NULL &&
defStruct->def←kind == DEF←STRUCT) {
o = FindUniqueName("o", defStruct->def.st.decls);
f←print(fout, "%sProc: TYPE = PROC[%s: %s,\n",
locase(proc->proc←name), o, progName);
for (dl = defStruct->def.st.decls;
dl != NULL;
dl = dl->next) {
pdeclaration(defStruct->def←name, &(dl->decl), 16, TRUE);
if (dl->next == NULL)
f←print(fout, "]");
else
f←print(fout, ",\n");
}
}
else {
f←print(fout, "%sProc: TYPE = PROC[o: %s",
locase(proc->proc←name), progName);
if (!streq(proc->arg←type, "void"))
f←print(fout, ", in: %s]", MapToCedarType(proc->arg←type,
TRUE));
else
f←print(fout, "]");
}
if (!streq(proc->res←type, "void"))
f←print(fout, "\n\t\tRETURNS [res: %s]",
MapToCedarType(proc->res←type, TRUE));
f←print(fout, ";\n");
}
f←print(fout, "\n");
f←print(fout,
"%s: TYPE = REF %sObject;\n", progName, progName);
f←print(fout, "%sObject: TYPE = RECORD [\n", progName);
for (proc = vers->procs; proc != NULL; proc = proc->next) {
f←print(fout, " %s: %sProc",
locase(proc->proc←name), locase(proc->proc←name));
f←print(fout, ",\n");
}
f←print(fout, " rpcHandle: %s.Handle ← NIL,\n", SunRPC);
f←print(fout, " rpcConversation: SunRPCAuth.Conversation ← NIL,\n");
f←print(fout, " data: REF ANY ← NIL\n");
f←print(fout, " ];\n\n");
if (PCedar) {
f←print(fout,
"ImportByName%s: PROC[name: ROPE]\n\t\tRETURNS [h: %s];\n",
progName, progName);
if (PCedarUDP) {
f←print(fout,
"Import%s: PROC[b: %s.Address ← %s.nullAddress]\n\t\tRETURNS [h: %s];\n\n",
progName, SunRPC, SunRPC, progName);
f←print(fout,
"Export%s: PROC[p: %s];\n\n", progName, progName);
}
else { /* PCedarTCP */
f←print(fout,
"ImportStream%s: PROC[b: %s.Address ← %s.nullAddress]\n\t\tRETURNS [h: %s];\n\n",
progName, SunRPC, SunRPC, progName);
f←print(fout,
"ExportStream%s: PROC[p: %s];\n\n", progName, progName);
}
}
else {
f←print(fout, "Make%sClient: PROC[h: %s.Handle,\n",
progName, SunRPC);
f←print(fout, "\tc: SunRPCAuth.Conversation] RETURNS [%s];\n",
progName);
f←print(fout, "Make%sServer: PROC[\n", progName);
f←print(fout, " data: REF,\n");
for (proc = vers->procs; proc != NULL; proc = proc->next) {
f←print(fout, " %s: %sProc",
locase(proc->proc←name), locase(proc->proc←name));
if (proc->next != NULL) f←print(fout, ",\n");
else f←print(fout, "\n");
}
f←print(fout, " ] RETURNS [%s.Server];\n\n", SunRPC);
}
}
}
static
penumdef(def)
definition *def;
{
char *name = def->def←name;
enumval←list *l = def->def.en.vals;
int contigFlag;
StringHashElement elem;
int inserted;
list *enumElementNames = NULL;
list *enumElement;
contigFlag = FillEnumAssignments(def->def.en.vals);
elem = StringHashFind(EnumTypes, name, insert, &inserted);
f←print(fout, "\n%s: TYPE = MACHINE DEPENDENT {\n", name);
for (l = def->def.en.vals; l != NULL; l = l->next) {
f←print(fout, "\t%s(%s)", l->name, l->assignment);
if (l->next != NULL) f←print(fout, ",\n");
else f←print(fout, "\n");
enumElement = (list *) malloc(sizeof(list));
enumElement->val = strdup(l->name);
enumElement->next = enumElementNames;
enumElementNames = enumElement;
elem->userData = (char *) enumElementNames;
}
f←print(fout, "\t};\n");
if (!contigFlag) return;
f←print(fout, "\n%sNames: READONLY ARRAY %s OF ROPE;\n",
name, name);
}
static
list *ptypedef(def)
definition *def;
{
char *name = def->def←name;
char *old = def->def.ty.old←type;
relation rel = def->def.ty.rel;
char buf[256];
list *sequenceDefns = NULL;
list *seqDefn;
int opaqueFlag = FALSE;
StringHashElement elem;
int inserted;
f←print(fout, "\n");
if (!streq(name, old)) {
if (streq(old, "string")) {
old = "ROPE";
rel = REL←ALIAS;
} else if (streq(old, "opaque")) {
old = "BYTE";
opaqueFlag = TRUE;
} else if (streq(old, "bool")) {
old = "BOOLEAN";
}
else {
old = MapToCedarType(old, TRUE);
}
switch (rel) {
case REL←ARRAY:
if (opaqueFlag) {
f←print(fout, "%s: TYPE = REF TEXT;\n", name);
}
else {
elem = StringHashFind(SeqTypes,
def->def.ty.old←type,
insert, &inserted);
if (inserted) {
sprintf(buf, "SeqType%d", SeqTypeId);
SeqTypeId++;
elem->userData = strdup(buf);
}
else {
sprintf(buf, "%s", elem->userData);
}
f←print(fout, "%s: TYPE = %s;\n", name, buf);
seqDefn = (list *) malloc(sizeof(list));
seqDefn->val = CreateSeqType(buf, old);
seqDefn->next = sequenceDefns;
sequenceDefns = seqDefn;
}
break;
case REL←POINTER:
f←print(fout, "%s: TYPE = REF %s;\n", name, old);
break;
case REL←VECTOR:
f←print(fout, "%s: TYPE = PACKED ARRAY [0..%s) OF %s;\n",
name,
ArrayMax(def->def.ty.array←max, FALSE),
old);
break;
case REL←ALIAS:
f←print(fout, "%s: TYPE = %s;\n", name, old);
break;
}
}
return (sequenceDefns);
}
list *pdeclaration(name, dec, blank, defaultFlag)
char *name;
declaration *dec;
int blank;
int defaultFlag;
{
char *type;
int n;
char buf[256];
list *sequenceDefns = NULL;
list *seqDefn;
StringHashElement elem;
int inserted;
char buf1[256];
if (streq(dec->type, "void")) {
return (NULL);
}
while (blank--) {
(void) fputc(' ', fout);
}
if (streq(dec->type, "string")) {
f←print(fout, "%s: ROPE", dec->name);
} else {
if (streq(dec->type, "opaque")) {
type = "char";
} else {
type = dec->type;
}
type = MapToCedarType(type, defaultFlag);
switch (dec->rel) {
case REL←ALIAS:
f←print(fout, "%s: %s",
dec->name, type);
break;
case REL←VECTOR:
f←print(fout, "%s: PACKED ARRAY [0..%s) OF %s",
dec->name, ArrayMax(dec->array←max, FALSE),
type);
break;
case REL←POINTER:
f←print(fout, "%s: REF %s",
dec->name, type);
break;
case REL←ARRAY:
if (streq(dec->type, "opaque")) {
f←print(fout, "%s: REF TEXT", dec->name);
}
else {
sprintf(buf, "%s.%s", name, dec->name);
elem = StringHashFind(SeqTypes, buf,
insert, &inserted);
if (inserted) {
sprintf(buf, "SeqType%d", SeqTypeId);
SeqTypeId++;
elem->userData = strdup(buf);
}
else {
sprintf(buf, "%s", elem->userData);
}
if (defaultFlag || index(buf, '.') != NULL)
strcpy(buf1, buf);
else
sprintf(buf1, "%s.%s", svcName, buf);
f←print(fout, "%s: %s", dec->name, buf1);
seqDefn = (list *) malloc(sizeof(list));
seqDefn->val = CreateSeqType(buf, type);
seqDefn->next = sequenceDefns;
sequenceDefns = seqDefn;
}
break;
}
}
return (sequenceDefns);
}
static
char *CreateSeqType(name, type)
char *name;
char *type;
{
char buf[512], buf1[256];
sprintf(buf, "%s: TYPE = REF %sObject;\n", name, name);
sprintf(buf1,
"%sObject: TYPE = RECORD [SEQUENCE size: [0..LAST[INT32]) OF %s];\n",
name, type);
strcat(buf, buf1);
return (strdup(buf));
}