<> <> <> DIRECTORY AMEvents USING [ CallDebugger ], Atom USING [ PutProp, GetProp, PropList ], Commander USING [ CommandProc, GetProperty, Handle, Register ], FS USING [ StreamOpen, Error ], IO, Log, PrincOpsUtils USING [ IsBound ], ProcessProps USING [ GetPropList ], Rope USING [ ROPE ], SpyLog USING [ WriteTrace ] ; LogImpl: CEDAR MONITOR -- for CLog IMPORTS AMEvents, Atom, Commander, FS, IO, ProcessProps, PrincOpsUtils, SpyLog EXPORTS Log = { OPEN IO; <> pd: PUBLIC REF Log.PD _ NEW[Log.PD_[]]; <> ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; ThHandle: TYPE = LONG CARDINAL; WhereToReport: TYPE = Log.WhereToReport; WhereProc: TYPE = Log.WhereProc; <> <<>> WP: TYPE = REF WPRec; WPRec: TYPE = RECORD [ proc: WhereProc, fixedWhereData: REF, defaultIfNotFound: Log.DNFProc_NIL ]; RegisterWhereToReport: PUBLIC PROC[ proc: WhereProc, where: WhereToReport, fixedWhereData: REF, defaultIfNotFound: Log.DNFProc] = { Atom.PutProp[$ReportStreams, where, NEW[WPRec_[proc: proc, fixedWhereData: fixedWhereData, defaultIfNotFound: defaultIfNotFound]]]; }; FindWhere: PUBLIC PROC[where: WhereToReport, whereData: REF] RETURNS [s: IO.STREAM] = { wp: WP; IF where=NIL THEN RETURN[pd.sysOut]; wp _ NARROW[Atom.GetProp[$ReportStreams, where]]; IF wp=NIL THEN RETURN[pd.sysOut]; s_wp.proc[wp.fixedWhereData, whereData]; IF s#NIL THEN RETURN[s]; RETURN[IF s#NIL THEN s ELSE IF wp.defaultIfNotFound=NIL OR wp.defaultIfNotFound[where, whereData] THEN pd.sysOut ELSE NIL]; }; Report: PUBLIC PROC[remark: ROPE, where: WhereToReport, whereData: REF _NIL] = { reportS: STREAM _ FindWhere[where, whereData]; IF remark=NIL OR reportS = NIL THEN RETURN; reportS.PutF["%t %s\n", time[], rope[remark]]; -- wish I could affort looking up caller. }; Problem: PUBLIC PROC[ remark: ROPE, where: WhereToReport, whereData: REF] = TRUSTED { IF remark=NIL THEN remark_"Unspecified problem"; Report[remark, where, whereData]; IF pd.attended THEN AMEvents.CallDebugger[remark]; }; ProblemBool: PUBLIC PROC[ remark: ROPE, where: WhereToReport, bool: BOOL, whereData: REF] RETURNS[sameBool: BOOL] = { sameBool_bool; Problem[remark, where, whereData]; }; <<>> ProblemHandle: PUBLIC PROC[ remark: ROPE, where: WhereToReport, handle: ThHandle, whereData: REF] RETURNS[sameHandle: ThHandle] = { sameHandle_handle; Problem[remark, where, whereData]; }; CmdWhere: WhereProc = { pl: Atom.PropList _ ProcessProps.GetPropList[]; ch: Commander.Handle; IF pl=NIL THEN RETURN[NIL]; ch _ NARROW[Commander.GetProperty[$CommanderHandle, pl]]; IF ch=NIL THEN RETURN[NIL]; RETURN[ch.err]; }; SetAttended: Commander.CommandProc = { pd.attended _ TRUE; Report["Attended[TRUE]", $Cmd, NIL]; }; ClearAttended: Commander.CommandProc = { pd.attended _ FALSE; Report["Attended[FALSE]", $Cmd, NIL]; }; <<>> <> loggingGroups: PUBLIC CARDINAL_0; WriteData: PUBLIC PROC[info: Log.LogInfo] = TRUSTED { <> }; DoLog: PUBLIC PROC[groups: CARDINAL_177777B] = { loggingGroups_ IF PrincOpsUtils.IsBound[SpyLog.WriteTrace] THEN groups ELSE 0; }; Noop: PUBLIC PROC = {NULL}; <> <> <<>> CLog: TYPE = Log.CLog; MakeCLog: PUBLIC PROC[fileName: ROPE, CommandProc: PROC[CLog]_NIL] RETURNS[cLog: CLog_NIL] = { logStream: IO.STREAM; logStream _ FS.StreamOpen[fileName: fileName, accessOptions: $append! FS.Error => logStream_NIL]; IF logStream=NIL THEN RETURN[NIL]; cLog_NEW[Log.CLogBody_[logStream: logStream, CommandProc: CommandProc]]; logStream.SetIndex[0]; }; WriteCLog: PUBLIC ENTRY PROC[cLog: CLog, entry: ROPE] = { WriteLog[cLog, entry]; }; WriteLog: INTERNAL PROC[cLog: CLog, entry: ROPE] = { cLog.logStream.SetIndex[cLog.logReadPos_cLog.logStream.GetLength[]]; cLog.logStream.PutRope[entry]; cLog.logStream.Flush[]; }; DoCLog: PUBLIC ENTRY PROC[cLog: CLog, entry: ROPE] = { WriteLog[cLog, entry]; cLog.logStream.SetIndex[cLog.logReadPos]; cLog.CommandProc[cLog]; }; RedoCLog: PUBLIC ENTRY PROC[cLog: CLog] = { cLog.logStream.SetIndex[cLog.logReadPos_0]; UNTIL IO.EndOf[cLog.logStream] DO cLog.CommandProc[cLog]; ENDLOOP; }; <> <<>> pd.ch _ NARROW[Commander.GetProperty[$CommanderHandle, ProcessProps.GetPropList[]]]; IF pd.ch#NIL THEN { pd.sysIn _ pd.ch.in; pd.sysOut _ pd.ch.out; }; RegisterWhereToReport[CmdWhere, $Cmd, NIL, NIL]; Commander.Register["Attended", SetAttended, "Break on errors"]; Commander.Register["Unattended", ClearAttended, "Log on errors, then muddle on."]; }.