<<>> <> <> <> <> <> <<>> DIRECTORY BasicTime USING [GMT, Period], FS USING [ComponentPositions, Error, ExpandName, FileInfo, StreamOpen], IO, MakeDo, Rope; MakeItDepsImpl: CEDAR PROGRAM IMPORTS BasicTime, FS, IO, MakeDo, Rope ~ BEGIN ROPE: TYPE ~ Rope.ROPE; MakeItData: TYPE ~ RECORD [ makeItFull, makeItShort, resultDir: ROPE ]; makeItClass: MakeDo.ActionClass _ NEW[MakeDo.ActionClassRep _ [ CheckConsistency: CheckMakeItConsistency, Rederive: RederiveMakeIt ]]; MakeItFind: MakeDo.FinderProc = { <<[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]>> 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]; <> 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; CheckMakeItConsistency: MakeDo.ConsistencyChecker = { <<[a: MakeDo.Action, result: MakeDo.Node] RETURNS [consistent: BOOL, reason: ROPE]>> 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.PutFR[format: "result %g (of %g) predates ingredient %g (of %g)", v1: [rope[resultName]], v2: [time[resultTime]], v3: [rope[MakeDo.PublicPartsOfNode[n: n].name]], v4: [time[nodeTime]] ]]; RETURN}; makeItData: REF MakeItData ~ NARROW[MakeDo.PublicPartsOfAction[a].foundData]; 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: MakeDo.RederiveProc = { <<[a: MakeDo.Action] RETURNS [from: MakeDo.From, cmd: ROPE]>> makeItData: REF MakeItData ~ NARROW[MakeDo.PublicPartsOfAction[a].foundData]; from _ DeriveFrom[makeItData]; cmd _ DeriveCmd[makeItData]; }; MakeDo.AddFinder[finder: [name: "MakeIt", finderProc: MakeItFind], end: front]; END.