MakeDo.Mesa
Copyright Ó 1991 by Xerox Corporation. All rights reserved.
Last Edited by: Spreitzer, May 9, 1986 8:37:53 pm PDT
Eduardo Pelegri-Llopart November 18, 1988 8:49:52 am PST
Last tweaked by Mike Spreitzer on October 6, 1992 11:03 am PDT
Carl Hauser, April 11, 1985 3:34:27 pm PST
DIRECTORY
BasicTime USING [GMT, nullGMT],
Commander USING [Handle],
IO USING [STREAM],
List USING [AList],
RefTab USING [Ref],
Rope USING [ROPE];
MakeDo: CEDAR DEFINITIONS =
BEGIN
ROPE: TYPE = Rope.ROPE;
RopeList: TYPE = LIST OF ROPE;
RefTable: TYPE = RefTab.Ref;
PropList: TYPE = List.AList;
Time: TYPE = BasicTime.GMT;
notExistTime: Time = BasicTime.nullGMT;
unknownTime: Time = LOOPHOLE[FIRST[LONG CARDINAL]];
New Types & Stuff:
NodeList: TYPE = LIST OF Node;
Node: TYPE = REF NodeRep; NodeRep: TYPE;
ActionList: TYPE = LIST OF Action;
Action: TYPE = REF ActionRep; ActionRep: TYPE;
Warning: SIGNAL [message: ROPE];
IsNode: PROC [REF ANY] RETURNS [BOOL];
NarrowToNode: PROC [REF ANY] RETURNS [Node];
IsAction: PROC [REF ANY] RETURNS [BOOL];
NarrowToAction: PROC [REF ANY] RETURNS [Action];
existsFSWatch: READONLY BOOL;
For deriving dependecies and ensuring consistency:
Ensure:
PROC [goals: RefTable, modifiabilitySpec: ModifiabilitySpec, supportFiles: RefTable,
PerMissedSupportFile:
PROC [Node], parent: Commander.Handle]
RETURNS [okGoalCount, nonOKGoalCount, nSteps:
NAT, failedSteps: ActionList, nonOKGoalList: NodeList];
Ensure that given goal nodes are current.
If supportFiles is non-nil, every leaf file node that the goals recursively depend on and that wasn't already in supportFiles is added and passed to PerMissedSupportFile (if given).
ModifiabilitySpec:
TYPE = RefTable;
NIL means guess, #NIL means modifiable iff in Table.
Modifiability: TYPE = {yes, guess, no, uninitialized};
Explain:
PROC [ch: Commander.Handle, nodes: RefTable];
List edges of the nodes, and give status of their producers.
GetActions:
PROC [goals: RefTable, modifiabilitySpec: ModifiabilitySpec, report: ReportSpec, neededLeaves, optionalLeaves, determiningLeaves, brokenGoals: RefTable ¬
NIL]
RETURNS [actions: ActionList];
Recursively explores graph to leaves.
Returns some actions, according to report.
The order of those actions is: actions to do later appear earlier.
ReportSpec: TYPE = {none, toBeDone, all};
DestructivelyReverseActionList: PROC [ActionList] RETURNS [ActionList];
Verify: PROC [pkgList: LIST OF ROPE];
It is recommended that you not try to interrupt the following:
SuspectNodeChange: PROC [n: Node];
SuspectNodesChange: PROC [RefTable];
UncurrentNode: PROC [n: Node];
UncurrentNodes: PROC [RefTable];
UncurrentProducer: PROC [n: Node];
UncurrentProducers: PROC [RefTable];
ForAll: PROC [suspectChange, uncurrent: BOOL];
DestroyGraph: PROC;
RetryToProduce:
PROC [Node];
If it has no producer (other than leaf), try (again) to get one.
MakeRefTable: PROC RETURNS [table: RefTable];
AddToRefTable: PROC [ra: REF ANY, t: RefTable];
EnsureRefInTable: PROC [ra: REF ANY, t: RefTable];
DeleteFromRefTable: PROC [ra: REF ANY, t: RefTable] RETURNS [found: BOOL];
RefInTable: PROC [ra: REF ANY, t: RefTable] RETURNS [BOOL];
ScanRefTable: PROC [table: RefTable, EachNode: PROC [REF ANY] RETURNS [stop: BOOL ¬ FALSE]];
EnumerateNodes: PROC[table: RefTable, EachNode: PROC [Node]];
AnalyzeDFFile:
PROC [dfName:
ROPE, goals, supportFiles: RefTable, modifiable: ModifiabilitySpec, doToVerifyGoals, doToOtherOwns, doToImports: DoToFile];
DoToFile: TYPE = {ignore, makeGoal, makeModifiable, makeSupport};
FindNode:
PROC [someName:
ROPE, class: NodeClass]
RETURNS [node: Node];
class may not be NIL.
LookupNodeClass: PROC [className: ROPE] RETURNS [class: NodeClass];
For controlling concurrency:
ForkParms: TYPE ~ REF ForkParmsRep; ForkParmsRep: TYPE;
ForkParmsFromStream: PROC [in: IO.STREAM] RETURNS [ForkParms];
GetForkParms: PROC RETURNS [ForkParms];
SetForkParms: PROC [ForkParms];
ForkParmsFromProfile:
PROC
RETURNS [ForkParms];
ForkParms is dependent on the target system
For Stating dependency rules:
AddFinder: PROC [finder: Finder, end: End];
End: TYPE = {front, back};
Finder: TYPE = RECORD [name: ROPE, finderProc: FinderProc, finderData: REF ANY ¬ NIL];
FinderProc: TYPE = PROC [resultName: ROPE, finderData: REF ANY] RETURNS [found: BOOLEAN, sought: Node, makes, cmdFrom: NodeList, from: From, cmd: ROPE, class: ActionClass, foundData: REF ANY];
From: TYPE = RECORD [mustHave, optional: NodeList];
ActionClass: TYPE = REF ActionClassRep;
ActionClassRep:
TYPE =
RECORD [
CheckConsistency: ConsistencyChecker,
Rederive: RederiveProc,
EnumHiddenDeps: HiddenDependencyEnumerator ¬ NIL,
ClearCaches: ClearCachesProc ¬ NIL,
classData: REF ANY ¬ NIL];
ConsistencyChecker:
TYPE =
PROC [a: Action, result: Node]
RETURNS [consistent:
BOOL, reason:
ROPE];
Missing inputs necessitate any result being consistent; but then, this won't be called if there are missing inputs.
RederiveProc:
TYPE =
PROC [a: Action]
RETURNS [from: From, cmd:
ROPE];
Called when one of the action's determiners changes.
HiddenDependencyEnumerator: TYPE ~ PROC [a: Action, Consume: PROC [Node]];
ClearCachesProc:
TYPE ~
PROC [ac: ActionClass];
When destroying the entire dependency graph, this PROC is also called to clear any caches the ActionClass may be keeping.
GetNode:
PROC [someName:
ROPE, class: NodeClass, mayAdd:
BOOL ¬
TRUE]
RETURNS [node: Node];
class may not be NIL.
name will first be canonized.
NodeClass: TYPE = REF NodeClassRep;
NodeClassRep: TYPE;
IsNodeClass: PROC [REF ANY] RETURNS [BOOL];
NarrowToNodeClass: PROC [REF ANY] RETURNS [NodeClass];
DeclareNodeClass:
PROC [
name: ROPE,
CanonizeName: PROC [ROPE] RETURNS [ROPE],
GetInfo: GetInfoProc
]
RETURNS [nodeClass: NodeClass];
GetInfoProc: TYPE = PROC [n: Node] RETURNS [created: Time, length: INT];
fileClass: NodeClass;
PublicPartsOfNode: PROC [n: Node] RETURNS [name: ROPE, class: NodeClass];
PublicPartsOfNodeClass: PROC [nc: NodeClass] RETURNS [name: ROPE, CanonizeName: PROC [ROPE] RETURNS [ROPE], GetInfo: GetInfoProc];
DescribeNode: PROC [n: Node] RETURNS [ROPE];
GetProp: PROC [n: Node, prop: REF ANY] RETURNS [val: REF ANY];
SetProp: PROC [n: Node, prop, val: REF ANY];
GetProducer: PROC [n: Node] RETURNS [producer: Action];
InnerGetInfo: GetInfoProc;
InnerGetCreated: PROC [n: Node] RETURNS [t: Time];
InnerExists:
PROC [n: Node, zeroLenExists:
BOOL ←
TRUE]
RETURNS [exists:
BOOL];
= {exists ← (created # notExistTime) AND (zeroLenExists OR length#0)}
PublicPartsOfAction: PROC [a: Action] RETURNS [cmd: ROPE, foundData: REF ANY, class: ActionClass];
InnerEnumerateSources:
PROC [a: Action, which: ActionDep, to:
PROC [n: Node, which: ActionDep, optional:
BOOL]];
Should only be used from inside ActionClass procs only when called from MakeDo impl.
ActionDep: TYPE = {cmd, data};
FmtTime: PROC [Time] RETURNS [ROPE];
For Extracting the Dependency Graph:
GetCreated: PROC [n: Node] RETURNS [t: Time];
GetInfo: GetInfoProc;
Exists:
PROC [n: Node, zeroLenExists:
BOOL ←
TRUE]
RETURNS [exists:
BOOL];
= {exists ← (created # notExistTime) AND (zeroLenExists OR length#0)}
EnumerateConsumers: PROC [n: Node, which: ActionDep, to: PROC [Action, ActionDep]];
EnumerateResults: PROC [a: Action, to: PROC [Node]];
EnumerateSources: PROC [a: Action, which: ActionDep, to: PROC [n: Node, which: ActionDep, optional: BOOL]];
END.