DIRECTORY CedarProcess USING [Process], Commander USING [CommandObject, Handle], FS USING [ComponentPositions, Error, ExpandName, StreamOpen], IO USING [Close, noInputStream, noWhereStream, PutF, PutFL, PutFR, PutRope, STREAM, Value], IOClasses USING [CreateDribbleOutputStream], List USING [AList, Assoc, DotCons, 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], MoreIOClasses USING [CreateBuffer, SendBuffer], Process USING [Abort, InvalidProcess], RefTab USING [Delete], Rope, SimpleFeedback USING [Append]; MakeDoReportOnFiles: CEDAR MONITOR IMPORTS FS, IO, IOClasses, List, MakeDo, MakeDoBasics, MakeDoPrivate, MoreIOClasses, Process, RefTab, Rope, SimpleFeedback 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, 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; }; CopyAList: PUBLIC PROC [old: List.AList] RETURNS [new: List.AList] ~ { tail: List.AList ¬ NIL; new ¬ NIL; UNTIL old = NIL DO newItem: List.AList ¬ LIST[List.DotCons[key: old.first.key, val: old.first.val]]; IF tail = NIL THEN new ¬ newItem ELSE tail.rest ¬ newItem; old ¬ old.rest; tail ¬ newItem; ENDLOOP; }; 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]; SimpleFeedback.Append[$MakeDo, oneLiner, $info, "command execution abandoned"]; } ELSE SimpleFeedback.Append[$MakeDo, oneLiner, $info, "command execution already finishing"]; }}; 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!)"; SimpleFeedback.Append[$MakeDo, oneLiner, $info, message]; 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.PutFL[format, LIST[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. Š MakeDoReportOnFiles.Mesa Copyright Σ 1991 by Xerox Corporation. All rights reserved. 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 Willie-s, September 27, 1991 4:44 pm PDT Michael Plass, September 30, 1991 12:51 pm PDT EXPORTS MakeDo, MakeDoBasics INVARIANT The integrity of the aux box data structure. Viewer Manipulation CopyAList copies the CONS cells of the list itself and also copies the DotCons cells which are the elements of the list. Because the DotCons cells are copied, one can change the key-value mappings in the new list without affecting the mappings in the old list. Because the CONS cells are copied, one can alter the list without affecting the old list. ERROR CommanderOps.Failed["CommandTool.CopyAList is deimplemented"]; Κ •NewlineDelimiter –(cedarcode) style™codešœ™Kšœ Οeœ1™˜Jšœ ˜ Kšžœžœ˜>Kšžœžœžœ#˜EKšžœ˜—Kšžœ˜ Kšœ˜—šžœ žœ ž˜!Kšžœ2˜6šžœžœž˜!Kšœ0˜0Kšœ6˜6Kšœ7˜7KšœH˜HKšœ.˜.KšžœL˜S———Kšœ:˜:Kšžœ˜—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šžœ˜—…—‚)#