home *** CD-ROM | disk | FTP | other *** search
- unit Logger;
- (*===================================================================*\
- || MODULE NAME: Logger ||
- || DEPENDENCIES: System, Dos ||
- || LAST MOD ON: 9102.11 ||
- || PROGRAMMER: Naoto Kimura ||
- || ||
- || This is an attempt to try to make a unit that will allow me ||
- || create a log of the input and output without having to ||
- || reimplement the CRT unit. ||
- || ||
- || REFERENCE ||
- || MATERIALS: Turbo Pascal User's Manual ||
- || Borland International ||
- || INTERRUP.LST text file obtained through UseNet ||
- || Ralf Brown (ralf@cs.cmu.edu) ||
- \*===================================================================*)
- interface
-
- uses dos;
-
- implementation
-
- {$F+}
- type
- LogRec = record
- Unused : array [1..8] of byte;
- LogFileRec : ^TextRec;
- OldInOutFunc : pointer
- end;
-
- (*-------------------------------------------------------------------*\
- | The following is used for performing an indirect call to an I/O |
- | routine used by the text file driver. |
- \*-------------------------------------------------------------------*)
- {$IFDEF VER40}
- const
- IndirectAddr : pointer = NIL;
-
- {static far} function PerformIO (var f : TextRec) : integer;
- inline($FF/$1E/IndirectAddr); {CALL [IndirectAddr]}
- {$ELSE}
- type
- IOfunction = function (var f : TextRec) : integer;
- {$ENDIF}
-
- (*-------------------------------------------------------------------*\
- | NAME: OutputToLog |
- | |
- | This private routine is used to output stuff to the log file. |
- | |
- | EXTERNALS: type registers (Dos), TextRec (Dos) |
- \*-------------------------------------------------------------------*)
- {static} procedure OutputToLog(
- var f : TextRec;
- var Dat : pointer;
- Len : word );
- var
- i : word;
- result : integer;
- begin
- with f do begin
- i := 0;
- while i < Len do begin
- if BufPos >= BufSize then begin
- {$IFDEF VER40}
- IndirectAddr := InOutFunc;
- result := PerformIO(f);
- {$ELSE}
- result := IOfunction(InOutFunc)(f)
- {$ENDIF}
- end;
- BufPtr^[BufPos] := TextBuf(Dat^)[i];
- inc(BufPos);
- inc(i)
- end;
- if f.BufPos >= f.BufSize then begin
- {$IFDEF VER40}
- IndirectAddr := InOutFunc;
- result := PerformIO(f)
- {$ELSE}
- result := IOfunction(f.InOutFunc)(f)
- {$ENDIF}
- end
- end
- end; (* OutputToLog *)
-
- (*-------------------------------------------------------------------*\
- | NAME: LogOutput |
- | |
- | This is the routine to send output to both the standard output |
- | handle and the log file. This procedure is only used if logging |
- | is to be performed. |
- | |
- | EXTERNALS: type registers (Dos), TextRec (Dos) |
- \*-------------------------------------------------------------------*)
- {static far} function LogOutput(var f : TextRec) : integer;
- const
- NumChrs : word = 0;
- result : integer = 0;
- begin
- with f,LogRec(UserData) do begin
- NumChrs := BufPos;
- {$IFDEF VER40}
- IndirectAddr := OldInOutFunc;
- result := PerformIO(f);
- {$ELSE}
- result := IOfunction(OldInOutFunc)(f);
- {$ENDIF}
- OutputToLog(LogFileRec^,pointer(BufPtr),NumChrs)
- end;
- LogOutput := result
- end; (* LogOutput *)
-
- (*-------------------------------------------------------------------*\
- | NAME: LogInput |
- | |
- | This is the routine that handles input in the Logger unit. It |
- | calls the original input routine to perform input, then calls the |
- | appropriate routine to log input to the log file. |
- | |
- | EXTERNALS: type registers (Dos), TextRec (Dos) |
- \*-------------------------------------------------------------------*)
- {static far} function LogInput (var f : TextRec) : integer;
- var
- result : integer;
- begin
- with f,LogRec(UserData) do begin
- {$IFDEF VER40}
- IndirectAddr := OldInOutFunc;
- result := PerformIO(f);
- {$ELSE}
- result := IOfunction(OldInOutFunc)(f);
- {$ENDIF}
- OutputToLog(LogFileRec^,pointer(BufPtr),BufEnd)
- end;
- LogInput := Result
- end; (* LogInput *)
-
- (*-------------------------------------------------------------------*\
- | NAME: LogIgnore |
- | |
- | This routine is used to perform a do-nothing function, usually for |
- | don't care conditions that may occur during I/O. This is an |
- | internal service routine and will not be directly used by any |
- | procedure outside of this unit. |
- | |
- | EXTERNALS: type TextRec (Dos) |
- \*-------------------------------------------------------------------*)
- {static far} function LogIgnore(var f : TextRec) : integer;
- begin
- LogIgnore := 0
- end; (* LogIgnore *)
-
-
- (*-------------------------------------------------------------------*\
- | NAME: OpenLogging |
- | |
- \*-------------------------------------------------------------------*)
- function OpenLogging(var f : TextRec) : integer;
- begin
- with TextRec(f),LogRec(UserData) do begin
- if Mode = fmInput then begin
- InOutFunc := @LogInput;
- FlushFunc := @LogIgnore
- end
- else begin
- Mode := fmOutput;
- InOutFunc := @LogOutput;
- FlushFunc := @LogOutput
- end
- end;
- OpenLogging := 0
- end; (* OpenLogging *)
-
- (*-------------------------------------------------------------------*\
- | NAME: CloseLogging |
- | |
- \*-------------------------------------------------------------------*)
- function CloseLogging(var f : TextRec) : integer;
- begin
- CloseLogging := 0
- end; (* CloseLogging *)
-
- (*-------------------------------------------------------------------*\
- | NAME: AssignLogging |
- | |
- \*-------------------------------------------------------------------*)
- procedure AssignLogging(
- var IO_File,
- LogFile : text);
- begin
- with TextRec(IO_File) do begin
- Mode := fmClosed;
- BufSize := SizeOf(Buffer);
- BufPtr := @Buffer;
- OpenFunc := @OpenLogging;
- with LogRec(UserData) do begin
- LogFileRec := @TextRec(LogFile);
- OldInOutFunc := InOutFunc;
- end;
- end
- end; (* AssignLogging *)
-
- var
- LogFile : text;
- OldExitProc : Pointer;
-
- {static far} procedure Cleanup;
- begin
- ExitProc := OldExitProc;
- close(LogFile)
- end;
-
- const
- DefaultAns = 'S';
- CopyRight : array [1..224] of char = (
- ^M,^J,#201,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #187,^M,^J,#186,' ','L','O','G','G','E','R',' ',' ',' ',' ',
- ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
- ' ',' ',' ',' ',' ','C','o','p','y','r','i','g','h','t',' ',
- '0','2','/','1','1','/','1','9','9','1',' ','(','c',')',' ',
- ' ','N','a','o','t','o',' ','K','i','m','u','r','a',' ',
- #186,^M,^J,#200,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,#205,
- #205,#205,#188,^M,^J );
-
- Choices : array [1..165] of char = (
- ^M,^J,' ','S','e','l','e','c','t',' ','o','n','e',' ','o','f',
- ' ','t','h','e',' ','f','o','l','l','o','w','i','n','g',':',^M,
- ^J,^M,^J,' ',' ',' ',' ',' ',' ','S',' ',' ',' ',' ',' ',' ',
- 's','c','r','e','e','n',' ','o','n','l','y',^M,^J,' ',' ',' ',
- ' ',' ',' ','P',' ',' ',' ',' ',' ',' ','s','c','r','e','e',
- 'n',' ','a','n','d',' ','p','r','i','n','t','e','r',^M,^J,' ',
- ' ',' ',' ',' ',' ','F',' ',' ',' ',' ',' ',' ','s','c','r',
- 'e','e','n',' ','a','n','d',' ','f','i','l','e',^M,^J,^M,^J,
- ' ',' ','P','l','e','a','s','e',' ','e','n','t','e','r',' ',
- 's','e','l','e','c','t','i','o','n',' ','(','d','e','f','a',
- 'u','l','t','=',DefaultAns,')',' ',':',' ' );
-
- FilePrompt : array [1..26] of char = (
- ^M,^J,' ',' ','E','n','t','e','r',' ','L','o','g',' ','f','i',
- 'l','e',' ','n','a','m','e',' ',':',' ' );
-
- ErrMsgBeg : array [1..25] of char = (
- ^M,^J,^G,'C','a','n','n','o','t',' ','w','r','i','t','e',' ',
- 't','o',' ','f','i','l','e',' ','"' );
- ErrMsgEnd : array [1..30] of char = (
- '"','!',' ',' ','N','o',' ','l','o','g','g','i','n','g',' ',
- 'w','i','l','l',' ','b','e',' ','d','o','n','e','.',^M,^J );
-
- StartMsg : array [1..32] of char = (
- ^M,^J,'-','-',' ','P','r','o','g','r','a','m',' ','e','x','e',
- 'c','u','t','i','o','n',' ','b','e','g','i','n','s',' ','-','-'
- );
-
- var
- StdCon : text;
- LogFileName : string;
- Choice : char;
- DoLogging : boolean;
-
- begin
- assign(StdCon,'con'); reset(StdCon);
- inline( $B8/$4000/ { mov ax,4000H }
- $BB/$02/$00/ { mov bx,StdErr }
- $B9/$E0/$00/ { mov cx,CopyRightLen }
- $BA/CopyRight/ { mov dx,OFFSET CopyRight }
- $CD/$21); { int 21h }
- repeat
- inline( $B8/$4000/ { mov ax,4000H }
- $BB/$02/$00/ { mov bx,StdErr }
- $B9/$A5/$00/ { mov cx,ChoicesLen }
- $BA/Choices/ { mov dx,OFFSET Choices }
- $CD/$21); { int 21h }
- if not (eoln(StdCon) or eof(StdCon)) then
- readln(StdCon,Choice)
- else begin
- Choice := DefaultAns;
- if not eof(StdCon) then readln(StdCon)
- end
- until Choice in ['S','s','P','p','F','f'];
- case Choice of
- 'S','s':DoLogging := FALSE;
- 'P','p':begin
- LogFileName := 'LPT1';
- DoLogging := TRUE;
- end;
- 'F','f':begin
- inline( $B8/$4000/ { mov ax,4000H }
- $BB/$02/$00/ { mov bx,StdErr }
- $B9/$1A/$00/ { mov cx,FilePrompt }
- $BA/FilePrompt/ { mov dx,OFFSET FilePrompt }
- $CD/$21); { int 21h }
- DoLogging := not SeekEoln(StdCon);
- readln(StdCon,LogFileName)
- end
- end;
- if DoLogging then begin
- assign(LogFile,LogFileName);
- {$I-}
- rewrite(LogFile);
- {$I+}
- if IOresult <> 0 then begin
- inline( $B8/$4000/ { mov ax,4000H }
- $BB/$02/$00/ { mov bx,StdErr }
- $B9/$19/$00/ { mov cx,ErrMsgBeg }
- $BA/ErrMsgBeg/ { mov dx,OFFSET ErrMsgBeg }
- $CD/$21/ { int 21h }
- {;-- Write file name }
- $B8/$4000/ { mov ax,4000H }
- $BB/$02/$00/ { mov bx,StdErr }
- $BA/LogFileName/ { mov dx,OFFSET LogFileName}
- $8B/$FA/ { mov di,dx }
- $33/$C9/ { xor cx,cx }
- $8A/$0D/ { mov cx,[di] }
- $42/ { inc dx }
- $CD/$21/ { int 21h }
- {;-- Finish err msg }
- $B8/$4000/ { mov ax,4000H }
- $BB/$02/$00/ { mov bx,StdErr }
- $B9/$1E/$00/ { mov cx,ErrMsgEnd }
- $BA/ErrMsgEnd/ { mov dx,OFFSET ErrMsgEnd }
- $CD/$21) { int 21h }
- end
- else begin
- OldExitProc := ExitProc;
- ExitProc := @Cleanup;
- AssignLogging( input, LogFile );
- reset(input);
- AssignLogging( output, LogFile );
- rewrite(output)
- end
- end;
- inline( $B8/$4000/ { mov ax,4000H }
- $BB/$02/$00/ { mov bx,StdErr }
- $B9/$20/$00/ { mov cx,StartMsgLen }
- $BA/StartMsg/ { mov dx,OFFSET StartMsg }
- $CD/$21); { int 21h }
- close(StdCon)
- end.
-