MakeItDepsImpl.mesa
Copyright Ó 1986, 1991, 1993 by Xerox Corporation. All rights reserved.
Eric Nickell, August 19, 1986 11:37:10 am PDT
Mike Spreitzer June 23, 1986 12:06:51 pm PDT
Last tweaked by Mike Spreitzer on May 18, 1993 4:16 pm PDT
Willie-s, May 18, 1993 2:54 pm PDT
Michael Plass, September 30, 1991 1:20 pm PDT
DIRECTORY
BasicTime USING [GMT, Period],
Commander, CommanderOps,
FS USING [ComponentPositions, Error, ExpandName, FileInfo, StreamOpen],
IO,
MakeDo,
Rope,
TextFind;
MakeItDepsImpl: CEDAR PROGRAM
IMPORTS BasicTime, Commander, CommanderOps, FS, IO, MakeDo, Rope, TextFind
=
BEGIN
ROPE: TYPE ~ Rope.ROPE;
RopeList: TYPE ~ LIST OF ROPE;
PatternList: TYPE ~ LIST OF PatternRule;
PatternRule: TYPE ~ REF PatternRulePrivate;
PatternRulePrivate: TYPE ~ RECORD [
resultTarget: TextFind.Target,
fromPats: RopeList,
cmdPat: ROPE];
PatternInstance: TYPE ~ REF PatternInstancePrivate;
PatternInstancePrivate: TYPE ~ RECORD [
rule: PatternRule,
from: MakeDo.From,
cmd: ROPE];
MakeItData: TYPE ~ RECORD [
makeItFull, makeItShort, resultDir: ROPE
];
patternClass: MakeDo.ActionClass ¬ NEW[MakeDo.ActionClassRep ¬ [
CheckConsistency: CheckConsistencyByDates,
Rederive: RederivePattern
]];
makeItClass: MakeDo.ActionClass ¬ NEW[MakeDo.ActionClassRep ¬ [
CheckConsistency: CheckConsistencyByDates,
Rederive: RederiveMakeIt
]];
pats: PatternList ¬ NIL;
PatternFind: PROC [resultName: ROPE, finderData: REF ANY] RETURNS [found: BOOLEAN, sought: MakeDo.Node, makes: MakeDo.NodeList, cmdFrom: MakeDo.NodeList, from: MakeDo.From, cmd: ROPE, class: MakeDo.ActionClass, foundData: REF ANY] --MakeDo.FinderProc-- = {
makeItData: REF MakeItData;
fullFName, resultDir: ROPE;
cp: FS.ComponentPositions;
dirOmitted: BOOL;
[fullFName, cp, dirOmitted] ¬ FS.ExpandName[name: resultName ! FS.Error => GOTO Fail];
resultName ¬ fullFName;
resultDir ¬ fullFName.Substr[len: cp.base.start];
FOR pl: PatternList ¬ pats, pl.rest WHILE pl#NIL DO
pat: PatternRule ~ pl.first;
matchStart, matchEnd, selStart, selEnd: INT;
subs: TextFind.Subs;
[found, matchStart, matchEnd, selStart, selEnd, subs] ¬ TextFind.RopeSearch[direction: forward, target: pat.resultTarget, rope: resultName, all: TRUE];
IF found THEN {
from ¬ [NIL, NIL];
FOR rl: RopeList ¬ pat.fromPats, rl.rest WHILE rl#NIL DO
fromName: ROPE ~ TextFind.RopeReplace[rope: resultName, with: rl.first, pattern: TRUE, subs: subs];
fromNode: MakeDo.Node ¬ MakeDo.GetNode[someName: fromName, class: MakeDo.fileClass];
from.mustHave ¬ CONS[fromNode, from.mustHave];
ENDLOOP;
cmdFrom ¬ NIL;
makes ¬ LIST[sought ¬ MakeDo.GetNode[someName: resultName, class: MakeDo.fileClass]];
cmd ¬ Rope.Cat["From ", resultDir, " ", TextFind.RopeReplace[rope: resultName, with: pat.cmdPat, pattern: TRUE, subs: subs] ];
class ¬ patternClass;
foundData ¬ NEW [PatternInstancePrivate ¬ [pat, from, cmd]];
RETURN};
ENDLOOP;
found ¬ FALSE;
sought ¬ NIL;
EXITS Fail => {found ¬ FALSE; sought ¬ NIL};
};
MakeItFind: PROC [resultName: ROPE, finderData: REF ANY] RETURNS [found: BOOLEAN, sought: MakeDo.Node, makes: MakeDo.NodeList, cmdFrom: MakeDo.NodeList, from: MakeDo.From, cmd: ROPE, class: MakeDo.ActionClass, foundData: REF ANY] --MakeDo.FinderProc-- = {
makeItData: REF MakeItData;
fullFName, resultDir, resultShort, makeItFull, makeItShort: ROPE;
cp: FS.ComponentPositions;
dirOmitted: BOOL;
[fullFName, cp, dirOmitted] ¬ FS.ExpandName[name: resultName ! FS.Error => GOTO Fail];
resultName ¬ fullFName;
resultShort ¬ fullFName.Substr[start: cp.base.start];
resultDir ¬ fullFName.Substr[len: cp.base.start];
[] ¬ FS.FileInfo[name: Rope.Concat[resultName, ".MakeIt"] ! FS.Error => GOTO Fail];
makeItShort ¬ resultShort.Concat[".MakeIt"];
makeItFull ¬ resultDir.Concat[makeItShort];
foundData ¬ makeItData ¬ NEW[MakeItData ¬ [
makeItFull: makeItFull, makeItShort: makeItShort, resultDir: resultDir
]];
from ¬ DeriveFrom[makeItData];
cmdFrom ¬ LIST[MakeDo.GetNode[someName: makeItFull, class: MakeDo.fileClass]];
makes ¬ LIST[sought ¬ MakeDo.GetNode[someName: resultName, class: MakeDo.fileClass]];
cmd ¬ DeriveCmd[makeItData];
class ¬ makeItClass;
found ¬ TRUE;
EXITS Fail => {
found ¬ FALSE;
sought ¬ NIL;
};
};
WithoutVersion: PROC [with: ROPE] RETURNS [without: ROPE] ~ {
cp: FS.ComponentPositions;
[fullFName: without, cp: cp] ¬ FS.ExpandName[name: with];
without ¬ Rope.Substr[base: without, len: cp.ext.start+cp.ext.length];
};
DeriveCmd: PROC [makeItData: REF MakeItData] RETURNS [cmd: ROPE]
~ {RETURN [IO.PutFR["From %g Source %g", [rope[makeItData.resultDir]], [rope[makeItData.makeItShort]] ]]};
DeriveFrom: PROC [makeItData: REF MakeItData] RETURNS [from: MakeDo.From] ~ {
s: IO.STREAM ¬ FS.StreamOpen[fileName: makeItData.makeItFull];
line: ROPE;
from ¬ [mustHave: LIST[MakeDo.GetNode[someName: FS.ExpandName[name: makeItData.makeItFull].fullFName, class: MakeDo.fileClass]], optional: NIL];
UNTIL Rope.Match[pattern: "--*{*}*", object: line ¬ IO.GetLineRope[s ! IO.EndOfStream => GOTO NotDependentOnAnything]] DO ENDLOOP;
IO.Close[self: s];
Here, line matches the specified pattern
line ¬ Rope.Substr[base: line, start: Rope.Find[s1: line, s2: "{"]+1]; --Strip thru "{"
line ¬ Rope.Substr[base: line, len: Rope.Find[s1: line, s2: "}"]]; -- Strip "}", etc.
s ¬ IO.RIS[rope: line];
DO
token: ROPE ~ FS.ExpandName[IO.GetTokenRope[stream: s, breakProc: IO.IDProc ! IO.EndOfStream => EXIT].token, makeItData.resultDir].fullFName;
from.mustHave ¬ CONS[MakeDo.GetNode[someName: token, class: MakeDo.fileClass], from.mustHave];
ENDLOOP;
IO.Close[self: s];
EXITS NotDependentOnAnything => {};
};
ForceConsistencyReturn: ERROR [setConsistent: BOOL, setReason: ROPE] ~ CODE;
CheckConsistencyByDates: PROC [a: MakeDo.Action, result: MakeDo.Node] RETURNS [consistent: BOOL, reason: ROPE] --MakeDo.ConsistencyChecker-- = {
ingredientFound: BOOL ¬ FALSE;
PerIngredient: PROC [n: MakeDo.Node, which: MakeDo.ActionDep, optional: BOOL] ~ {
nodeTime: BasicTime.GMT ¬ MakeDo.InnerGetCreated[n];
IF nodeTime=MakeDo.notExistTime THEN RETURN;
ingredientFound ¬ TRUE;
IF resultExists AND BasicTime.Period[from: nodeTime, to: resultTime] < 0 THEN ERROR ForceConsistencyReturn[setConsistent: FALSE, setReason: IO.PutFLR["result %g (of %g) predates ingredient %g (of %g)", LIST[[rope[resultName]], [time[resultTime]], [rope[MakeDo.PublicPartsOfNode[n: n].name]], [time[nodeTime]]]]];
RETURN};
resultTime: MakeDo.Time = result.InnerGetCreated[];
resultName: ROPE = MakeDo.PublicPartsOfNode[n: result].name;
resultExists: BOOL ~ resultTime # MakeDo.notExistTime;
MakeDo.InnerEnumerateSources[a: a, which: data, to: PerIngredient ! ForceConsistencyReturn => {
consistent ¬ setConsistent;
reason ¬ setReason;
GOTO Exit;
}];
IF NOT ingredientFound THEN RETURN [TRUE, "no inputs exist to indicate inconsistency"];
IF NOT resultExists THEN RETURN [FALSE, "some inputs but no output exist"];
RETURN [consistent: TRUE, reason: "result dated later than any existing ingredient"];
EXITS Exit => a ¬ a};
RederiveMakeIt: PROC [a: MakeDo.Action] RETURNS [from: MakeDo.From, cmd: ROPE] --MakeDo.RederiveProc-- = {
makeItData: REF MakeItData ~ NARROW[MakeDo.PublicPartsOfAction[a].foundData];
from ¬ DeriveFrom[makeItData];
cmd ¬ DeriveCmd[makeItData];
};
RederivePattern: PROC [a: MakeDo.Action] RETURNS [from: MakeDo.From, cmd: ROPE] --MakeDo.RederiveProc-- = {
pi: PatternInstance ~ NARROW[MakeDo.PublicPartsOfAction[a].foundData];
RETURN [pi.from, pi.cmd]};
AddPattern: PROC [resultPat: ROPE, froms: RopeList, cmdPat: ROPE] ~ {
pats ¬ CONS[NEW[PatternRulePrivate ¬ [TextFind.TargetFromRope[rope: resultPat, pattern: TRUE], froms, cmdPat]], pats];
RETURN};
TestFind: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY, msg: ROPE] --Commander.CommandProc-- ~ {
argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd];
IF argv.argc<3 THEN RETURN [$Failure, "Usage: target seek (forward|backward|(+|-)(case|word|def|all))* [with]"];
{target: TextFind.Target ~ TextFind.TargetFromRope[rope: argv[1], pattern: TRUE];
subject: ROPE ~ argv[2];
direction: TextFind.Direction ¬ forward;
case: BOOL ¬ TRUE;
word, def, all, found: BOOL ¬ FALSE;
with: ROPE ¬ NIL;
matchStart, matchEnd, selStart, selEnd: INT;
subs: TextFind.Subs;
FOR i: INT IN (2 .. argv.argc) DO
SELECT TRUE FROM
argv[i].Equal["forward"] => direction ¬ forward;
argv[i].Equal["backward"] => direction ¬ backward;
argv[i].Equal["-case"] => case ¬ FALSE;
argv[i].Equal["-word"] => word ¬ FALSE;
argv[i].Equal["-def"] => def ¬ FALSE;
argv[i].Equal["-all"] => all ¬ FALSE;
argv[i].Equal["+case"] => case ¬ TRUE;
argv[i].Equal["+word"] => word ¬ TRUE;
argv[i].Equal["+def"] => def ¬ TRUE;
argv[i].Equal["+all"] => all ¬ TRUE;
ENDCASE => with ¬ argv[i];
ENDLOOP;
[found, matchStart, matchEnd, selStart, selEnd, subs] ¬ TextFind.RopeSearch[direction, target, subject, 0, subject.Length[], case, word, def, all];
cmd.out.PutFL["Search[%g, \"%q\", \"%q\", %gcase, %gword, %gdef, %gall] => [%g, %g, %g, %g, %g]\n", LIST[ [rope[IF direction=forward THEN "forward" ELSE "backward"]], [rope[argv[1]]], [rope[argv[2]]], B2S[case], B2S[word], B2S[def], B2S[all], [boolean[found]], [integer[matchStart]], [integer[matchEnd]], [integer[selStart]], [integer[selEnd]] ]];
IF with#NIL THEN {
ans: ROPE ¬ TextFind.RopeReplace[subject, 0, subject.Length[], with, TRUE, subs];
cmd.out.PutF["Replace[\"%q\"] => \"%q\"\n", [rope[with]], [rope[ans]] ]};
RETURN}};
B2S: PROC [b: BOOL] RETURNS [IO.Value]
~ {RETURN [[character[IF b THEN '+ ELSE '-]]]};
Commander.Register["TestTextFind", TestFind];
MakeDo.AddFinder[finder: [name: "Pattern", finderProc: PatternFind], end: front];
AddPattern["<dir:**>'>sun4←solaris'><base:**>.so", LIST["<dir>'>sun4←solaris'><base>.c2c.o"], "ComplexCc -out <base>.so -in <base>.c2c.o -class sun4←solaris -cSwitch \"-G\""];
AddPattern["<dir:**>'><base:**>-scc.o", LIST["<dir>'><base>.c"], "! cc -g -c <base>.c -o <base>-scc.o"];
AddPattern["<dir:**>'><base:**>-gcc.o", LIST["<dir>'><base>.c"], "! gcc -g -c <base>.c -o <base>-gcc.o"];
AddPattern["<dir:**>'><base:**>.nm", LIST["<dir>'><base>.o"], "! nm -ap <base>.o '> <base>.nm"];
AddPattern["<dir:**>'><base:*>.dvi", LIST["<dir>'><base>.tex"], "! latex <base>.tex"];
AddPattern["<dir:**>'><base:*>.4050ps", LIST["<dir>'><base>.dvi"], "! 4050dvips <base>.dvi '> <base>.4050ps"];
AddPattern["<dir:**>'><base:*>.DTps", LIST["<dir>'><base>.dvi"], "! DTdvips <base>.dvi '> <base>.DTps"];
AddPattern["<dir:**>'><base:*>.LWps", LIST["<dir>'><base>.dvi"], "! dvips <base>.dvi '> <base>.LWps"];
MakeDo.AddFinder[finder: [name: "MakeIt", finderProc: MakeItFind], end: front];
END.