<> <> <> <> <<>> DIRECTORY BasicTime USING [GMT, Period], FS USING [ComponentPositions, Error, ExpandName, FileInfo, StreamOpen], IO USING [Close, EndOfStream, GetLineRope, GetTokenRope, IDProc, PutFR, RIS, STREAM], MakeDo, Rope USING [Cat, Find, Match, ROPE, Substr]; MakeItDepsImpl: CEDAR PROGRAM IMPORTS BasicTime, FS, IO, MakeDo, Rope ~ BEGIN ROPE: TYPE ~ Rope.ROPE; MakeItData: TYPE ~ RECORD [ makeItFile: 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; makeItName: ROPE; resultName _ FS.ExpandName[name: resultName ! FS.Error => GOTO Fail].fullFName; makeItName _ WithoutVersion[FS.FileInfo[name: Rope.Cat[resultName, ".MakeIt"] ! FS.Error => GOTO Fail].fullFName]; foundData _ makeItData _ NEW[MakeItData _ [ makeItFile: makeItName ]]; from _ DeriveFrom[makeItData]; cmdFrom _ LIST[MakeDo.GetNode[someName: makeItName, 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 [Rope.Cat["SecondSource ", makeItData.makeItFile]]; }; DeriveFrom: PROC [makeItData: REF MakeItData] RETURNS [from: MakeDo.From] ~ { s: IO.STREAM _ FS.StreamOpen[fileName: makeItData.makeItFile]; line: ROPE; from _ [mustHave: LIST[MakeDo.GetNode[someName: FS.ExpandName[name: makeItData.makeItFile].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].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]>> PerIngredient: PROC [n: MakeDo.Node, which: MakeDo.ActionDep, optional: BOOL] ~ { nodeTime: BasicTime.GMT _ MakeDo.InnerGetCreated[n]; nodeName: ROPE ~ MakeDo.PublicPartsOfNode[n: n].name; SELECT TRUE FROM nodeTime = MakeDo.notExistTime => { IF ~optional THEN ERROR ForceConsistencyReturn[setConsistent: TRUE, setReason: IO.PutFR[format: "ingredient %g doesn't exist", v1: [rope[nodeName]]]]; }; resultTime = MakeDo.notExistTime => {}; --More important than anything below BasicTime.Period[from: nodeTime, to: resultTime] < 0 => 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[nodeName]], v4: [time[nodeTime]]]] ENDCASE; }; makeItData: REF MakeItData ~ NARROW[MakeDo.PublicPartsOfAction[a].foundData]; resultTime: MakeDo.Time = result.InnerGetCreated[]; resultName: ROPE = MakeDo.PublicPartsOfNode[n: result].name; MakeDo.InnerEnumerateSources[a: a, which: data, to: PerIngredient ! ForceConsistencyReturn => { consistent _ setConsistent; reason _ setReason; GOTO Exit; }]; IF resultTime = MakeDo.notExistTime THEN RETURN [consistent: FALSE, reason: IO.PutFR[format: "result %g doesn't exist", v1: [rope[resultName]]]] ELSE RETURN [consistent: TRUE, reason: "result dated later than any ingredient"]; EXITS Exit => {}; }; 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.