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