DIRECTORY FS, GGBasicTypes, GGError, GGModelTypes, GGUtility, Imager, Interpress, IO, IPMaster, Rope, ViewerClasses; GGUtilityImpl: CEDAR PROGRAM IMPORTS GGError, FS, Imager, Interpress, IO, IPMaster, Rope EXPORTS GGUtility = BEGIN BitVector: TYPE = GGBasicTypes.BitVector; FeatureData: TYPE = GGModelTypes.FeatureData; Outline: TYPE = GGModelTypes.Outline; Sequence: TYPE = GGModelTypes.Sequence; Slice: TYPE = GGModelTypes.Slice; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; Traj: TYPE = GGModelTypes.Traj; Viewer: TYPE = ViewerClasses.Viewer; Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = CODE; EntityNotFound: PUBLIC SIGNAL = CODE; StartFeatureDataList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF FeatureData] = { ptr _ entityList _ NIL; }; AddFeatureData: PUBLIC PROC [entity: FeatureData, entityList, ptr: LIST OF FeatureData] RETURNS [newList, newPtr: LIST OF FeatureData] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; DeleteSequenceFromList: PUBLIC PROC [seq: Sequence, seqList: LIST OF Sequence] RETURNS [smallerList: LIST OF Sequence] = { beforeEnt, ent, afterEnt: LIST OF Sequence; notFound: BOOL _ FALSE; [beforeEnt, ent, afterEnt] _ FindSequenceAndNeighbors[seq, seqList]; IF notFound THEN RETURN[seqList]; IF beforeEnt = NIL THEN smallerList _ afterEnt ELSE { beforeEnt.rest _ afterEnt; smallerList _ seqList; }; }; -- end of DeleteSequenceFromList FindSequenceAndNeighbors: PROC [entity: Sequence, entityList: LIST OF Sequence] RETURNS [beforeEnt, ent, afterEnt: LIST OF Sequence] = { lastE: LIST OF Sequence _ NIL; eList: LIST OF Sequence _ entityList; IF eList = NIL THEN ERROR EntityNotFound; UNTIL eList = NIL DO IF eList.first = entity THEN { beforeEnt _ lastE; ent _ eList; afterEnt _ eList.rest; RETURN}; lastE _ eList; eList _ eList.rest; ENDLOOP; SIGNAL Problem[msg: "sequence not found."]; }; AppendSequenceList: PUBLIC PROC [list1, list2: LIST OF Sequence] RETURNS [result: LIST OF Sequence] = { pos: LIST OF Sequence; newCell: LIST OF Sequence; IF list1 = NIL THEN RETURN[list2]; result _ CONS[list1.first, NIL]; pos _ result; FOR l: LIST OF Sequence _ list1.rest, l.rest UNTIL l = NIL DO newCell _ CONS[l.first, NIL]; pos.rest _ newCell; pos _ newCell; ENDLOOP; pos.rest _ list2; }; -- end of AppendSequenceList StartSequenceList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF Sequence] = { ptr _ entityList _ NIL; }; AddSequence: PUBLIC PROC [entity: Sequence, entityList, ptr: LIST OF Sequence] RETURNS [newList, newPtr: LIST OF Sequence] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; StartList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF REF ANY] = { ptr _ entityList _ NIL; }; AddEntity: PUBLIC PROC [entity: REF ANY, entityList, ptr: LIST OF REF ANY] RETURNS [newList, newPtr: LIST OF REF ANY] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; AppendNATs: PUBLIC PROC [list1, list2: LIST OF NAT] RETURNS [result: LIST OF NAT] = { pos: LIST OF NAT; newCell: LIST OF NAT; IF list1 = NIL THEN RETURN[list2]; result _ CONS[list1.first, NIL]; pos _ result; FOR l: LIST OF NAT _ list1.rest, l.rest UNTIL l = NIL DO newCell _ CONS[l.first, NIL]; pos.rest _ newCell; pos _ newCell; ENDLOOP; pos.rest _ list2; }; StartNATList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF NAT] = { ptr _ entityList _ NIL; }; StartTrajList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF Traj] = { ptr _ entityList _ NIL; }; StartSDList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF SliceDescriptor] = { ptr _ entityList _ NIL; }; StartOutlineList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF Outline] = { ptr _ entityList _ NIL; }; StartSliceList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF Slice] = { ptr _ entityList _ NIL; }; AddOutline: PUBLIC PROC [entity: Outline, entityList, ptr: LIST OF Outline] RETURNS [newList, newPtr: LIST OF Outline] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; AddSlice: PUBLIC PROC [entity: Slice, entityList, ptr: LIST OF Slice] RETURNS [newList, newPtr: LIST OF Slice] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; AddNAT: PUBLIC PROC [entity: NAT, entityList, ptr: LIST OF NAT] RETURNS [newList, newPtr: LIST OF NAT] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; AddTraj: PUBLIC PROC [entity: Traj, entityList, ptr: LIST OF Traj] RETURNS [newList, newPtr: LIST OF Traj] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; AddSD: PUBLIC PROC [entity: SliceDescriptor, entityList, ptr: LIST OF SliceDescriptor] RETURNS [newList, newPtr: LIST OF SliceDescriptor] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; BreakIntervalMOD: PUBLIC PROC [start, end, mod: NAT] RETURNS [s1, e1, s2, e2: INT] = { IF start >= mod OR end >= mod THEN ERROR; IF start <= end THEN RETURN[start, end, -1, -1]; RETURN[0, end, start, mod-1]; }; BreakIntervalMODLen: PUBLIC PROC [start, len, mod: NAT] RETURNS [s1, len1, s2, len2: INT] = { IF start >= mod OR len > mod + 1 THEN ERROR; IF start + len -1 < mod THEN RETURN[start, len, -1, -1]; RETURN[0, start+len-mod, start, mod-start]; }; InMODRegion: PUBLIC PROC [test: NAT, start, end, mod: NAT] RETURNS [BOOL] = { IF start = end THEN RETURN [test = start]; IF start < end THEN RETURN [test IN [start..end]]; RETURN [test IN [start..mod) OR test IN [0..end]]; }; AllFalse: PUBLIC PROC [bitvec: BitVector] RETURNS [BOOL] = { FOR i: NAT IN [0..bitvec.len) DO IF bitvec[i] = TRUE THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE]; }; AllTrue: PUBLIC PROC [bitvec: BitVector] RETURNS [BOOL] = { FOR i: NAT IN [0..bitvec.len) DO IF bitvec[i] = FALSE THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE]; }; GetInterpressFileName: PUBLIC PROC [ipName: Rope.ROPE, currentWDir: Rope.ROPE, feedback: Viewer] RETURNS [fullName: Rope.ROPE _ NIL, success: BOOL _ TRUE] = { cp: FS.ComponentPositions; IF Rope.Length[ipName]=0 OR Rope.Equal[ipName, ""] THEN { GGError.AppendHerald[feedback, "Select an Interpress file name", oneLiner]; GGError.Blink[feedback]; RETURN[NIL, FALSE]; }; [fullName, cp, ] _ FS.ExpandName[ipName, currentWDir ! FS.Error => { GGError.Append[feedback, "... FS Error during name expansion", oneLiner]; GGError.Blink[feedback]; success _ FALSE; CONTINUE; } ]; IF success AND Rope.Equal[s1: Rope.Substr[base: fullName, start: cp.ext.start, len: cp.ext.length], s2: "gargoyle", case: FALSE] THEN { GGError.Append[feedback, " .gargoyle extension for IP files not allowed", oneLiner]; GGError.Blink[feedback]; success _ FALSE; }; IF success AND cp.ext.length=0 THEN fullName _ Rope.Concat[fullName, ".IP"]; -- add IP extension }; OpenInterpressOrComplain: PUBLIC PROC [feedback: Viewer, fullName: Rope.ROPE] RETURNS [ipMaster: Interpress.Master, success: BOOL] = { success _ TRUE; ipMaster _ Interpress.Open[fileName: fullName, log: NIL ! FS.Error => { GGError.Append[feedback, error.explanation, oneLiner]; GOTO Quit; }; IPMaster.Error => { --ErrorDesc: TYPE = RECORD[code: ATOM, explanation: ROPE] GGError.Append[feedback, Rope.Cat[error.explanation, " for ", fullName], oneLiner]; GOTO Quit; }; Imager.Error => { --ErrorDesc: TYPE = RECORD [code: ATOM, explanation: ROPE] GGError.Append[feedback, Rope.Cat[error.explanation, " for ", fullName], oneLiner]; GOTO Quit; }; IO.Error, IO.EndOfStream => { GGError.Append[feedback, Rope.Cat["IO Stream Error for ", fullName], oneLiner]; GOTO Quit; }; ]; IF ipMaster.pages=0 THEN { GGError.Append[feedback, Rope.Concat["Zero pages in ", fullName], oneLiner]; GOTO Quit; }; EXITS Quit => { GGError.Blink[feedback]; success _ FALSE; }; }; GetGargoyleFileName: PUBLIC PROC [ggName: Rope.ROPE, currentWDir: Rope.ROPE, feedback: Viewer, emergency: BOOL _ FALSE] RETURNS [fullName: Rope.ROPE _ NIL, success: BOOL _ TRUE, versionSpecified: BOOL _ FALSE] = { cp: FS.ComponentPositions; versionSpecified _ Rope.SkipTo[s: ggName, skip: "!"]#Rope.Length[ggName]; IF Rope.Length[ggName]=0 OR Rope.Equal[ggName, ""] THEN { IF NOT emergency THEN { GGError.PutF[feedback, oneLiner, "No filename specified"]; GGError.Blink[feedback]; }; RETURN[NIL, FALSE]; }; [fullName, cp, ] _ FS.ExpandName[ggName, currentWDir ! FS.Error => { success _ FALSE; IF NOT emergency THEN { GGError.PutF[feedback, oneLiner, "FS Error during name expansion of %g", [rope[ggName]]]; GGError.Blink[feedback]; }; CONTINUE; } ]; IF success AND (Rope.Equal[s1: Rope.Substr[base: fullName, start: cp.ext.start, len: cp.ext.length], s2: "IP", case: FALSE] OR Rope.Equal[s1: Rope.Substr[base: fullName, start: cp.ext.start, len: cp.ext.length], s2: "interpress", case: FALSE]) THEN { IF NOT emergency THEN { GGError.Append[feedback, " Interpress extension for Gargoyle files not allowed", oneLiner]; GGError.Blink[feedback]; }; success _ FALSE; }; IF success AND cp.ext.length=0 THEN fullName _ Rope.Concat[fullName, ".gargoyle"]; }; END. æGGUtilityImpl.mesa Last edited by Bier on December 28, 1986 10:17:12 pm PST. Contents: General Purpose routines for use by Gargoyle. Pier, August 20, 1986 11:27:10 am PDT Templates for List Operations Destructive Delete DeleteTypeFromList: PUBLIC PROC [entity: Type, entityList: LIST OF Type] RETURNS [smallerList: LIST OF Type] = { beforeEnt, ent, afterEnt: LIST OF Type; notFound: BOOL _ FALSE; [beforeEnt, ent, afterEnt] _ FindTypeAndNeighbors[entity, entityList]; IF notFound THEN RETURN[entityList]; IF beforeEnt = NIL THEN smallerList _ afterEnt ELSE { beforeEnt.rest _ afterEnt; smallerList _ entityList; }; }; -- end of DeleteTypeFromList FindTypeAndNeighbors: PROC [entity: Type, entityList: LIST OF Type] RETURNS [beforeEnt, ent, afterEnt: LIST OF Type] = { lastE: LIST OF Type _ NIL; eList: LIST OF Type _ entityList; IF eList = NIL THEN SIGNAL Problem[msg: "msg"]; UNTIL eList = NIL DO IF eList.first = entity THEN { beforeEnt _ lastE; ent _ eList; afterEnt _ eList.rest; RETURN}; lastE _ eList; eList _ eList.rest; ENDLOOP; SIGNAL Problem[msg: "msg"]; }; Operations on LIST OF FeatureData Operations on LIST OF Sequence Non-destructive (copies the first list). Operations on LIST OF REF ANY Two Finger List Constructor Operations on Assorted LIST Types Non-destructive (copies the first list). Two Finger List Construction StartTypeList: PUBLIC PROC [] RETURNS [entityList, ptr: LIST OF Type] = { ptr _ entityList _ NIL; }; AddType: PUBLIC PROC [entity: Type, entityList, ptr: LIST OF Type] RETURNS [newList, newPtr: LIST OF Type] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; Modular Arithmetic Example: BreakIntervalMODLen[6, 4, 7] => [0, 3, 6, 1]. BreakIntervalMODLen[2, 5, 7] => [2, 5, -1, -1]. BreakIntervalMODLen[6, 8, 7] => [0, 7, 6, 1]. -- repeats 6 twice Operations on Bit Vectors File Names Êl˜Icode™K™9™8K™%—šÏk ˜ KšœFœ ˜j—K˜šÏn œœ˜Kšœœœ˜;Kšœ ˜—˜Kšœ œ˜)Kšœ œ˜-Kšœ œ˜%Kšœ œ˜'Kšœœ˜!Kšœœ ˜5Kšœœ˜Kšœœ˜$—K˜Kš žœœœ œœ˜/Kšžœœœœ˜%K˜Kšœ™™K™—KšÏb™šŸœžœœœœœ œœœ ™xKšœœœ™)Kšœ œœ™KšœH™HKšœ œœ ™$Kšœ œœ™.šœ™Kšœ™Kšœ™K™—KšœÏc™!—šžœž œœœœ œœœ ™€Kšœœœ œ™Kšœœœ™$Kšœ œœœ™1šœ œ™Kšœœ™Kšœ7œ™?Kšœ™Kšœ™—Kšœ™Kšœ™Kšœ™—K™K˜Kšœ!™!K™šžœœœœœœž œ˜WKšœœ˜K˜K˜—šžœœœ(œœœœœ˜Ššœœœ˜Kš œœœœœ˜#Kšœœ œ˜%Kšœ˜K˜—šœ˜Kšœ˜Kšœ œ œ˜Kšœ˜K˜—K˜K˜—Kšœ™K˜šžœœœœœ œœœ˜zKšœœœ ˜+Kšœ œœ˜KšœD˜DKšœ œœ ˜!Kšœ œœ˜.šœ˜Kšœ˜Kšœ˜K˜—Kšœ  ˜#K˜—šžœœ œœ œœœ˜ˆKšœœœ œ˜Kšœœœ˜%Kšœ œœœ˜)šœ œ˜Kšœœ˜Kšœ7œ˜?Kšœ˜Kšœ˜—Kšœ˜Kšœ%˜+Kšœ˜—šžœœœœœ œ œœ˜gKšœœœ ˜Kšœ œœ ˜K™(Kšœ œœœ˜"Kšœ œœ˜ Kšœ ˜ š œœœœœ˜=Kšœ œ œ˜Kšœ˜Kšœ˜—Kšœ˜Kšœ˜Kšœ ˜K˜—š žœœœœœœ˜QKšœœ˜K˜K˜—šž œœœ%œœ œœœ˜~šœœœ˜Kš œœœœœ˜#Kšœœ œ˜%Kšœ˜K˜—šœ˜Kšœ˜Kšœ œ œ˜Kšœ˜K˜—K˜—K˜Kšœ™K™KšŸ™šž œœœœœœœœ˜HKšœœ˜K˜K˜—šž œœœ œœœœœœœœœœœ˜yšœœœ˜Kš œœœœœ˜#Kšœœ œ˜%Kšœ˜K˜—šœ˜Kšœ˜Kšœ œ œ˜Kšœ˜K˜—K˜K˜—K™Kšœ!™!K™šž œœœœœœœ œœœ˜UKšœœœœ˜Kšœ œœœ˜K™(Kšœ œœœ˜"Kšœ œœ˜ Kšœ ˜ š œœœœœœ˜8Kšœ œ œ˜Kšœ˜Kšœ˜—Kšœ˜Kšœ˜Kšœ˜K˜—K˜šž œœœœœœœ˜GKšœœ˜K˜K˜—š ž œœœœœœ ˜IKšœœ˜K˜—š ž œœœœœœ˜RKšœœ˜K˜—š žœœœœœœ ˜OKšœœ˜K˜K˜—š žœœœœœœ ˜KKšœœ˜K˜—K™KšŸ™šžœœœœœœžœ™MKšœœ™K™—šž œœœ žœœœžœœœœžœ™všœœœ™Kš œœœœœ™#Kšœœ œ™%Kšœ™K™—šœ™Kšœ™Kšœ œ œ™Kšœ™K™—K™—K˜šž œœœ$œœ œœœ ˜zšœœœ˜Kš œœœœœ˜#Kšœœ œ˜%Kšœ˜K˜—šœ˜Kšœ˜Kšœ œ œ˜Kšœ˜K˜—K˜K˜—šžœœœ"œœœœœ ˜ršœœœ˜Kš œœœœœ˜#Kšœœ œ˜%Kšœ˜K˜—šœ˜Kšœ˜Kšœ œ œ˜Kšœ˜K˜—K˜—šžœœœ œœœœœœœœ˜jšœœœ˜Kš œœœœœ˜#Kšœœ œ˜%Kšœ˜K˜—šœ˜Kšœ˜Kšœ œ œ˜Kšœ˜K˜—K˜K˜—šžœœœ!œœœœœ ˜nšœœœ˜Kš œœœœœ˜#Kšœœ œ˜%Kšœ˜K˜—šœ˜Kšœ˜Kšœ œ œ˜Kšœ˜K˜—K˜—šžœœœ,œœœœœ˜šœœœ˜Kš œœœœœ˜#Kšœœ œ˜%Kšœ˜K˜—šœ˜Kšœ˜Kšœ œ œ˜Kšœ˜K˜—K˜—K˜Kšœ™K™š žœ œœœœ˜VKšœœ œœ˜)Kšœœœ˜0Kšœ˜K˜K˜—š žœœœœœœ˜]Kšœ6™6Kšœ/™/Kšœ@™@Kšœœœœ˜,Kšœœœ ˜8Kšœ%˜+K˜K˜—šž œœœœœœœ˜NKšœ œœ˜*Kšœ œœœ˜2Kšœœœœ ˜2Kšœ˜—K˜Kšœ™K™š žœœœœœ˜<šœœœ˜ Jš œ œœœœ˜'—Jšœ˜Jšœœ˜ K˜K˜—š žœœœœœ˜;šœœœ˜ Jš œ œœœœ˜(—Jšœ˜Jšœœ˜ K˜K˜—K˜K™ K™šžœ œœœœœœ œœ˜žKšœœ˜šœœœ˜9KšœK˜KKšœ˜Kšœœœ˜K˜—šœœ"œ ˜DKšœI˜IKšœ˜Kšœ œ˜Kšœ˜ K˜Kšœ˜—•StartOfExpansion9[base: ROPE, start: INT _ 0, len: INT _ 2147483647]šœ œlœœ˜‡KšœU˜UKšœ˜Kšœ œ˜K˜—Kšœ œœ* ˜`K˜K˜—š žœ œ#œœ(œ˜†Kšœ œ˜šœ4œ˜9šœ ˜ Kšœ6˜6Kšœ˜ Kšœ˜—šœ 9˜MKšœS˜SKšœ˜ Kšœ˜—šœ :˜LKšœS˜SKšœ˜ Kšœ˜—šœœ˜KšœO˜OKšœ˜ Kšœ˜—Kšœ˜—šœœ˜KšœL˜LKšœ˜ Kšœ˜—š˜šœ ˜ Kšœ˜Kšœ œ˜K˜——K˜K˜K˜—šžœ œœœœœœœœ œœœœ˜ÕKšœœ˜KšœI˜Išœœœ˜9–Ò[gargoyleData: REF ANY, msgType: GGError.MsgType, format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]šœœ œ˜Kšœ:˜:Kšœ˜K˜—Kšœœœ˜Kšœ˜—šœœ"œ ˜DKšœ œ˜–Ò[gargoyleData: REF ANY, msgType: GGError.MsgType, format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]šœœ œ˜KšœY˜YKšœ˜K˜—Kšœ˜ K˜Kšœ˜—–9[base: ROPE, start: INT _ 0, len: INT _ 2147483647]š œ œgœœnœœ˜úšœœ œ˜Kšœ\˜\Kšœ˜K˜—Kšœ œ˜K˜—Kšœ œœ/˜RK˜K˜—K™Kšœ˜—…—&fB¸