DIRECTORY BasicTime USING [GMT], Convert USING [RopeFromInt], HashTable USING [Insert, Fetch, Value], Loader USING [BCDBuildTime], IO USING [int, rope, time, PutF, PutFR, STREAM], Rope USING [ROPE, Cat, Concat, Equal, Fetch, Find, Length, Substr], SiroccoPrivate USING [CComponent, CType, Generic, Handle, TABLES], UserCredentials USING [Get]; SiroccoPrivateImpl: CEDAR PROGRAM IMPORTS Convert, HashTable, IO, Loader, Rope, UserCredentials EXPORTS SiroccoPrivate ~ { OPEN SiroccoPrivate; Version: PUBLIC ROPE; ROPE: TYPE ~ Rope.ROPE; Value: TYPE ~ HashTable.Value; AquireState: PUBLIC SIGNAL RETURNS [Handle] ~ CODE; EndItAll: PUBLIC ERROR ~ CODE; MakeUpName: PUBLIC PROC [base: ROPE, postfix: ROPE, tables: TABLES] RETURNS [madeUpName: ROPE] ~ { successful: BOOLEAN; value: Value; [successful, value] _ HashTable.Fetch[tables.madeUpNameTable, base]; IF successful THEN madeUpName _ NARROW[value] ELSE { madeUpName _ Rope.Concat[base, postfix]; [successful, value] _ HashTable.Fetch[tables.localTable, madeUpName]; WHILE successful DO madeUpName _ Rope.Concat[madeUpName, postfix]; [successful, value] _ HashTable.Fetch[tables.localTable, madeUpName]; ENDLOOP; successful _ HashTable.Insert[tables.madeUpNameTable, base, madeUpName]; }; }; Merge: PROC [list1, list2: CComponent] RETURNS [comp: CComponent] ~ { IF (list1 = NIL) THEN { comp _ list2; RETURN }; IF (list2 = NIL) THEN { comp _ list1; RETURN }; IF (list1.val > list2.val) THEN { comp _ Merge[list2, list1]; RETURN }; list2 _ Merge[list1.sibling, list2]; list1.sibling _ list2; comp _ list1; }; Nest: PUBLIC PROC [in: ROPE, level: NAT] RETURNS [out: ROPE] ~ { INDENT: ROPE ~ "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; out _ Rope.Concat[in, Rope.Substr[INDENT, 0, (level+1)]]; }; NewFcn: PUBLIC PROC [name: ROPE, obj: ROPE, size: INT] RETURNS [out: ROPE] ~ { h: Handle _ SIGNAL AquireState; line1: ROPE; line2: ROPE; programKeyWD: ROPE _ IO.PutFR["%gP%gV%g", IO.rope[h.programName], IO.int[h.programNo], IO.int[h.versionNo] ]; obj _ UnDo[obj, programKeyWD]; line1 _ IO.PutFR[Nest["%g: PROC RETURNS [temp: REF %g] ~ {", 2], IO.rope[name], IO.rope[obj] ]; line2 _ IO.PutFR[Nest["temp _ NEW[%g[%g]];", 2], IO.rope[obj], IO.int[size], ]; out _ Rope.Concat[line1, line2] }; Sort: PUBLIC PROC [list: CComponent] RETURNS [comp: CComponent] ~ { longComp: CComponent; shortComp: CComponent; [longComp, shortComp] _ Split[list]; IF (longComp # NIL) AND (longComp.sibling # NIL) THEN longComp _ Sort[longComp]; IF (shortComp # NIL) THEN shortComp _ Sort[shortComp]; comp _ Merge[longComp, shortComp]; }; Split: PROC [list: CComponent] RETURNS [longComp: CComponent _ NIL, shortComp: CComponent _ NIL] ~ { IF (list = NIL) THEN RETURN; [shortComp, longComp] _ Split[list.sibling]; list.sibling _ longComp; longComp _ list; }; UnDo: PUBLIC PROC [in: ROPE, programKey: ROPE] RETURNS [out: ROPE] ~ { len1: INT ~ Rope.Length[in]; len2: INT ~ Rope.Length[programKey]; prefix: ROPE; IF (len1 <= len2) -- can't have "mumble." OR (Rope.Fetch[in, (len2)] # '.) THEN { out _ SELECT TRUE FROM Rope.Equal[in, "LONGCARDINAL"] => "CARD", Rope.Equal[in, "LONGINTEGER"] => "INT", Rope.Equal[in, "SINK"] => "CrRPC.BulkDataSink", Rope.Equal[in, "SOURCE"] => "CrRPC.BulkDataSource", Rope.Equal[in, "STRING"] => "ROPE", Rope.Equal[in, "UNSPECIFIED"] => "CARDINAL", ENDCASE => in; RETURN; }; out _ in; prefix _ Rope.Substr[in, 0, len2]; IF Rope.Equal[prefix, programKey] THEN { out _ Rope.Substr[in, (len2+1), len1]; }; }; UnDoable: PUBLIC PROC [in: ROPE, programKey: ROPE] RETURNS [out: ROPE, yes: BOOLEAN] ~ { len1: INT ~ Rope.Length[in]; len2: INT ~ Rope.Length[programKey]; prefix: ROPE; yes _ FALSE; out _ in; IF (len1 <= len2) THEN RETURN; -- can't have "mumble." IF (Rope.Fetch[in, (len2)] # '.) THEN RETURN; prefix _ Rope.Substr[in, 0, len2]; IF Rope.Equal[prefix, programKey] THEN { yes _ TRUE; out _ Rope.Substr[in, (len2+1), len1]; }; }; Marshal: PUBLIC PROC [h: SiroccoPrivate.Handle, type: CType, typeName: ROPE, name: ROPE, code: ROPE, uniqueNo: NAT, level: NAT _ 2] RETURNS [rc: ROPE, rn: ROPE] ~ { list: CComponent; successful: BOOLEAN; tag: ROPE; tagType: ROPE; uniqueLoopIndex: ROPE; value: Value; programKey: ROPE; allTheTables: TABLES; UniqueID: PROC [prefix: ROPE] RETURNS [unique: ROPE] ~ { unique _ Rope.Concat[prefix, Convert.RopeFromInt[uniqueNo]]; [successful, value] _ HashTable.Fetch[allTheTables.localTable, unique]; IF successful THEN ERROR; -- ERROR IN GENERATING NAME uniqueNo _ uniqueNo + 1; }; allTheTables _ h.allTheTables; programKey _ h.programKey; rc _ code; SELECT type.class FROM array => { subscript: ROPE; uniqueLoopIndex _ UniqueID["i"]; subscript _ IO.PutFR["%g[%g]", IO.rope[name], IO.rope[uniqueLoopIndex] ]; rc _ IO.PutFR[Nest["%gFOR %g: CARDINAL IN [0..%g) DO", (level+1)], IO.rope[rc], IO.rope[uniqueLoopIndex], IO.int[type.bound] ]; [successful, value] _ HashTable.Fetch[allTheTables.condensedTypeTable, type.children.type]; [rc, rn] _ Marshal[h, NARROW [value], type.children.type, subscript, rc, uniqueNo, (level+1)]; rc _ IO.PutFR[Nest["%g", (level+1)], IO.rope[rc] ]; rc _ Rope.Concat[rc, "ENDLOOP;"]; }; boolean => { rc _ IO.PutFR["%gCrRPC.PutBOOL[h, %g];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; bulkDataSink => { rc _ IO.PutFR["%gCrRPC.PutBulkDataSink[h, %g];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; bulkDataSource => { rc _ IO.PutFR["%gCrRPC.PutBulkDataSource[h, %g];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; cardinal => { rc _ IO.PutFR["%gCrRPC.PutCARDINAL[h, %g];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; choice => { tag _ UniqueID["tag"]; tagType _ UnDo[typeName, programKey]; rc _ IO.PutFR[Nest["%gCrRPC.PutCARDINAL[h, ORD[%g.type]];", level], IO.rope[rc], IO.rope[name] ]; rc _ IO.PutFR[Nest["%gWITH %g SELECT FROM", (level+1)], IO.rope[rc], IO.rope[name] ]; list _ type.children.sibling; WHILE (list # NIL) DO variant: ROPE _ Rope.Concat["it.", list.name]; rc _ IO.PutFR[Nest["%git: %g %g => {", (level+2)], IO.rope[rc], IO.rope[list.name], IO.rope[tagType] ]; [successful, value] _ HashTable.Fetch[allTheTables.condensedTypeTable, list.type]; [rc, rn] _ Marshal[h, NARROW [value], list.type, variant, rc, uniqueNo, (level+2)]; rc _ IO.PutFR[Nest["%g", (level+2)], IO.rope[rc], ]; rc _ IO.PutFR[Nest["%g};", (level+1)], IO.rope[rc], ]; list _ list.sibling; ENDLOOP; rc _ Rope.Concat[rc, "ENDCASE;"]; }; enumeration => { rc _ IO.PutFR["%gCrRPC.PutCARDINAL[h, ORD[%g]];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; integer => { rc _ IO.PutFR["%gCrRPC.PutINTEGER[h, %g];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; longCardinal => { rc _ IO.PutFR["%gCrRPC.PutCARD[h, %g];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; longInteger => { rc _ IO.PutFR["%gCrRPC.PutINT[h, %g];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; record => { IF (type.children = NIL) THEN { rc _ IO.PutFR["%gNULL; -- RECORD []", IO.rope[rc], ]; RETURN[rc, name]; }; list _ type.children; WHILE (list # NIL) DO [successful, value] _ HashTable.Fetch[allTheTables.condensedTypeTable, list.type]; [rc, rn] _ Marshal[h, NARROW [value], list.type, Rope.Cat[name, ".", list.name], rc, uniqueNo, (level)]; -- a special case! (bj) IF (list.sibling # NIL) THEN rc _ IO.PutFR[Nest["%g", (level)], IO.rope[rc]]; list _ list.sibling; ENDLOOP; }; sequence => { element: ROPE; uniqueLoopIndex _ UniqueID["i"]; element _ IO.PutFR["%g.body[%g]", IO.rope[name], IO.rope[uniqueLoopIndex] ]; rc _ IO.PutFR[Nest["%gCrRPC.PutCARDINAL[h, %g.length];", level], IO.rope[rc], IO.rope[name] ]; rc _ IO.PutFR[Nest["%gFOR %g: CARDINAL IN [0..%g.length) DO", (level+1)], IO.rope[rc], IO.rope[uniqueLoopIndex], IO.rope[name] ]; [successful, value] _ HashTable.Fetch[allTheTables.condensedTypeTable, type.children.type]; [rc, rn] _ Marshal[h, NARROW [value], type.children.type, element, rc, uniqueNo, (level+1)]; rc _ Nest[rc, (level+1)]; rc _ Rope.Concat[rc, "ENDLOOP;"]; }; string => { rc _ IO.PutFR["%gCrRPC.PutROPE[h, %g];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; unspecified => { rc _ IO.PutFR["%gCrRPC.PutCARDINAL[h, %g];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; ENDCASE => { rc _ Rope.Concat[rc, "--UNKNOWN--"]; rn _ name; ERROR; }; }; UnMarshal: PUBLIC PROC [h: Handle, type: CType, typeName: ROPE, name: ROPE, code: ROPE, uniqueNo: NAT, level: NAT _ 2] RETURNS [rc: ROPE, rn: ROPE] ~ { list: CComponent; successful: BOOLEAN; tag: ROPE; tagType: ROPE; tempRope: ROPE; uniqueLoopIndex: ROPE; value: Value; variantType: CType; programKey: ROPE; allTheTables: TABLES; RemoveAssign: PROC [in: ROPE] RETURNS [out: ROPE] ~ { temp: INT; temp _ Rope.Find[in, "_"] + 1; out _ IF (temp = 0) THEN in ELSE Rope.Substr[in, temp, Rope.Length[in]]; }; SimpleType: PROC [typeClass: Generic] RETURNS [yes: BOOLEAN] ~ { yes _ SELECT typeClass FROM integer, longInteger, cardinal, longCardinal, unspecified, boolean, string, enumeration => TRUE, ENDCASE => FALSE; }; UniqueID: PROC [prefix: ROPE] RETURNS [unique: ROPE] ~ { unique _ Rope.Concat[prefix, Convert.RopeFromInt[uniqueNo]]; [successful, value] _ HashTable.Fetch[allTheTables.localTable, unique]; IF successful THEN ERROR; -- ERROR IN GENERATING NAME uniqueNo _ uniqueNo + 1; }; allTheTables _ h.allTheTables; programKey _ h.programKey; rc _ code; SELECT type.class FROM array => { subscript: ROPE; uniqueLoopIndex _ UniqueID["i"]; subscript _ IO.PutFR["%g[%g]", IO.rope[name], IO.rope[uniqueLoopIndex] ]; rc _ IO.PutFR["%gFOR %g: CARDINAL IN [0..%g) DO", IO.rope[rc], IO.rope[uniqueLoopIndex], IO.int[type.bound] ]; [successful, value] _ HashTable.Fetch[allTheTables.condensedTypeTable, type.children.type]; rc _ Nest[rc, (level+1)]; [rc, rn] _ UnMarshal[h, NARROW [value], type.children.type, subscript, rc, uniqueNo, (level+1)]; rc _ Nest[rc, (level+1)]; rc _ Rope.Concat[rc, "ENDLOOP;"]; }; boolean => { rc _ IO.PutFR["%g%g _ CrRPC.GetBOOL[h];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; bulkDataSink => { rc _ IO.PutFR["%g%g _ CrRPC.GetBulkDataSink[h];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; bulkDataSource => { rc _ IO.PutFR["%g%g _ CrRPC.GetBulkDataSource[h];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; cardinal => { rc _ IO.PutFR["%g%g _ CrRPC.GetCARDINAL[h];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; choice => { tag _ UniqueID["tag"]; tagType _ UnDo[type.children.type, programKey]; rc _ Rope.Concat[rc, Nest[" TRUSTED {", (level+1)]]; rc _ IO.PutFR[Nest["%g%g: %g ~ VAL[CrRPC.GetCARDINAL[h]];", (level+1)], IO.rope[rc], IO.rope[tag], IO.rope[tagType] ]; rc _ IO.PutFR[Nest["%gSELECT %g FROM", (level+2)], IO.rope[rc], IO.rope[tag] ]; list _ type.children.sibling; WHILE (list # NIL) DO [successful, value] _ HashTable.Fetch[allTheTables.condensedTypeTable, list.type]; variantType _ NARROW [value]; IF SimpleType[variantType.class] THEN { rc _ IO.PutFR["%g%g => %g _ ", IO.rope[rc], IO.rope[list.name], IO.rope[name] ]; [tempRope, rn] _ UnMarshal[h, variantType, list.type, name, "", uniqueNo, (level+2)]; tempRope _ RemoveAssign[tempRope]; tempRope _ Rope.Substr[tempRope, 0, (Rope.Length[tempRope]-1)]; rc _ IO.PutFR[Nest["%g[%g[%g]];", (level+2)], IO.rope[rc], IO.rope[list.name], IO.rope[tempRope] ]; } ELSE { IF ((variantType.class = record) AND (variantType.children = NIL)) THEN { rc _ IO.PutFR[Nest["%g%g => %g _ [%g[%g~]]; -- RECORD []", (level+2)], IO.rope[rc], IO.rope[list.name], IO.rope[name], IO.rope[list.name], IO.rope[list.name] ]; } ELSE { uniqueName: ROPE _ UniqueID["x"]; rc _ IO.PutFR[Nest["%g%g => {", (level+3)], IO.rope[rc], IO.rope[list.name], ]; rc _ IO.PutFR[Nest["%g%g: %g;", (level+3)], IO.rope[rc], IO.rope[uniqueName], IO.rope[UnDo[list.type, programKey]] ]; [rc, rn] _ UnMarshal[h, variantType, list.type, uniqueName, rc, uniqueNo, (level+3)]; rc _ IO.PutFR[Nest["%g", (level+3)], IO.rope[rc] ]; rc _ IO.PutFR[Nest["%g%g _ [%g[%g]];", (level+3)], IO.rope[rc], IO.rope[name], IO.rope[list.name], IO.rope[uniqueName] ]; rc _ IO.PutFR[Nest["%g};", (level+2)], IO.rope[rc] ]; }; }; list _ list.sibling; ENDLOOP; rc _ Rope.Concat[rc, Nest["ENDCASE;", (level+1)]]; rc _ Rope.Concat[rc, "};"]; }; enumeration => { rc _ IO.PutFR["%g%g _ VAL[CrRPC.GetCARDINAL[h]];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; integer => { rc _ IO.PutFR["%g%g _ CrRPC.GetINTEGER[h];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; longCardinal => { rc _ IO.PutFR["%g%g _ CrRPC.GetCARD[h];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; longInteger => { rc _ IO.PutFR["%g%g _ CrRPC.GetINT[h];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; record => { IF (type.children = NIL) THEN { rc _ IO.PutFR["%gNULL; -- RECORD []", IO.rope[rc], ]; RETURN[rc, name]; }; list _ type.children; WHILE (list # NIL) DO [successful, value] _ HashTable.Fetch[allTheTables.condensedTypeTable, list.type]; [rc, rn] _ UnMarshal[h, NARROW [value], list.type, Rope.Cat[name, ".", list.name], rc, uniqueNo, (level)]; -- a special case! (bj) IF (list.sibling # NIL) THEN rc _ IO.PutFR[Nest["%g", (level)], IO.rope[rc]]; list _ list.sibling; ENDLOOP; }; sequence => { element: ROPE; uniqueLoopIndex: ROPE _ UniqueID["i"]; uniqueName: ROPE _ UniqueID["length"]; element _ IO.PutFR["%g.body[%g]", IO.rope[name], IO.rope[uniqueLoopIndex] ]; rc _ Rope.Concat[rc, Nest["{", (level+1)]]; rc _ IO.PutFR[Nest["%g%g: CARDINAL ~ CrRPC.GetCARDINAL[h];", (level+1)], IO.rope[rc], IO.rope[uniqueName] ]; rc _ IO.PutFR[Nest["%g%g _ NEW[%gObject[%g]];", (level+1)], IO.rope[rc], IO.rope[name], IO.rope[UnDo[typeName, programKey]], IO.rope[uniqueName] ]; rc _ IO.PutFR[Nest["%gFOR %g: CARDINAL IN [0..%g) DO", (level+2)], IO.rope[rc], IO.rope[uniqueLoopIndex], IO.rope[uniqueName] ]; [successful, value] _ HashTable.Fetch[allTheTables.condensedTypeTable, type.children.type]; [rc, rn] _ UnMarshal[h, NARROW [value], type.children.type, element, rc, uniqueNo, (level+2)]; rc _ Nest[rc, (level+2)]; rc _ Rope.Concat[rc, Nest["ENDLOOP;", (level+1)]]; rc _ Rope.Concat[rc, "};"]; }; string => { rc _ IO.PutFR["%g%g _ CrRPC.GetROPE[h];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; unspecified => { rc _ IO.PutFR["%g%g _ CrRPC.GetCARDINAL[h];", IO.rope[rc], IO.rope[name] ]; rn _ name; }; ENDCASE => { rc _ IO.PutFR["%g -- %g _ CrRPC.GetCARDINAL[h]; (UNKNOWN)--", IO.rope[rc], IO.rope[name] ]; rn _ name; ERROR; }; }; FileHeader: PUBLIC PROC [out: IO.STREAM, filename: ROPE] ~ { IO.PutF[out, Nest["-- %g", 1], IO.rope[filename]]; IO.PutF[out, Nest["-- Copyright (C) 1986 by Xerox Corporation. All rights reserved.", 1]]; IO.PutF[out, Nest["-- Generated by %g at %g", 1], IO.rope[UserCredentials.Get[].name], IO.time[]]; IO.PutF[out, Nest["-- using %g", 1], IO.rope[Version]]; IO.PutF[out, Nest["", 0]]; }; Init: PROC ~ { date: BasicTime.GMT ~ Loader.BCDBuildTime[SiroccoPrivateImpl.Init]; -- incest! Version _ IO.PutFR["Sirocco [1.0] of %g", IO.time[date]]; }; Init[]; }... @SiroccoPrivateImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Bhargava, August 11, 1986 10:48:02 am PDT Bill Jackson (bj) September 25, 1986 3:11:42 am PDT Copied Types Signals Procs Empty Record is a special case ASSUMES nameBody is the associated with name i.e name : REF nameObject ΚΏ˜šœ™Icodešœ Οmœ1™