MakeDo.Mesa
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 5, 1992 11:54 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: BOOLFALSE]];
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 ANYNIL];
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 ANYNIL];
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: BOOLTRUE] 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: BOOLTRUE] 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: BOOLTRUE] 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.