DIRECTORY Atom, BasicTime, Commander, DFUtilities, FS, IO, IOClasses, MakeDo, Process, RedBlackTree, Rope; MakeDoCmds: CEDAR PROGRAM IMPORTS Atom, Commander, DFUtilities, FS, IO, IOClasses, MakeDo, Process, RedBlackTree, Rope EXPORTS MakeDo = BEGIN ROPE: TYPE = Rope.ROPE; GetObjectOrSwitch: PROC [from: IO.STREAM] RETURNS [asAny: REF ANY] = { SELECT from.PeekChar[] FROM '- => { IF from.GetChar[] # '- THEN ERROR; RETURN[Atom.MakeAtom[from.GetTokenRope[Break].token]]; }; ENDCASE => RETURN [GetObject[from]]; }; Break: PROC [char: CHAR] RETURNS [cc: IO.CharClass] = { cc _ SELECT char FROM IN [0C .. ' ] => sepr, ENDCASE => other; }; GetObject: PROC [from: IO.STREAM] RETURNS [node: MakeDo.Node] = { SELECT from.PeekChar[] FROM '( => { className, objectName: ROPE; class: MakeDo.NodeClass; node: MakeDo.Node; IF from.GetChar[] # '( THEN ERROR; className _ from.GetRopeLiteral[]; objectName _ from.GetRopeLiteral[]; [] _ from.SkipWhitespace[]; IF from.GetChar[] # ') THEN { SIGNAL MakeDo.Warning["Syntax error, you fool"]; RETURN [NIL]; }; class _ MakeDo.LookupNodeClass[className]; IF class = NIL THEN { SIGNAL MakeDo.Warning[IO.PutFR[ "no such class as %g", [refAny[className]] ]]; RETURN [NIL]; }; node _ MakeDo.FindNode[objectName, class]; RETURN [node]; }; ENDCASE => { fileName: ROPE _ from.GetTokenRope[Break].token; node: MakeDo.Node _ MakeDo.FindNode[fileName, MakeDo.fileClass]; RETURN [node]; }; }; AnalyzeDFFile: PUBLIC PROC [dfName: ROPE, goals: MakeDo.RefTable, modifiable: MakeDo.ModifiabilitySpec, doToVerifyGoals, doToOthers: MakeDo.DoToFile] = { Consume: PROC [item: REF ANY] RETURNS [stop: BOOL _ FALSE] = 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]; SELECT (IF fi.verifyRoot THEN doToVerifyGoals ELSE doToOthers) FROM ignore => NULL; makeGoal => NameAdd[verless, TRUE, TRUE]; makeModifiable => NameAdd[verless, FALSE, TRUE]; ENDCASE => ERROR; }; 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; NameAdd: PROC [name: ROPE, goal, mod: BOOL] = { n: MakeDo.Node _ MakeDo.FindNode[name, MakeDo.fileClass]; NodeAdd[n, goal, mod]; }; NodeAdd: PROC [n: MakeDo.Node, goal, mod: BOOL] = { IF mod THEN MakeDo.EnsureRefInTable[n, modifiable]; IF goal THEN MakeDo.EnsureRefInTable[n, goals]; }; dfIn: IO.STREAM = FS.StreamOpen[dfName]; DFUtilities.ParseFromStream[in: dfIn, proc: Consume]; dfIn.Close[]; }; DFDontExist: ERROR [fileName: ROPE] = CODE; CmdMakeDo: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- = BEGIN ENABLE DFDontExist => {msg _ fileName.Concat[" doesn't exist"]; result _ $Failure; CONTINUE}; AddDF: PROC [doToVerifyGoals, doToOthers: MakeDo.DoToFile] = BEGIN dfName: ROPE _ NIL; dfIn: IO.STREAM _ NIL; IF doToVerifyGoals=makeModifiable OR doToOthers=makeModifiable THEN specModifiable _ TRUE; [] _ in.SkipWhitespace[]; IF in.EndOf[] THEN {AddMsg["No DF-file name after -whatever"]; RETURN}; dfName _ in.GetTokenRope[Break].token; IF dfName.Find["."] < 0 THEN dfName _ dfName.Cat[".DF"]; [] _ FS.FileInfo[dfName !FS.Error => IF error.group = user THEN DFDontExist[dfName]]; AnalyzeDFFile[dfName, goals, modifiable, doToVerifyGoals, doToOthers]; END; NodeAdd: PROC [n: MakeDo.Node, goal, mod: BOOL] = { IF mod THEN MakeDo.EnsureRefInTable[n, modifiable]; IF goal THEN MakeDo.EnsureRefInTable[n, goals]; }; AddObject: PROC [goal, mod: BOOL] = { n: MakeDo.Node; IF mod THEN specModifiable _ TRUE; [] _ in.SkipWhitespace[]; IF in.EndOf[] THEN {AddMsg["No object after -nm"]; RETURN}; n _ GetObject[in]; NodeAdd[n, goal, mod]; }; AddMsg: PROC [more: ROPE] = {msgout.PutRope[more]; msgout.PutRope["\n"]}; goals: MakeDo.RefTable _ MakeDo.MakeRefTable[]; modifiable: MakeDo.RefTable _ MakeDo.MakeRefTable[]; specModifiable: BOOL _ FALSE; in: IO.STREAM _ IO.RIS[cmd.commandLine]; msgout, logfile: IO.STREAM _ NIL; logfile _ FS.StreamOpen["MakeDo.log", create]; msgout _ IOClasses.CreateDribbleOutputStream[logfile, cmd.err]; {ENABLE MakeDo.Warning => {AddMsg[message]; RESUME}; FOR i: INT _ in.SkipWhitespace[], in.SkipWhitespace[] WHILE NOT in.EndOf[] DO thing: REF ANY _ GetObjectOrSwitch[in]; IF thing # NIL THEN WITH thing SELECT FROM a: ATOM => SELECT a FROM $rg => AddDF[makeGoal, ignore]; $og => AddDF[makeGoal, makeGoal]; $rgom => AddDF[makeGoal, makeModifiable]; $dr => AddDF[makeGoal, makeModifiable]; $om => AddDF[makeModifiable, makeModifiable]; $nm => AddObject[FALSE, TRUE]; $p => MakeDo.SetProcessAllocation[in.GetInt[]]; ENDCASE => AddMsg[IO.PutFR["Bad switch [-%g]", IO.atom[a]]]; ENDCASE => { n: MakeDo.Node _ MakeDo.NarrowToNode[thing]; NodeAdd[n, TRUE, TRUE]; }; Process.CheckForAbort[]; ENDLOOP; IF NOT specModifiable THEN {modifiable.DestroyTable[]; modifiable _ NIL}; SELECT cmd.procData.clientData FROM $MakeDo => { okGoalCount, nonOKGoalCount, nSteps, nFailedSteps: NAT; failedSteps: MakeDo.ActionList; failedGoals: MakeDo.NodeList; [okGoalCount:okGoalCount, nonOKGoalCount:nonOKGoalCount, nSteps:nSteps, failedSteps:failedSteps, nonOKGoalList:failedGoals] _ MakeDo.Ensure[goals, modifiable, cmd]; nFailedSteps _ 0; FOR failedSteps _ failedSteps, failedSteps.rest WHILE failedSteps # NIL DO msgout.PutF["%lFailed: %g%l\n", IO.rope["b"], IO.rope[failedSteps.first.PublicPartsOfAction[].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 OK; %g not.\n", IO.rope[Quantify[okGoalCount, "goal"]], IO.int[nonOKGoalCount]]; IF failedGoals # NIL THEN { msgout.PutF["%lNot OK:", IO.rope["b"]]; FOR failedGoals _ failedGoals, failedGoals.rest WHILE failedGoals # NIL DO msgout.PutF[" %g", IO.rope[failedGoals.first.DescribeNode[]]]; ENDLOOP; msgout.PutF["%l\n", IO.rope["B"]]; }; result _ IF nonOKGoalCount # 0 THEN $Failure ELSE $Success; }; $MakePrediction, $MakeCommandList => { al: MakeDo.ActionList _ MakeDo.GetActions[ goals, modifiable, SELECT cmd.procData.clientData FROM $MakePrediction => toBeDone, $MakeCommandList => all, ENDCASE => ERROR]; al _ MakeDo.DestructivelyReverseActionList[al]; msgout.PutRope["Commands:\n"]; FOR al _ al, al.rest WHILE al # NIL DO a: MakeDo.Action = al.first; cmd: ROPE = a.PublicPartsOfAction[].cmd; msgout.PutF["%g\n", [rope[cmd]] ]; ENDLOOP; al _ al; }; ENDCASE => ERROR; }; msgout.Flush[]; logfile.Close[]; END; CmdExplain: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- = BEGIN args: MakeDo.RefTable _ MakeDo.MakeRefTable[]; in: IO.STREAM _ IO.RIS[cmd.commandLine]; FOR i: INT _ in.SkipWhitespace[], in.SkipWhitespace[] WHILE NOT in.EndOf[] DO ENABLE MakeDo.Warning => { cmd.out.PutRope[message]; cmd.out.PutRope["\n"]; RESUME}; n: MakeDo.Node _ GetObject[in]; IF n # NIL THEN MakeDo.EnsureRefInTable[n, args]; ENDLOOP; MakeDo.Explain[cmd, args]; END; CmdProduce: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- = BEGIN in: IO.STREAM _ IO.RIS[cmd.commandLine]; FOR i: INT _ in.SkipWhitespace[], in.SkipWhitespace[] WHILE NOT in.EndOf[] DO ENABLE MakeDo.Warning => { cmd.out.PutRope[message]; cmd.out.PutRope["\n"]; RESUME}; n: MakeDo.Node _ GetObject[in]; IF n # NIL THEN MakeDo.RetryToProduce[n]; ENDLOOP; in.Close[]; END; Bitch: ERROR [message: ROPE] = CODE; CmdSuspect: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --Commander.CommandProc-- = BEGIN ENABLE Bitch => {msg _ message; result _ $Failure; CONTINUE}; in: IO.STREAM _ IO.RIS[cmd.commandLine]; FOR i: INT _ in.SkipWhitespace[], in.SkipWhitespace[] WHILE NOT in.EndOf[] DO ENABLE MakeDo.Warning => { cmd.out.PutRope[message]; cmd.out.PutRope["\n"]; RESUME}; thing: REF ANY _ GetObjectOrSwitch[in]; DoObject: PROC [change, current, producer: BOOL] = { n: MakeDo.Node; [] _ in.SkipWhitespace[]; IF in.EndOf[] THEN Bitch["MakeDo ran off end of command line --- missing object"]; n _ GetObject[in]; Work[n, change, current, producer]; }; Work: PROC [n: MakeDo.Node, change, current, producer: BOOL] = { IF change THEN MakeDo.SuspectNodeChange[n]; IF current THEN MakeDo.UncurrentNode[n]; IF producer THEN MakeDo.UncurrentProducer[n]; }; IF thing # NIL THEN WITH thing SELECT FROM a: ATOM => SELECT a FROM $allCurrent => MakeDo.ForAll[FALSE, TRUE]; $allChange => MakeDo.ForAll[TRUE, FALSE]; $all => MakeDo.ForAll[TRUE, TRUE]; $change => DoObject[TRUE, FALSE, FALSE]; $current => DoObject[FALSE, TRUE, FALSE]; $producer => DoObject[FALSE, FALSE, TRUE]; ENDCASE => cmd.out.PutF["Unrecognized switch -%g\n", [atom[a]]]; ENDCASE => { n: MakeDo.Node _ MakeDo.NarrowToNode[thing]; Work[n, TRUE, TRUE, TRUE]; }; ENDLOOP; in.Close[]; END; CmdDestroy: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] --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, clientData: $MakeDo, doc: "Ensure that derived files are up to date. Syntax is MakeDo * : | -nm | -rg | -og | -rgom | -dr | -om | -p : | (className: objectName:)"]; Commander.Register[key: "MakePrediction", proc: CmdMakeDo, clientData: $MakePrediction, doc: "Estimate what 'MakeDo' would execute. Syntax is MakeCommandList *"]; Commander.Register[key: "MakeCommandList", proc: CmdMakeDo, clientData: $MakeCommandList, doc: "List all commands needed to make goals. Syntax is MakeCommandList *"]; Commander.Register[key: "MakeExcuses", proc: CmdExplain, doc: "Explain why MakeDo is misbehaving. Syntax is MakeExcuses *"]; Commander.Register[key: "MakeSuspicion", proc: CmdSuspect, doc: "Suspect cached information is out of synch with reality. Syntax is MakeSuspicion * : -change --suspect the named file of change -current --forget whether named file is current -producer --suspect that the next execution of the file's producer will be different from the last --all of the above -allChange --suspect every object of change -allCurrent --suspect every object of not being current and every action of behaving differently than last time -all --all of the above"]; Commander.Register[key: "MakeEmpty", proc: CmdDestroy, doc: "Delete the entire dependency graph. No arguments"]; Commander.Register[key: "MakeProducer", proc: CmdProduce, doc: "For leaves, try again to find a producer. Syntax is MakeProducer *"]; END. LMakeDoCmds.Mesa Last Edited by: Spreitzer, May 9, 1986 8:51:37 pm PDT Κ s– "cedar" style˜code™J™5—K˜KšΟk œ*œœ1˜jK˜šΠbx œœ˜Kšœœœ0˜\Kšœ ˜—K˜Kš˜K˜Kšœœœ˜K˜šΟnœœœœœ œœ˜Fšœ˜šœ˜Kšœœœ˜"Kšœ0˜6K˜—Kšœœ˜$—K˜—K˜š Ÿœœœœœ˜7šœœ˜Kšœ˜Kšœ ˜—K˜—K˜š Ÿ œœœœœ˜Ašœ˜˜Kšœœ˜K˜K˜Kšœœœ˜"K˜"Kšœ#˜#K˜šœœ˜Kšœ*˜0Kšœœ˜ K˜—Kšœ*˜*šœ œœ˜šœœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœœ˜ Kšœ˜—Kšœ*˜*Kšœ˜K˜—šœ˜ Kšœ œ"˜0Kšœ@˜@Kšœ˜K˜——K˜—K˜šŸ œœœ œq˜™šŸœœœœœœœ˜Kšœ˜—Kšœœ ˜"K˜—Kšœ œœ œ ˜;K˜—šœ&˜&šœ*˜*Kšœ˜Kšœ ˜ šœ˜#Kšœ˜Kšœ˜Kšœœ˜——Kšœ/˜/K˜šœœœ˜&K˜Kšœœ˜(K˜"Kšœ˜—K˜Kšœ˜—Kšœœ˜—K˜Kšœ˜Kšœ˜Kšœ˜—K˜šŸ œœœ œœœœœ œ˜uKš˜Kšœ.˜.Kš œœœœœ˜(š œœ,œœ ˜Mšœ˜K˜K˜Kšœ˜—K˜Kšœœœ"˜1Kšœ˜—Kšœ˜Kšœ˜—K˜šŸ œœœ œœœœœ œ˜uKš˜Kš œœœœœ˜(š œœ,œœ ˜Mšœ˜K˜K˜Kšœ˜—K˜Kšœœœ˜)Kšœ˜—K˜ Kšœ˜—K˜KšŸœœ œœ˜$K˜šŸ œœœ œœœœœ œ˜uKšœœ-œ˜CKš œœœœœ˜(š œœ,œœ ˜Mšœ˜K˜K˜Kšœ˜—Kšœœœ˜'šŸœœœ˜4K˜Kšœ˜Kšœ œ@˜RK˜Kšœ#˜#K˜—šŸœœ-œ˜@Kšœœ˜+Kšœ œ˜(Kšœ œ˜-K˜—š œ œœœœ˜*šœœœ˜Kšœœœ˜*Kšœœœ˜)Kšœœœ˜"Kšœœœœ˜(Kšœœœœ˜)Kšœœœœ˜*Kšœ9˜@—šœ˜ K˜,Kšœœœœ˜K˜——Kšœ˜—K˜ Kšœ˜—K˜šŸ œœœ œœœœœ œ˜uKš˜Kšœ˜Kšœ˜—K˜š Ÿœœœ œœ œ˜?Kšœ œœ œœœœœ˜`—K˜Kš&œwΟtœ‘œ‘œ‘ œ‘ œ‘œ‘œ ‘œ‘œ‘œ‘œ‘ œ‘œΟbœ ‘œ‘œ ‘œ‘’œ˜ώK˜Kšœ‘œ‘œ˜¨K˜Kšœ“‘œ‘œ˜¬K˜Kšœm‘ œ‘œ˜…K˜Kš%œ’‘œ‘œ‘Πbt ‘œ‘Πct"’ œ‘œ‘€&’ œ‘œ‘€X‘œ‘€’ œ  ’œ c’œ œ˜ΫK˜K˜qK˜Kšœ‚‘œ‘œ˜ŽK˜Kšœ˜—…—+ͺ9i