MakeDoAuxImpl.Mesa
Mike Spreitzer September 4, 1986 10:56:54 pm PDT
Carl Hauser, April 11, 1985 3:43:34 pm PST
DIRECTORY Basics, BasicTime, CedarProcess, Commander, CommandTool, Convert, FS, Icons, IO, List, MakeDo, MakeDoPrivate, MessageWindow, ProcessProps, RedBlackTree, Rope, UserProfile;
MakeDoAuxImpl:
CEDAR
MONITOR
IMPORTS BasicTime, CommandTool, Convert, FS, Icons, IO, List, MakeDo, MakeDoPrivate, MessageWindow, ProcessProps, RedBlackTree, Rope, UserProfile
EXPORTS MakeDo, MakeDoPrivate
=
BEGIN OPEN MakeDo, MakeDoPrivate;
NodeRep: PUBLIC TYPE = MakeDoPrivate.NodeRep;
ActionRep: PUBLIC TYPE = MakeDoPrivate.ActionRep;
NodeClassRep: PUBLIC TYPE = MakeDoPrivate.NodeClassRep;
Warning: PUBLIC SIGNAL [message: ROPE] = CODE;
debugging: PUBLIC BOOL ← FALSE;
leaf: PUBLIC Action ← NEW [ActionRep ← [cmd: "-- leaf", class: leafClass]];
leafClass: ActionClass ← NEW [ActionClassRep ← []];
nodes: RedBlackTree.Table ← RedBlackTree.Create[IdGetKey, CompareNodes];
installationDirectory: ROPE = CommandTool.CurrentWorkingDirectory[];
defaultIconFileShortName: ROPE = "MakeDo.Icons";
defaultIconFileName: ROPE = FS.ExpandName[defaultIconFileShortName, installationDirectory].fullFName;
iconsFileName: ROPE;
icons: PUBLIC IconSeq;
LoadIcons:
PROC [fileName:
ROPE]
RETURNS [icons: IconSeq] = {
nIcons: NAT ← 0;
flavors: LIST OF Icons.IconFlavor ← NIL;
FOR nIcons ← 0, nIcons+1
DO
flavor: Icons.IconFlavor = Icons.NewIconFromFile[fileName, nIcons];
IF flavor = unInit THEN EXIT;
flavors ← CONS[flavor, flavors];
ENDLOOP;
icons ← NEW [IconSeqPrivate[nIcons]];
FOR i:
NAT
DECREASING
IN [0 .. icons.length)
DO
icons[i] ← flavors.first;
flavors ← flavors.rest;
ENDLOOP;
IF flavors # NIL THEN ERROR;
};
Fullize:
PROC [short:
ROPE]
RETURNS [full:
ROPE] = {
full ← NIL;
full ← FS.FileInfo[name: short, wDir: installationDirectory !FS.Error => CONTINUE].fullFName;
full ← full};
NoteProfile:
PROC [reason: UserProfile.ProfileChangeReason]
--UserProfile.ProfileChangedProc-- = {
proFileName: ROPE = UserProfile.Token["MakeDo.IconFile", defaultIconFileShortName];
fullFileName: ROPE ← NIL;
fullFileName ← Fullize[proFileName];
IF fullFileName =
NIL
THEN {
MessageWindow.Append[Rope.Cat["MakeDo icons file ", proFileName, " not found (relative to ", installationDirectory, ")"], TRUE];
MessageWindow.Blink[];
fullFileName ← Fullize[defaultIconFileShortName];
};
IF fullFileName #
NIL
AND
NOT fullFileName.Equal[iconsFileName,
FALSE]
THEN {
ok: BOOL ← TRUE;
icons ← LoadIcons[fullFileName !
FS.Error => {
ok ← FALSE;
MessageWindow.Append[Rope.Cat["Problem loading MakeDo icons from ", fullFileName], TRUE];
MessageWindow.Blink[];
CONTINUE}];
IF ok THEN iconsFileName ← fullFileName;
};
IF icons =
NIL
THEN {
icons ← NEW [IconSeqPrivate[1]];
icons[0] ← tool;
iconsFileName ← NIL;
};
};
CompareNodes:
PUBLIC
PROC [k, data:
REF
ANY]
RETURNS [Basics.Comparison]
--RedBlackTree.Compare-- =
BEGIN
GetKey:
PROC [ra:
REF]
RETURNS[r:
ROPE] = {
r ←
WITH ra
SELECT
FROM
n: Node => n.name,
x: ROPE => x,
ENDCASE => ERROR};
k1: ROPE ← GetKey[k];
k2: ROPE ← GetKey[data];
RETURN [k1.Compare[s2: k2, case: FALSE]];
END;
GetNode:
PUBLIC
ENTRY
PROC [someName:
ROPE, class: NodeClass, mayAdd:
BOOL ←
TRUE]
RETURNS [node: Node] = {
ENABLE UNWIND => NULL;
canonicalName: ROPE ← IF class # NIL THEN class.CanonizeName[someName] ELSE someName;
IF (node ←
NARROW[nodes.Lookup[canonicalName]]) =
NIL
AND mayAdd
THEN {
node ← NEW [NodeRep ← [name: canonicalName, class: class, memberships: MakeRefTable[]]];
StartTime[node];
nodes.Insert[node, node];
}
ELSE IF node = NIL THEN NULL
ELSE IF class # node.class THEN ERROR;
};
EnumerateNodes:
PUBLIC
ENTRY
PROC [to:
PROC [Node], andDestroy
--table when done--:
BOOL] = {
ENABLE UNWIND => {};
PerNode:
PROC [data:
REF
ANY]
RETURNS [stop:
BOOL ←
FALSE]
--RedBlackTree.EachNode-- = {
n: Node = NARROW[data];
to[n];
};
nodes.EnumerateIncreasing[PerNode];
IF andDestroy THEN nodes.DestroyTable[];
};
IncrementStepCount:
PUBLIC
ENTRY
PROC [job: Job] = {
ENABLE UNWIND => {};
job.nSteps ← job.nSteps + 1;
};
AddFailedCmd:
PUBLIC
ENTRY
PROC [job: Job, a: Action] = {
ENABLE UNWIND => {};
job.failedSteps ← CONS[a, job.failedSteps];
};
MakeRefTable:
PUBLIC
PROC
RETURNS [table: RefTable] =
{table ← RedBlackTree.Create[IdGetKey, CompareRefs]};
AddToRefTable:
PUBLIC
PROC [ra:
REF
ANY, t: RefTable] =
{t.Insert[ra, ra]};
EnsureRefInTable:
PUBLIC
PROC [ra:
REF
ANY, t: RefTable] = {
IF t.Lookup[ra] = ra THEN RETURN;
t.Insert[ra, ra];
};
DeleteFromRefTable:
PUBLIC
PROC [ra:
REF
ANY, t: RefTable]
RETURNS [found:
REF
ANY] = {
n: RedBlackTree.Node = t.Delete[ra];
RETURN [IF n # NIL THEN n.data ELSE NIL];
};
IdGetKey:
PROC [data:
REF
ANY]
RETURNS [
REF
ANY]
--RedBlackTree.GetKey-- =
{RETURN[data]};
CompareRefs:
PROC [k, data:
REF
ANY]
RETURNS [Basics.Comparison]
--RedBlackTree.Compare-- =
TRUSTED
BEGIN
k1: INT ← LOOPHOLE[k];
k2: INT ← LOOPHOLE[data];
RETURN [
SELECT k1
FROM
< k2 => less,
= k2 => equal,
> k2 => greater,
ENDCASE => ERROR];
END;
chKey: ATOM ← $CommanderHandle;
GetCommanderHandle:
PUBLIC
PROC
RETURNS [ch: Commander.Handle] = {
ch ← NARROW[List.Assoc[chKey, ProcessProps.GetPropList[]]];
IF ch = NIL THEN ERROR;
};
fineTime: BOOL ← FALSE;
Log:
PUBLIC
PROC [fmt:
ROPE, v1, v2, v3, v4, v5:
IO.Value ← [null[]]] =
BEGIN
out: IO.STREAM ← GetCommanderHandle[].out;
IF fineTime THEN out.PutF["%g:", IO.card[BasicTime.GetClockPulses[]]];
out.PutF[fmt, v1, v2, v3, v4, v5];
out.PutChar['\n];
END;
Confirm:
PUBLIC
PROC [action:
ROPE] =
BEGIN
ch: Commander.Handle = GetCommanderHandle[];
in: IO.STREAM = ch.in;
out: IO.STREAM = ch.out;
out.PutF["Ready to %g ? ", IO.rope[action]];
WHILE in.GetChar[] # '\n DO NULL ENDLOOP;
END;
Exists:
PUBLIC
PROC [n: Node]
RETURNS [exists:
BOOL] =
{exists ← GetCreated[n] # notExistTime};
InnerExists:
PUBLIC
PROC [n: Node]
RETURNS [exists:
BOOL] =
{exists ← InnerGetCreated[n] # notExistTime};
FmtTime:
PUBLIC
PROC [t: Time]
RETURNS [asRope:
ROPE] = {
asRope ←
SELECT t
FROM
notExistTime => "never",
unknownTime => "unknown",
ENDCASE => Convert.RopeFromTime[from: t, end: seconds, useAMPM: FALSE, includeZone: FALSE];
};
PublicPartsOfNode:
PUBLIC
PROC [n: Node]
RETURNS [name:
ROPE, class: NodeClass] = {
RETURN [
name: n.name,
class: n.class];
};
DescribeNode:
PUBLIC
PROC [n: Node]
RETURNS [r:
ROPE] = {
SELECT n.class
FROM
fileClass => {
r ← n.name;
};
ENDCASE => {
r ← IO.PutFR["(%g %g)", [refAny[n.class.name]], [refAny[n.name]]];
};
};
PublicPartsOfAction:
PUBLIC
PROC [a: Action]
RETURNS [cmd:
ROPE, foundData:
REF
ANY] = {
RETURN [
cmd: a.cmd,
foundData: a.foundData];
};
DestructivelyReverseActionList:
PUBLIC
PROC [old: ActionList]
RETURNS [new: ActionList] = {
prev: ActionList ← NIL;
cur: ActionList ← old;
WHILE cur #
NIL
DO
next: ActionList ← cur.rest;
cur.rest ← prev;
prev ← cur;
cur ← next;
ENDLOOP;
new ← prev;
};
EnglishList:
PUBLIC
PROC [nl: NodeList]
RETURNS [el:
ROPE, ec:
CARDINAL] =
BEGIN
twoOfMany: ROPE;
ec ← 0;
FOR nl ← nl, nl.rest
WHILE nl #
NIL
DO
SELECT ec
FROM
=0 => el ← nl.first.name;
=1 => {
twoOfMany ← nl.first.name.Cat[", and ", el];
el ← nl.first.name.Cat[" and ", el];
};
=2 => el ← nl.first.name.Cat[", ", twoOfMany];
>2 => el ← nl.first.name.Cat[", ", el];
ENDCASE => ERROR;
ec ← ec + 1;
ENDLOOP;
END;
IsNode:
PUBLIC
PROC [ra:
REF
ANY]
RETURNS [
BOOL] =
{RETURN [ISTYPE[ra, Node]]};
NarrowToNode:
PUBLIC
PROC [ra:
REF
ANY]
RETURNS [Node] =
{RETURN[NARROW[ra]]};
IsAction:
PUBLIC
PROC [ra:
REF
ANY]
RETURNS [
BOOL] =
{RETURN [ISTYPE[ra, Action]]};
NarrowToAction:
PUBLIC
PROC [ra:
REF
ANY]
RETURNS [Action] =
{RETURN[NARROW[ra]]};
IsNodeClass:
PUBLIC
PROC [ra:
REF
ANY]
RETURNS [
BOOL] =
{RETURN [ISTYPE[ra, NodeClass]]};
NarrowToNodeClass:
PUBLIC
PROC [ra:
REF
ANY]
RETURNS [NodeClass] =
{RETURN[NARROW[ra]]};
UserProfile.CallWhenProfileChanges[NoteProfile];
END.