#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"); }