MakeDoCmds.Mesa
Last Edited by: Spreitzer, September 4, 1985 11:08:12 pm PDT
DIRECTORY BasicTime, Commander, DFUtilities, FS, IO, IOClasses, MakeDo, Process, Rope;
MakeDoCmds: CEDAR PROGRAM
IMPORTS Commander, DFUtilities, FS, IO, IOClasses, MakeDo, Process, Rope =
BEGIN
ROPE: TYPE = Rope.ROPE;
CmdMakeDo: PROC [cmd: Commander.Handle] RETURNS [result: REF ANYNIL, msg: ROPENIL] --Commander.CommandProc-- =
BEGIN
AddDF: PROC [goalPlus, goalOther, mod: BOOL] =
BEGIN
Consume: PROC [item: REF ANY] RETURNS [stop: BOOLFALSE] =
BEGIN
Process.CheckForAbort[];
WITH item SELECT FROM
di: REF DFUtilities.DirectoryItem => NULL;
fi: REF DFUtilities.FileItem => {
cp: FS.ComponentPositions;
full, verless: ROPE;
[full, cp, ] ← FS.ExpandName[fi.name];
verless ← full.Substr[start: 0, len: cp.ext.start + cp.ext.length];
IF (IF fi.verifyRoot THEN goalPlus ELSE goalOther)
THEN NameAdd[verless, TRUE, TRUE]
ELSE IF mod THEN NameAdd[verless, FALSE, TRUE];
};
ii: REF DFUtilities.ImportsItem => NULL;
ii: REF DFUtilities.IncludeItem => {
dfIn: IO.STREAMFS.StreamOpen[ii.path1];
DFUtilities.ParseFromStream[in: dfIn, proc: Consume];
dfIn.Close[]};
ci: REF DFUtilities.CommentItem => NULL;
wi: REF DFUtilities.WhiteSpaceItem => NULL;
ENDCASE => ERROR;
END;
dfName: ROPENIL;
dfIn: IO.STREAMNIL;
IF mod THEN guessBoundary ← FALSE;
[] ← in.SkipWhitespace[];
IF in.EndOf[] THEN {AddMsg["No DF-file name after -whatever"]; RETURN};
dfName ← in.GetTokenRope[IO.IDProc].token;
IF dfName.Find["."] < 0 THEN dfName ← dfName.Cat[".DF"];
dfIn ← FS.StreamOpen[dfName];
DFUtilities.ParseFromStream[in: dfIn, proc: Consume];
dfIn.Close[];
END;
NameAdd: PROC [name: ROPE, goal, mod: BOOL] = {
n: MakeDo.Node ← MakeDo.FindNode[name, MakeDo.fileClass];
IF mod THEN MakeDo.AddNodeToTable[n, modifiable];
IF goal THEN MakeDo.AddNodeToTable[n, goals];
};
AddName: PROC [goal, mod: BOOL] = {
name: ROPE;
IF mod THEN guessBoundary ← FALSE;
[] ← in.SkipWhitespace[];
IF in.EndOf[] THEN {AddMsg["No name after -mn"]; RETURN};
name ← in.GetTokenRope[IO.IDProc].token;
NameAdd[name, goal, mod];
};
AddMsg: PROC [more: ROPE] = {msgout.PutRope[more]; msgout.PutRope["\n"]};
goals: MakeDo.Table ← MakeDo.MakeNodeTable[];
modifiable: MakeDo.Table ← MakeDo.MakeNodeTable[];
guessBoundary: BOOLTRUE;
in: IO.STREAMIO.RIS[cmd.commandLine];
nFailed, nSucceeded, nSteps, nFailedSteps: NAT;
failedSteps: MakeDo.CommandList;
ok: BOOLTRUE;
do: BOOLTRUE;
record: BOOLFALSE;
assumeAllInconsistent, suspectAll: BOOLFALSE;
cmds: ROPE;
msgout, logfile: IO.STREAMNIL;
SELECT cmd.procData.clientData FROM
$MakeDo => NULL;
$MakeCommandList => {do ← FALSE; record ← TRUE};
ENDCASE => ERROR;
logfile ← FS.StreamOpen["MakeDo.log", create];
msgout ← IOClasses.CreateDribbleOutputStream[logfile, cmd.err];
[] ← in.SkipWhitespace[];
{ENABLE MakeDo.Warning => {AddMsg[message]; result ← $Failure; RESUME};
WHILE NOT in.EndOf[] DO
arg: ROPE ← in.GetTokenRope[IO.IDProc].token;
IF arg.Length[] = 0 OR arg.Fetch[0] # '- THEN NameAdd[arg, TRUE, TRUE]
ELSE IF arg.Equal["-gr"] THEN AddDF[TRUE, FALSE, FALSE]
ELSE IF arg.Equal["-gm"] THEN AddDF[TRUE, TRUE, FALSE]
ELSE IF arg.Equal["-dr"] THEN AddDF[TRUE, FALSE, TRUE]
ELSE IF arg.Equal["-dm"] THEN AddDF[TRUE, TRUE, TRUE]
ELSE IF arg.Equal["-md"] THEN AddDF[FALSE, FALSE, TRUE]
ELSE IF arg.Equal["-mn"] THEN AddName[FALSE, TRUE]
ELSE IF arg.Equal["-assumeAllInconsistent"] THEN assumeAllInconsistent ← TRUE
ELSE IF arg.Equal["-dontAssumeAllInconsistent"] THEN assumeAllInconsistent ← FALSE
ELSE IF arg.Equal["-suspectAll"] THEN suspectAll ← TRUE
ELSE IF arg.Equal["-dontSuspectAll"] THEN suspectAll ← FALSE
ELSE IF arg.Equal["-do"] THEN do ← TRUE
ELSE IF arg.Equal["-dontDo"] THEN do ← FALSE
ELSE IF arg.Equal["-record"] THEN record ← TRUE
ELSE IF arg.Equal["-dontRecord"] THEN record ← FALSE
ELSE IF arg.Equal["-p"] THEN MakeDo.SetProcessAllocation[in.GetInt[]]
ELSE AddMsg[IO.PutFR["Bad switch [%g]", IO.rope[arg]]];
[] ← in.SkipWhitespace[];
Process.CheckForAbort[];
ENDLOOP;
[nFailed:nFailed, nSucceeded:nSucceeded, nSteps:nSteps, failedSteps:failedSteps, cmds:cmds] ← MakeDo.Ensure[cmd, goals, modifiable, guessBoundary, assumeAllInconsistent, suspectAll, do, record];
};
IF ok THEN {
IF record THEN {
msgout.PutRope["Steps:\n"];
msgout.PutRope[cmds];
};
IF do THEN {
nFailedSteps ← 0;
FOR failedSteps ← failedSteps, failedSteps.rest WHILE failedSteps # NIL DO
msgout.PutF["%lFailed: %g%l\n", IO.rope["b"], IO.rope[failedSteps.first.PublicPartsOfCommand[].cmd], IO.rope["B"]];
nFailedSteps ← nFailedSteps + 1;
ENDLOOP;
IF nFailedSteps > 0 THEN msgout.PutF["%g failed; %g ok.\n", IO.rope[Quantify[nFailedSteps, "step"]], IO.int[nSteps - nFailedSteps]];
msgout.PutF["%g failed; %g ok.\n", IO.rope[Quantify[nFailed, "goal"]], IO.int[nSucceeded]];
};
};
msgout.Flush[];
logfile.Close[];
END;
CmdExplain: PROC [cmd: Commander.Handle] RETURNS [result: REF ANYNIL, msg: ROPENIL] --Commander.CommandProc-- =
BEGIN
args: MakeDo.Table ← MakeDo.MakeNodeTable[];
in: IO.STREAMIO.RIS[cmd.commandLine];
verbosely: BOOLFALSE;
[] ← in.SkipWhitespace[];
WHILE NOT in.EndOf[] DO
argName: ROPE ← in.GetTokenRope[IO.IDProc].token;
IF argName.Equal["-verbose"]
THEN verbosely ← TRUE
ELSE {
argNode: MakeDo.Node ← MakeDo.FindNode[argName, MakeDo.fileClass];
MakeDo.AddNodeToTable[argNode, args];
};
[] ← in.SkipWhitespace[];
ENDLOOP;
MakeDo.Explain[cmd, args, verbosely];
END;
CmdProduce: PROC [cmd: Commander.Handle] RETURNS [result: REF ANYNIL, msg: ROPENIL] --Commander.CommandProc-- =
BEGIN
in: IO.STREAMIO.RIS[cmd.commandLine];
[] ← in.SkipWhitespace[];
WHILE NOT in.EndOf[] DO
argName: ROPE ← in.GetTokenRope[IO.IDProc].token;
argNode: MakeDo.Node ← MakeDo.FindNode[argName, MakeDo.fileClass];
MakeDo.RetryToProduce[argNode];
[] ← in.SkipWhitespace[];
ENDLOOP;
in.Close[];
END;
CmdSuspect: PROC [cmd: Commander.Handle] RETURNS [result: REF ANYNIL, msg: ROPENIL] --Commander.CommandProc-- =
BEGIN
in: IO.STREAMIO.RIS[cmd.commandLine];
[] ← in.SkipWhitespace[];
WHILE NOT in.EndOf[] DO
argName: ROPE ← in.GetTokenRope[IO.IDProc].token;
IF argName.Equal["-all", FALSE]
THEN {
MakeDo.SuspectAll[TRUE, TRUE];
}
ELSE {
stack: MakeDo.Table = MakeDo.NewRefTable[];
argNode: MakeDo.Node;
suspectProducer: BOOL = argName.Equal["-p", FALSE];
IF suspectProducer THEN argName ← in.GetTokenRope[IO.IDProc].token;
argNode ← MakeDo.FindNode[argName, MakeDo.fileClass];
IF suspectProducer
THEN MakeDo.SuspectProducer[argNode, stack]
ELSE {
MakeDo.NodeMayNeedRemaking[argNode, stack];
MakeDo.SuspectNodeChange[argNode, stack];
};
};
[] ← in.SkipWhitespace[];
ENDLOOP;
in.Close[];
END;
CmdDestroy: PROC [cmd: Commander.Handle] RETURNS [result: REF ANYNIL, msg: ROPENIL] --Commander.CommandProc-- =
BEGIN
MakeDo.DestroyGraph[];
END;
Quantify: PROC [n: NAT, stuff: ROPE] RETURNS [quantity: ROPE] =
{quantity ← IO.PutFR["%g %g%g", IO.int[n], IO.rope[stuff], IO.rope[IF n = 1 THEN "" ELSE "s"]]};
Commander.Register[key: "MakeDo", proc: CmdMakeDo, doc: "Ensure that derived files are up to date", clientData: $MakeDo];
Commander.Register[key: "MakeCommandList", proc: CmdMakeDo, doc: "List commands that would bring derived files are up to date", clientData: $MakeCommandList];
Commander.Register[key: "MakeExcuses", proc: CmdExplain, doc: "Explain what MakeDo would do"];
Commander.Register[key: "MakeSuspicion", proc: CmdSuspect, doc: "Suspect everything"];
Commander.Register[key: "MakeEmpty", proc: CmdDestroy, doc: "Delete the entire dependency graph"];
Commander.Register[key: "MakeProducer", proc: CmdProduce, doc: "For leaves, try again to find a producer"];
END.