DIRECTORY AMTypes USING [ TV ], Basics USING [ BITAND ], Commander USING [ Handle ], IO USING [ STREAM, Value ], Rope USING [ ROPE ] ; Log: CEDAR DEFINITIONS IMPORTS Basics = { PD: TYPE = RECORD [ attended: BOOLEAN_FALSE, sysIn: IO.STREAM, sysOut: IO.STREAM, -- IOs for error and system status reporting ch: Commander.Handle_NIL ]; pd: REF PD; ROPE: TYPE=Rope.ROPE; Text: TYPE = RECORD [ t: SEQUENCE maxLength: CARDINAL OF CHAR ]; LogInfo: TYPE = RECORD[ logCode: ATOM_NIL, logD1: LONG CARDINAL_0, logD2: LONG CARDINAL_0 ]; loggingGroups: CARDINAL; LOG: PROC[group: CARDINAL_1, info: LogInfo_[]] = TRUSTED INLINE { IF Basics.BITAND[group, loggingGroups]#0 THEN { WriteData[info]; Here[]; }; }; SLOG: PROC[group: CARDINAL_1] = TRUSTED INLINE { IF Basics.BITAND[group, Log.loggingGroups]#0 THEN { Noop[]; Here[]; }; }; WriteData: PROC[info: LogInfo]; Noop: PROC; Here: PROC; DoLog: PROC[groups: CARDINAL_177777B]; WhereToReport: TYPE=ATOM; ThHandle: TYPE = LONG CARDINAL -- Thrush.ThHandle --; nullHandle: ThHandle = 0; WhereProc: TYPE = PROC[fixedWhereData: REF, whereData: REF] RETURNS[s: IO.STREAM_NIL]; DNFProc: TYPE = PROC[fixedWhereData: REF, whereData: REF] RETURNS[default: BOOL]; RegisterWhereToReport: PROC[ proc: WhereProc_NIL, where: WhereToReport, fixedWhereData: REF_NIL, defaultIfNotFound: DNFProc_NIL]; FindWhere: PROC[where: WhereToReport, whereData: REF] RETURNS [s: IO.STREAM_NIL]; Report: PROC[remark: ROPE, where: WhereToReport_NIL, whereData: REF _NIL]; ReportFR: PROC[remark: ROPE, where: WhereToReport_NIL, whereData: REF _NIL, a1, a2: IO.Value _ [rope[NIL]]]; Problem: PROC[ remark: ROPE_NIL, where: WhereToReport_NIL, whereData: REF _NIL]; ProblemFR: PROC[ remark: ROPE_NIL, where: WhereToReport_NIL, whereData: REF _NIL, a1, a2: IO.Value _ [rope[NIL]]]; ProblemBool: PROC[remark: ROPE_NIL, where: WhereToReport_NIL, bool: BOOL_FALSE, whereData: REF_NIL] RETURNS[sameBool: BOOL]; ProblemHandle: PROC[remark: ROPE_NIL, where: WhereToReport_NIL, handle: ThHandle _ nullHandle, whereData: REF_NIL] RETURNS[sameHandle: ThHandle]; CLog: TYPE = REF CLogBody; CLogBody: TYPE = RECORD [ logStream: IO.STREAM, logReadPos: INT_0, CommandProc: PROC[CLog] ]; MakeCLog: PROC[fileName: ROPE, CommandProc: PROC[CLog], new: BOOL_FALSE, keep: CARDINAL_2] RETURNS[cLog: CLog]; WriteCLog: PROC[cLog: CLog, entry: ROPE]; CloseCLog: PROC[cLog: CLog] RETURNS[nullCLog: CLog]; DoCLog: PROC[cLog: CLog, entry: ROPE]; RedoCLog: PROC[cLog: CLog]; GetBinding: PROC[qualifiedName: ROPE] RETURNS [tv: AMTypes.TV]; GetBindingToProc: PROC[qualifiedProcName: ROPE] RETURNS [proc: PROC ANY RETURNS ANY]; }. ŽLog.mesa Last modified by D. Swinehart, June 16, 1984 4:58:50 pm PDT Logging of errors and status reports; Spying for performance measurement Variables Types Error, Information, Performance Logging Error reporting and management Report finds an appropriate stream and prints a time-stamped version of remark. Clients can register procedures to interpret the WhereToReport atoms and obtain the appropriate stream for a given call, aided by the lead supplied in the Report call. Problem is intended for reporting unexpected errors and conditions. It will raise the indicated signal, or an internal one by default, if the system is currently attended (there's an executive command.) In any case, it will report the remark argument. It will return automatically or if the operator proceeds from the signal, so the caller needs to do what is necessary to recover after calling Problem. The other Problem... functions are for convenience in returning innocuous values from procedures. The defaultIfNotFound parameter to the registration procedure indicates whether the message should be ignored (FALSE) or printed (TRUE) when the corresponding stream-finding procedure returns NIL. IF defaultIfNotFound=NIL, answer assumed TRUE Command Logging, indirect execution. Originally developed as part of ThMessageDBImpl CommandProc should consume any command in the log, such that if it's the last command, we're at end of file Write it at end, then read it and do it, using CommandProc Typical thing to do after a MakeCLog, to replay an old one. Dynamic "IsBound"; applies to procedures only. qualifiedName is either Interface.variable or Program.variable. Returns NIL if the Interface, Program, or variable is undefined. Assumes global context. I suppose there's a way to speed it up by looking for top level. qualifiedProcName is either Interface.Proc or Program.Proc. Returns NIL if the Interface, Program, or Proc is undefined. ÊߘJšœ™Jšœ;™;J˜JšœH™HJ˜šÏk ˜ Jšœœœ˜Jšœœœ˜Jšœ œ ˜Jšœœœ ˜Jšœœœ˜J˜J˜—Jšœœ œœ ˜)J˜šÏc ™ J˜šœœœ˜Jšœ œœ˜Jšœœœ˜Jšœœœž-˜@Jšœ˜J˜—Jšœœœ˜ J˜—™J˜Jšœœœ˜šœœœ˜Jšœœ œœ˜'J˜—J˜—™'J˜šœ œœ˜Jšœ œœ˜Jšœœœ˜Jšœœœ˜Jšœ˜J˜—Jšœœ˜š œœœœœ˜Ašœœœ˜/Jšœ˜——š œœœœœ˜0šœœœ˜3Jšœ˜——J˜JšÏn œœ˜JšŸœœ˜ JšŸœœ˜ JšŸœœ œ ˜&J˜™Jš ŸœBŸœ4Ÿ œHŸœŸœ™øJšŸœæŸœ›Ÿœ™–Jšœ Ÿ œM™aJšœÏbœYœœ:™Ä—J˜Jšœœœ˜Jš œ œœœžœ˜5J˜JšŸ œœœœ œœœœœ˜VJšŸœœœœ œœ œ˜QšŸœœ˜Jš œœ(œœœ˜dJšœœ™-—JšŸ œœ"œœœœœ˜QJ˜Jš Ÿœœ œœ œœ˜Jš Ÿœœ œœ œœ˜KJšœœœ˜ —J˜šŸœœ˜Jš œœœœ œœ˜A—šŸ œœ˜š œœœœ œœ˜@Jšœœœ˜!——š Ÿ œœ œœœ˜>Jš œœœ œœ˜%Jšœ œ˜—š Ÿ œœ œœœ˜?Jšœ*œœ˜2Jšœ˜—J˜—J™$™/J™Jšœœœ ˜šœ œœ˜Jšœ œœ˜Jšœ œ˜šŸ œœ˜J™MJ™—J˜—J˜šŸœœ œŸ œœ œœœ˜ZJšœ˜—J˜JšŸ œœœ˜)J˜JšŸ œœ œ˜4J˜šŸœœœ˜&J™:—J˜šŸœœ ˜J™;——J™™.š Ÿ œœœœœ˜?Jšœ?™?Jšœ@™@Jšœœ?™Y—J˜šŸœœœœœœœœ˜UJ™;J™<——J˜J˜—…— B¯