DIRECTORY CedarProcess USING [Process], Commander USING [CommandObject, Handle], CommandTool USING [CopyAList], FS USING [ComponentPositions, Error, ExpandName, StreamOpen], IO USING [Close, noInputStream, noWhereStream, PutF, PutFR, PutRope, STREAM, Value], IOClasses USING [CreateDribbleOutputStream], List USING [Assoc, PutAssoc], MakeDo USING [ActionRep, EnumerateResults, NodeClassRep, NodeRep, PublicPartsOfNode, UncurrentProducer], MakeDoBasics USING [CheckIn, EndFork, Execution, InnerSuspectNodeChange, NeedToFinish, RegisterReporter, Reporter, ReporterRep, SetES], MakeDoPrivate USING [ActionRep, AddFailedCmd, NodeClassRep, NodeRep], MessageWindow USING [Append], MoreIOClasses USING [CreateBuffer, SendBuffer], Process USING [Abort, InvalidProcess], RefTab USING [Delete], Rope; MakeDoReportOnFiles: CEDAR MONITOR IMPORTS CommandTool, FS, IO, IOClasses, List, MakeDo, MakeDoBasics, MakeDoPrivate, MessageWindow, MoreIOClasses, Process, RefTab, Rope EXPORTS MakeDo = BEGIN OPEN MakeDo, MakeDoPrivate, MakeDoBasics; ROPE: TYPE = Rope.ROPE; NodeRep: PUBLIC TYPE = MakeDoPrivate.NodeRep; ActionRep: PUBLIC TYPE = MakeDoPrivate.ActionRep; NodeClassRep: PUBLIC TYPE = MakeDoPrivate.NodeClassRep; reporterOnFiles: MakeDoBasics.Reporter ~ NEW [MakeDoBasics.ReporterRep _ [ destroyAuxBox: DestroyAuxBox, auxBoxDestroyed: AuxBoxDestroyed, buffer: Buffer, msg: Msg, flush: Flush ]]; AuxBox: TYPE ~ LIST OF FileExecutionViewer; auxBox: AuxBox _ NIL; FileExecutionViewer: TYPE ~ REF FileExecutionViewerRep; FileExecutionViewerRep: TYPE ~ RECORD [ logFileName: ROPE, logStream: IO.STREAM ]; bufKey: ATOM = $MakeDoBuffer; logFilePrefix: ROPE _ ".makeLog."; auxBoxOccupancy: INT _ 0; monitor: BOOL _ FALSE; DestroyAuxBox: -- PUBLIC -- PROC ~ { FOR auxRest: AuxBox _ auxBox, auxRest.rest WHILE auxRest # NIL DO exView: FileExecutionViewer ~ auxRest.first; exView.logStream.Close[]; ENDLOOP; auxBox _ NIL; }; AuxBoxDestroyed: -- PUBLIC -- PROC RETURNS [BOOL _ TRUE] ~ { RETURN [auxBox = NIL]; }; Buffer: -- PUBLIC -- ENTRY PROC [e: Execution] = { ENABLE UNWIND => NULL; InnerBuffer[e]; RETURN}; InnerBuffer: INTERNAL PROC [e: Execution] = {--structure contorted to avoid Cirio blind spots ch: Commander.Handle ~ e.ch; bufout: IO.STREAM = MoreIOClasses.CreateBuffer[]; gname, verless, logFileName, fmterr: ROPE; logStream: IO.STREAM; IF AuxBoxDestroyed[] THEN { auxBoxOccupancy _ 0; }; auxBoxOccupancy _ auxBoxOccupancy + 1; e.bch _ NEW [Commander.CommandObject _ [ commandLine: "Shouldn't care", propertyList: List.PutAssoc[bufKey, bufout, CommandTool.CopyAList[ch.propertyList]] ]]; gname _ MakeDo.PublicPartsOfNode[e.goal].name; {lgname: ROPE ~ gname; fullName: ROPE; cp: FS.ComponentPositions; [fullName, cp, ] _ FS.ExpandName[lgname !FS.Error => GOTO Genit]; verless _ Rope.Substr[base: fullName, start: 0, len: cp.ext.start+cp.ext.length]; logFileName _ Rope.Replace[verless, cp.base.start, 0, logFilePrefix]; EXITS Genit => { logFileName _ IO.PutFR["%gAction%g", [rope[logFilePrefix]], [integer[actionCount _ actionCount.SUCC]]]; ch.err.PutF["Log for making %g going to %g\n", [rope[gname]], [rope[logFileName]] ]}; }; e.bch.in _ IO.noInputStream; {llogFileName: ROPE ~ logFileName; llogStream: IO.STREAM; llogStream _ FS.StreamOpen[fileName: llogFileName, accessOptions: create !FS.Error => { fmterr _ IO.PutFR["FS.Error[%g, %g]", [atom[error.code]], [rope[error.explanation]] ]; GOTO Complain}]; logStream _ llogStream; EXITS Complain => { ch.err.PutF["%g when trying to create command log %g; output will not be logged.\n", [rope[fmterr]], [rope[logFileName]] ]; logStream _ IO.noWhereStream} }; {exView: FileExecutionViewer ~ NEW [FileExecutionViewerRep _ [logFileName: logFileName, logStream: logStream]]; this: LIST OF FileExecutionViewer ~ LIST[exView]; e.view _ exView; IF auxBox = NIL THEN auxBox _ this ELSE { this.rest _ auxBox; auxBox _ this }; }; e.bch.err _ e.bch.out _ IOClasses.CreateDribbleOutputStream[bufout, logStream]; e.es _ buffered; }; actionCount: INT _ 0; Abandonit: PROC [e: Execution] ~ { {OPEN e; IF NeedToFinish[e] THEN { ENABLE UNWIND => { EndFork[e.resources]; Flush[e, TRUE, TRUE, a.cmd]; [] _ job.processes.Delete[process]; }; IF forked THEN Flush[e, TRUE, TRUE, a.cmd]; a.fails _ true; AddFailedCmd[job, a]; EnumerateResults[a, InnerSuspectNodeChange]; CheckIn[job, goal, a, e.process]; SetES[e, final]; UncurrentProducer[goal]; MessageWindow.Append[message: "command execution abandoned", clearFirst: TRUE]; } ELSE MessageWindow.Append[message: "command execution already finishing", clearFirst: TRUE]; }}; Stopit: PROC [e: Execution] = { message: ROPE _ "command execution ABORTed"; IF e.process # NIL AND e.process.status = busy THEN TRUSTED {Process.Abort[e.process.process !Process.InvalidProcess => { message _ IF process#e.process.process THEN "Zowie! Bug 6 encountered!" ELSE IF e.process.status=busy THEN "Wow! CedarProcess bug observed!" ELSE "Already gone!"; CONTINUE; }]} ELSE message _ IF e.process = NIL THEN "Can't ABORT because it's not gotten started yet" ELSE SELECT e.process.status FROM done => "Can't ABORT because it's already done", aborted => "Can't ABORT because it's already ABORTED", debugging => "Won't ABORT because it's being debugged", busy => "Wouldn't ABORT because it was not busy a few microseconds ago", invalid => "Won't ABORT because it's invalid", ENDCASE => "Won't ABORT because status unrecognized (I'm suffering software rot!)"; MessageWindow.Append[message: message, clearFirst: TRUE]; RETURN}; Gushit: PROC [e: Execution] = { e.gushMe _ TRUE; }; Msg: -- PUBLIC -- ENTRY PROC [ch: Commander.Handle, format: ROPE, v1, v2, v3, v4, v5: IO.Value _ [null[]]] = { ENABLE UNWIND => NULL; ch.out.PutF[format, v1, v2, v3, v4, v5]; }; Flush: --PUBLIC-- ENTRY PROC [e: Execution, long, abandon: BOOL, asRope: ROPE] = { ENABLE UNWIND => NULL; exView: FileExecutionViewer ~ NARROW[e.view]; bch: Commander.Handle ~ e.bch; ch: Commander.Handle ~ e.ch; buffer: IO.STREAM = NARROW[List.Assoc[bufKey, bch.propertyList]]; last: LIST OF FileExecutionViewer _ NIL; IF abandon THEN { ch.out.PutF["%lAbandoning %g%l\n", [rope["be"]], [rope[asRope]], [rope["BE"]]]; MoreIOClasses.SendBuffer[buffer, ch.out, FALSE]; ch.out.PutRope["\n"]; } ELSE IF long THEN MoreIOClasses.SendBuffer[buffer, ch.out, TRUE] ELSE ch.out.PutF["%lDone with %g%l\n", [rope["e"]], [rope[asRope]], [rope["E"]]]; IF AuxBoxDestroyed[] THEN { auxBoxOccupancy _ 0; } ELSE FOR cur: LIST OF FileExecutionViewer _ auxBox, cur.rest WHILE cur # NIL DO IF cur.first = exView THEN { IF last # NIL THEN last.rest _ cur.rest ELSE auxBox _ cur.rest; cur.first.logStream.Close[]; auxBoxOccupancy _ auxBoxOccupancy - 1; EXIT; }; last _ cur; ENDLOOP; }; MakeDoBasics.RegisterReporter[$FILES, reporterOnFiles]; END. N MakeDoReportOnFiles.Mesa Last tweaked by Mike Spreitzer on April 26, 1990 9:57:00 am PDT Carl Hauser, April 11, 1985 3:43:34 pm PST Eduardo Pelegri-Llopart March 20, 1989 9:51:55 am PST JKF January 11, 1989 10:32:27 am PST EXPORTS MakeDo, MakeDoBasics INVARIANT The integrity of the aux box data structure. Viewer Manipulation Κ q– "cedar" style•NewlineDelimiter ™codešœ™Kšœ?™?Kšœ'Οk™*Kšœ5™5K™$—J˜š ˜ Jšœ œ ˜Jšœ œ˜(Jšœ œ ˜Jšœœ5˜=Jšœœ=œ ˜TJšœ œ˜,Jšœœ˜Jšœœ\˜hJšœ œu˜‡Jšœœ2˜EJšœœ ˜Jšœœ˜/Jšœœ˜&Jšœœ ˜Jšœ˜—K˜K˜šΡbnxœœ˜"Kšœœœk˜†Kšœ™Kšœ˜š ™ K™,——K˜Kšœ˜Kšœœ%˜/K˜Kšœœœ˜Kšœ œœ˜-Kšœ œœ˜1Kšœœœ˜7head™šœ)œ˜JK˜Kšœ!˜!Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜K˜—Kšœœœœ˜+Kšœœ˜K˜Kšœœœ˜7šœœœ˜'Kšœ œ˜Kšœ œ˜K˜—K˜Kšœœ˜K˜šœœ˜"K˜—Kšœœ˜Kšœ œœ˜K˜šΟn œΟc œœ˜$šœ(œ œ˜AK˜,K˜Kšœ˜—Kšœ œ˜ Kšœ˜—K˜š Ÿœ  œœœœœ˜˜Jšœ ˜ Kšœœ˜>Kšœœœ#˜EKšœ˜—Kšœ˜ Kšœ˜—šœ œ ˜!Kšœ2˜6šœœ˜!Kšœ0˜0Kšœ6˜6Kšœ7˜7KšœH˜HKšœ.˜.KšœL˜S———Kšœ3œ˜9Kšœ˜—K˜–‚ -- [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift: BOOL _ FALSE, control: BOOL _ FALSE]šŸœœ˜Kšœ œ˜K˜—K˜K˜š Ÿœ  œœœ œœ˜nKšœœœ˜K˜(K˜—K˜š Ÿœ  œœœœ œ˜RKšœœœ˜Kšœœ ˜-Kšœ˜K˜Kšœœœœ'˜AKšœœœœ˜(šœ œ˜KšœO˜OKšœ)œ˜0K˜K˜—Kšœœœ*œ˜@KšœM˜Qšœœ˜K˜K˜—š œœœœ(œœ˜Ošœœ˜Kšœœœœ˜?K˜K˜&Kšœ˜K˜—K˜ Kšœ˜—K˜K˜K˜7——Kšœ˜—…—`%