MakeDoAuxImpl.Mesa
Last Edited by: Spreitzer, September 4, 1985 10:57:35 pm PDT
DIRECTORY Basics, BasicTime, CedarProcess, Commander, CommandTool, IO, List, MakeDo, MakeDoPrivate, Menus, PrincOpsUtils, Process, ProcessProps, RedBlackTree, Rope, ViewerClasses, ViewerIO;
MakeDoAuxImpl:
CEDAR
MONITOR
IMPORTS BasicTime, IO, List, MakeDo, MakeDoPrivate, ProcessProps, RedBlackTree, Rope
EXPORTS MakeDo, MakeDoPrivate
=
INVARIANT
logs describes allocation of log viewers.
visitCount is unique for each invocation of NewVisit.
c.lastVisit = visit => c.computed says whether to think hard.
dependency graph is reachable from nodes.
Job is consistent.
BEGIN OPEN MakeDo, MakeDoPrivate;
NodeRep: PUBLIC TYPE = MakeDoPrivate.NodeRep;
CommandRep: PUBLIC TYPE = MakeDoPrivate.CommandRep;
visitCount: CARDINAL ← 0;
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 [depth:
INTEGER, 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[]]];
FOR i: INT IN [0 .. depth) DO out.PutChar['\t] ENDLOOP;
out.PutF[fmt, v1, v2, v3, v4, v5];
out.PutChar['\n];
END;
Confirm:
PUBLIC
PROC [depth:
INTEGER, action:
ROPE] =
BEGIN
ch: Commander.Handle = GetCommanderHandle[];
in: IO.STREAM = ch.in;
out: IO.STREAM = ch.out;
FOR i: INT IN [0 .. depth) DO out.PutChar['\t] ENDLOOP;
out.PutF["Ready to %g ? ", IO.rope[action]];
WHILE in.GetChar[] # '\n DO NULL ENDLOOP;
END;
NewVisit:
PUBLIC
ENTRY
PROC
RETURNS [v: Visit] = {
v ← [visitCount ← visitCount+1];
};
IncrementStepCount:
PUBLIC
ENTRY
PROC [job: Job] = {
ENABLE UNWIND => {};
job.nSteps ← job.nSteps + 1;
};
AddFailedCmd:
PUBLIC
ENTRY
PROC [job: Job, c: Command] = {
ENABLE UNWIND => {};
job.failedSteps ← CONS[c, job.failedSteps];
};
AddCommand:
PUBLIC
ENTRY
PROC [job: Job, cmd:
ROPE] = {
ENABLE UNWIND => {};
job.cmds ← job.cmds.Cat[cmd, "\n"];
};
nodes: Table ← MakeNodeTable[];
DestroyGraph:
PUBLIC
ENTRY
PROC = {
ENABLE UNWIND => NULL;
DestroyNode:
INTERNAL
PROC [data:
REF
ANY]
RETURNS [stop:
BOOL ←
FALSE]
--RedBlackTree.EachNode-- = {
n: Node = NARROW[data];
IF n.producer # NIL AND n.producer.c # NIL THEN DestroyCmd[n.producer.c];
IF n.producer # NIL THEN n.producer.c ← NIL;
n.producer ← NIL;
n.class ← NIL;
n.props ← NIL;
n.lockedOuts ← NIL;
};
DestroyCmd:
INTERNAL
PROC [c: Command] = {
RemoveConsumption[c, cmd];
RemoveConsumption[c, data];
WHILE c.makes.first #
NIL
DO
UnlinkMake[c.makes.first];
ENDLOOP;
c.class ← NIL;
c.foundData ← NIL;
c.missedSources ← NIL;
c.lockedOuts ← NIL;
};
DestroyQueues[];
nodes.EnumerateIncreasing[DestroyNode];
nodes.DestroyTable[];
};
UnlinkMake:
INTERNAL
PROC [e: Edge] = {
n: Node = e.n;
c: Command = e.c;
IF e.nNext # NIL OR e.nPrev # NIL THEN ERROR;
n.producer ← NIL;
IF e.cNext # NIL THEN e.cNext.cPrev ← e.cPrev ELSE c.makes.last ← e.cPrev;
IF e.cPrev # NIL THEN e.cPrev.cNext ← e.cNext ELSE c.makes.first ← e.cNext;
e.cNext ← e.cPrev ← NIL;
};
SuspectAll:
PUBLIC
ENTRY
PROC [change, remake:
BOOL] = {
ENABLE UNWIND => NULL;
stack: Table = NewRefTable[];
PerNode:
PROC [data:
REF
ANY]
RETURNS [stop:
BOOL ←
FALSE]
--RedBlackTree.EachNode-- = {
n: Node = NARROW[data];
IF change THEN SuspectNodeChange[n, stack];
IF remake THEN SuspectProducer[n, stack];
};
nodes.EnumerateIncreasing[PerNode];
};
NewRefTable:
PUBLIC
PROC
RETURNS [table: Table] =
{table ← RedBlackTree.Create[IdGetKey, CompareRefs]};
MakeNodeTable:
PUBLIC
PROC
RETURNS [table: Table] =
{table ← RedBlackTree.Create[IdGetKey, CompareNodes]};
AddNodeToTable:
PUBLIC
PROC [n: Node, t: Table] =
{t.Insert[n, n]};
NodeInTable:
PUBLIC
PROC [n: Node, t: Table]
RETURNS [
BOOL] = {
in: BOOL ← t.Lookup[n] # NIL;
RETURN [in]};
IsRootGoal:
PUBLIC
PROC [job: Job, n: Node]
RETURNS [
BOOL] =
{RETURN [NodeInTable[n, job.goals]]};
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, down: NewMonitorLock[]]];
nodes.Insert[node, node];
}
ELSE IF node = NIL THEN NULL
ELSE IF node.class = NIL THEN node.class ← class
ELSE IF class # NIL AND class # node.class THEN ERROR;
};
Exists:
PUBLIC
PROC [n: Node]
RETURNS [exists:
BOOL] =
{exists ← GetCreated[n] # notExistTime};
IdGetKey:
PUBLIC
PROC [data:
REF
ANY]
RETURNS [
REF
ANY]
--RedBlackTree.GetKey-- =
{RETURN[data]};
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;
CompareRefs:
PUBLIC
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;
END.