home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
PASCAL
/
NKTOOLS.ZIP
/
LOGGER.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-02-11
|
14KB
|
351 lines
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.