MakeDoIt:
PROC [cmd: Commander.Handle]
RETURNS [result:
REF
ANY ←
NIL, msg:
ROPE ←
NIL]
--Commander.CommandProc-- =
BEGIN
AddDF:
PROC [goalPlus, goalOther, mod:
BOOL] =
BEGIN
Consume:
PROC [item:
REF
ANY]
RETURNS [stop:
BOOL ←
FALSE] =
BEGIN
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 goals ← CONS[verless, goals]
ELSE IF mod THEN otherModifiable ← CONS[verless, otherModifiable];
};
ii: REF DFUtilities.ImportsItem => NULL;
ii:
REF DFUtilities.IncludeItem => {
dfIn: IO.STREAM ← FS.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: ROPE ← NIL;
dfIn: IO.STREAM ← NIL;
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;
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;
IF goal THEN goals ← CONS[name, goals] ELSE IF mod THEN otherModifiable ← CONS[name, otherModifiable];
};
AddMsg: PROC [more: ROPE] = {msgout.PutRope[more]; msgout.PutRope["\n"]};
goals, otherModifiable: MakeDo.RopeList ← NIL;
guessBoundary: BOOL ← TRUE;
in: IO.STREAM ← IO.RIS[cmd.commandLine];
nFailed, nSucceeded, nSteps, nFailedSteps: NAT;
failedSteps: MakeDo.CommandList;
ok: BOOL ← TRUE;
dontDo:
BOOL ←
SELECT cmd.procData.clientData
FROM
$MakeDo => FALSE,
$MakeCommandList => TRUE,
ENDCASE => ERROR;
assumeAllInconsistent: BOOL ← FALSE;
cmds: ROPE;
msgout, logfile: IO.STREAM ← NIL;
logfile ← FS.StreamOpen["MakeDo.log", create];
msgout ← IOClasses.CreateDribbleOutputStream[logfile, cmd.err];
[] ← in.SkipWhitespace[];
WHILE
NOT in.EndOf[]
DO
arg: ROPE ← in.GetTokenRope[IO.IDProc].token;
IF arg.Length[] = 0 OR arg.Fetch[0] # '- THEN goals ← CONS[arg, goals]
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 AddMsg[IO.PutFR["Bad switch [%g]", IO.rope[arg]]];
[] ← in.SkipWhitespace[];
ENDLOOP;
[nFailed:nFailed, nSucceeded:nSucceeded, nSteps:nSteps, failedSteps:failedSteps, cmds:cmds] ← MakeDo.Ensure[cmd, goals, otherModifiable, guessBoundary, dontDo, assumeAllInconsistent !
MakeDo.Warning => {AddMsg[message]; result ← $Failure; RESUME};
MakeDo.Error => {AddMsg[message]; result ← $Failure; ok ← FALSE; CONTINUE}];
IF ok
THEN {
IF dontDo
THEN {
msg ← Rope.Cat["ToDo:\n", cmds];
}
ELSE {
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]];
msg ← IO.PutFR["%g failed; %g ok.\n", IO.rope[Quantify[nFailed, "goal"]], IO.int[nSucceeded]];
};
};
msgout.Flush[];
logfile.Close[];
END;
ExplainIt:
PROC [cmd: Commander.Handle]
RETURNS [result:
REF
ANY ←
NIL, msg:
ROPE ←
NIL]
--Commander.CommandProc-- =
BEGIN
args: MakeDo.RopeList ← NIL;
in: IO.STREAM ← IO.RIS[cmd.commandLine];
[] ← in.SkipWhitespace[];
WHILE
NOT in.EndOf[]
DO
arg: ROPE ← in.GetTokenRope[IO.IDProc].token;
args ← CONS[arg, args];
[] ← in.SkipWhitespace[];
ENDLOOP;
MakeDo.Explain[cmd, args];
END;
Commander.Register[key: "MakeDo", proc: MakeDoIt, doc: "Ensure that derived files are up to date", clientData: $MakeDo];
Commander.Register[key: "MakeCommandList", proc: MakeDoIt, doc: "List commands that would bring derived files are up to date", clientData: $MakeCommandList];
Commander.Register[key: "Explain", proc: ExplainIt, doc: "Explain MakeDo's last action on given files"];