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