379 lines
8.9 KiB
Plaintext
379 lines
8.9 KiB
Plaintext
|
|
|||
|
{ Copyright (c) 1989 by Borland International, Inc. }
|
|||
|
|
|||
|
unit TCUtil;
|
|||
|
{ Turbo Pascal 5.5 object-oriented example miscellaneous utility routines.
|
|||
|
This unit is used by TCALC.PAS.
|
|||
|
See TCALC.DOC for an more information about this example.
|
|||
|
}
|
|||
|
|
|||
|
{$S-}
|
|||
|
|
|||
|
interface
|
|||
|
|
|||
|
uses Crt, Dos;
|
|||
|
|
|||
|
const
|
|||
|
FreeListItems = 100; { Sets the size of the free list }
|
|||
|
Letters : set of Char = ['A'..'Z', 'a'..'z'];
|
|||
|
Numbers : set of Char = ['0'..'9'];
|
|||
|
ErrAbstractCall = 'Call to abstract method ';
|
|||
|
ErrNoMemory = 'Out of memory';
|
|||
|
NULL = 0;
|
|||
|
BS = 8;
|
|||
|
FF = 12;
|
|||
|
CR = 13;
|
|||
|
ESC = 27;
|
|||
|
F1 = 15104;
|
|||
|
F2 = 15360;
|
|||
|
F3 = 15616;
|
|||
|
F4 = 15872;
|
|||
|
F5 = 16128;
|
|||
|
F6 = 16384;
|
|||
|
F7 = 16640;
|
|||
|
F8 = 16896;
|
|||
|
F9 = 17152;
|
|||
|
F10 = 17408;
|
|||
|
AltF1 = 26624;
|
|||
|
AltF2 = 26880;
|
|||
|
AltF3 = 27136;
|
|||
|
AltF4 = 27392;
|
|||
|
AltF5 = 27648;
|
|||
|
AltF6 = 27904;
|
|||
|
AltF7 = 28160;
|
|||
|
AltF8 = 28416;
|
|||
|
AltF9 = 28672;
|
|||
|
AltF10 = 28928;
|
|||
|
HomeKey = 18176;
|
|||
|
UpKey = 18432;
|
|||
|
PgUpKey = 18688;
|
|||
|
LeftKey = 19200;
|
|||
|
RightKey = 19712;
|
|||
|
EndKey = 20224;
|
|||
|
DownKey = 20480;
|
|||
|
PgDnKey = 20736;
|
|||
|
InsKey = 20992;
|
|||
|
DelKey = 21248;
|
|||
|
CtrlLeftKey = 29440;
|
|||
|
CtrlRightKey = 29696;
|
|||
|
AltX = 11520;
|
|||
|
|
|||
|
type
|
|||
|
ProcPtr = procedure;
|
|||
|
StringPtr = ^String;
|
|||
|
WordPtr = ^Word;
|
|||
|
CharSet = set of Char;
|
|||
|
|
|||
|
procedure Abstract(Name : String);
|
|||
|
|
|||
|
function Compare(var P1, P2; Length : Word) : Boolean;
|
|||
|
|
|||
|
function GetKey : Word;
|
|||
|
|
|||
|
function GetKeyUpCase : Word;
|
|||
|
|
|||
|
function GetKeyChar(Legal : CharSet) : Char;
|
|||
|
|
|||
|
procedure Abort(Message : String);
|
|||
|
|
|||
|
procedure Beep;
|
|||
|
|
|||
|
function FileExists(F : String) : Boolean;
|
|||
|
|
|||
|
function Min(N1, N2 : Longint) : Longint;
|
|||
|
|
|||
|
function Max(N1, N2 : Longint) : Longint;
|
|||
|
|
|||
|
function NumToString(N : Longint) : String;
|
|||
|
|
|||
|
function UpperCase(S : String) : String;
|
|||
|
|
|||
|
function FillString(Len : Byte; Ch : Char) : String;
|
|||
|
|
|||
|
function TruncStr(TString : String; Len : Byte) : String;
|
|||
|
|
|||
|
function PadChar(PString : String; Ch : Char; Len : Byte) : String;
|
|||
|
|
|||
|
function CenterStr(S : String; Width : Byte) : String;
|
|||
|
|
|||
|
function LeftJustStr(S : String; Width : Byte) : String;
|
|||
|
|
|||
|
function RightJustStr(S : String; Width : Byte) : String;
|
|||
|
|
|||
|
function ColToString(Col : Word) : String;
|
|||
|
|
|||
|
function RowToString(Row : Word) : String;
|
|||
|
|
|||
|
function StringToCol(S : String; MaxCols : Word) : Word;
|
|||
|
|
|||
|
function StringToRow(S : String; MaxRows : Word) : Word;
|
|||
|
|
|||
|
procedure ClearInputBuffer;
|
|||
|
|
|||
|
implementation
|
|||
|
|
|||
|
const
|
|||
|
AbortMessage : String[80] = '';
|
|||
|
|
|||
|
var
|
|||
|
SavedExitProc : Pointer;
|
|||
|
|
|||
|
procedure Abstract(Name : String);
|
|||
|
{ Called by abstract methods which should never be executed. Aborts the
|
|||
|
program with an error message.
|
|||
|
}
|
|||
|
begin
|
|||
|
Abort(ErrAbstractCall + Name);
|
|||
|
end; { Abstract }
|
|||
|
|
|||
|
{$L TCCOMPAR}
|
|||
|
|
|||
|
function Compare(var P1, P2; Length : Word) : Boolean; external;
|
|||
|
{ Compares two areas of memory - see TCCOMPAR.ASM for the source }
|
|||
|
|
|||
|
function GetKey : Word;
|
|||
|
{ Returns the value of a key that was pressed - handles extended characters
|
|||
|
(function keys, etc.) by treating all characters as words.
|
|||
|
}
|
|||
|
var
|
|||
|
Ch : Char;
|
|||
|
begin
|
|||
|
Ch := ReadKey;
|
|||
|
if Ord(Ch) = NULL then { Extended character }
|
|||
|
GetKey := Word(Ord(ReadKey)) shl 8
|
|||
|
else
|
|||
|
GetKey := Ord(Ch); { Normal character }
|
|||
|
end; { GetKey }
|
|||
|
|
|||
|
function GetKeyUpCase : Word;
|
|||
|
{ Returns the upper case equivalent of a character from the keyboard }
|
|||
|
var
|
|||
|
Ch : Word;
|
|||
|
begin
|
|||
|
Ch := GetKey;
|
|||
|
if (Ch >= Ord(' ')) and (Ch <= Ord('~')) then
|
|||
|
GetKeyUpCase := Ord(UpCase(Chr(Ch))) { Change the character's case }
|
|||
|
else
|
|||
|
GetKeyUpCase := Ch; { Leave the character alone }
|
|||
|
end; { GetKeyUpCase }
|
|||
|
|
|||
|
function GetKeyChar(Legal : CharSet) : Char;
|
|||
|
{ Reads an ASCII key from the keyboard, only accepting keys in Legal }
|
|||
|
var
|
|||
|
Ch : Word;
|
|||
|
begin
|
|||
|
repeat
|
|||
|
Ch := GetKeyUpCase;
|
|||
|
until (Ch = ESC) or (Chr(Lo(Ch)) in Legal);
|
|||
|
GetKeyChar := Chr(Lo(Ch));
|
|||
|
end; { GetKeyChar }
|
|||
|
|
|||
|
procedure Abort(Message : String);
|
|||
|
{ Aborts the program with an error message }
|
|||
|
begin
|
|||
|
AbortMessage := Message;
|
|||
|
Halt(1);
|
|||
|
end; { Abort }
|
|||
|
|
|||
|
procedure Beep;
|
|||
|
{ Produces a low beep on the speaker }
|
|||
|
begin
|
|||
|
Sound(220);
|
|||
|
Delay(300);
|
|||
|
NoSound;
|
|||
|
end; { Beep }
|
|||
|
|
|||
|
function FileExists(F : String) : Boolean;
|
|||
|
{ Checks to see if a selected file exists }
|
|||
|
var
|
|||
|
SR : SearchRec;
|
|||
|
begin
|
|||
|
FindFirst(F, AnyFile, SR);
|
|||
|
FileExists := DosError = 0;
|
|||
|
end; { FileExists }
|
|||
|
|
|||
|
function Min(N1, N2 : Longint) : Longint;
|
|||
|
{ Returns the smaller of two numbers }
|
|||
|
begin
|
|||
|
if N1 <= N2 then
|
|||
|
Min := N1
|
|||
|
else
|
|||
|
Min := N2;
|
|||
|
end; { Min }
|
|||
|
|
|||
|
function Max(N1, N2 : Longint) : Longint;
|
|||
|
{ Returns the larger of two numbers }
|
|||
|
begin
|
|||
|
if N1 >= N2 then
|
|||
|
Max := N1
|
|||
|
else
|
|||
|
Max := N2;
|
|||
|
end; { Max }
|
|||
|
|
|||
|
function NumToString(N : Longint) : String;
|
|||
|
{ Converts a number to a string }
|
|||
|
var
|
|||
|
S : String[80];
|
|||
|
begin
|
|||
|
Str(N, S);
|
|||
|
NumToString := S;
|
|||
|
end; { NumToString }
|
|||
|
|
|||
|
function UpperCase(S : String) : String;
|
|||
|
{ Returns an all-upper case version of a string }
|
|||
|
var
|
|||
|
Counter : Word;
|
|||
|
begin
|
|||
|
for Counter := 1 to Length(S) do
|
|||
|
S[Counter] := UpCase(S[Counter]);
|
|||
|
UpperCase := S;
|
|||
|
end; { UpperCase }
|
|||
|
|
|||
|
function FillString(Len : Byte; Ch : Char) : String;
|
|||
|
var
|
|||
|
S : String;
|
|||
|
begin
|
|||
|
S[0] := Chr(Len);
|
|||
|
FillChar(S[1], Len, Ch);
|
|||
|
FillString := S;
|
|||
|
end; { FillString }
|
|||
|
|
|||
|
function TruncStr(TString : String; Len : Byte) : String;
|
|||
|
{ Truncates a string to a specified length }
|
|||
|
begin
|
|||
|
if Length(TString) > Len then
|
|||
|
Delete(TString, Succ(Len), Length(TString) - Len);
|
|||
|
TruncStr := TString;
|
|||
|
end; { TruncStr }
|
|||
|
|
|||
|
function PadChar(PString : String; Ch : Char; Len : Byte) : String;
|
|||
|
{ Pads a string to a specified length with a specified character }
|
|||
|
var
|
|||
|
CurrLen : Byte;
|
|||
|
begin
|
|||
|
CurrLen := Min(Length(PString), Len);
|
|||
|
PString[0] := Chr(Len);
|
|||
|
FillChar(PString[Succ(CurrLen)], Len - CurrLen, Ch);
|
|||
|
PadChar := PString;
|
|||
|
end; { PadChar }
|
|||
|
|
|||
|
function CenterStr(S : String; Width : Byte) : String;
|
|||
|
{ Center a string within a certain width }
|
|||
|
begin
|
|||
|
S := LeftJustStr(LeftJustStr('', (Width - Length(S)) shr 1) + S, Width);
|
|||
|
CenterStr := S;
|
|||
|
end; { CenterStr }
|
|||
|
|
|||
|
function LeftJustStr(S : String; Width : Byte) : String;
|
|||
|
{ Left-justify a string within a certain width }
|
|||
|
begin
|
|||
|
LeftJustStr := PadChar(S, ' ', Width);
|
|||
|
end; { LeftJustStr }
|
|||
|
|
|||
|
function RightJustStr(S : String; Width : Byte) : String;
|
|||
|
{ Right-justify a string within a certain width }
|
|||
|
begin
|
|||
|
S := TruncStr(S, Width);
|
|||
|
RightJustStr := LeftJustStr('', Width - Length(S)) + S;
|
|||
|
end; { RightJustStr }
|
|||
|
|
|||
|
function ColToString(Col : Word) : String;
|
|||
|
{ Converts a column to a string }
|
|||
|
var
|
|||
|
S : String[4];
|
|||
|
W : Word;
|
|||
|
begin
|
|||
|
if Col > 18278 then { Column is 4 letters }
|
|||
|
S := Chr(Ord('A') + ((Col - 18279) div 17576))
|
|||
|
else
|
|||
|
S := '';
|
|||
|
if Col > 702 then { Column is at least 3 letters }
|
|||
|
S := S + Chr(Ord('A') + (((Col - 703) mod 17576) div 676));
|
|||
|
if Col > 26 then { Column is at least 2 letters }
|
|||
|
S := S + Chr(Ord('A') + (((Col - 27) mod 676) div 26));
|
|||
|
S := S + Chr(Ord('A') + (Pred(Col) mod 26));
|
|||
|
ColToString := S;
|
|||
|
end; { ColToString }
|
|||
|
|
|||
|
function RowToString(Row : Word) : String;
|
|||
|
{ Converts a row to a string }
|
|||
|
begin
|
|||
|
RowToString := NumToString(Row);
|
|||
|
end; { RowToString }
|
|||
|
|
|||
|
function StringToCol(S : String; MaxCols : Word) : Word;
|
|||
|
{ Converts a string to a column }
|
|||
|
var
|
|||
|
L : Byte;
|
|||
|
C : Longint;
|
|||
|
begin
|
|||
|
StringToCol := 0; { Return 0 by default to indicate a bad column }
|
|||
|
L := Length(S);
|
|||
|
if L = 0 then
|
|||
|
Exit;
|
|||
|
S := UpperCase(S);
|
|||
|
for C := 1 to L do
|
|||
|
begin
|
|||
|
if not (S[C] in Letters) then { Bad letter - return }
|
|||
|
Exit;
|
|||
|
end;
|
|||
|
C := Ord(S[L]) - Ord(Pred('A'));
|
|||
|
if L > 1 then
|
|||
|
Inc(C, (Ord(S[Pred(L)]) - Ord(Pred('A'))) * 26);
|
|||
|
if L > 2 then
|
|||
|
Inc(C, (Ord(S[L - 2]) - Ord(Pred('A'))) * 676);
|
|||
|
if L > 3 then
|
|||
|
Inc(C, Longint(Ord(S[L - 3]) - Ord(Pred('A'))) * 17576);
|
|||
|
if C > MaxCols then
|
|||
|
Exit;
|
|||
|
StringToCol := C; { Successful - return column string }
|
|||
|
end; { StringToCol }
|
|||
|
|
|||
|
function StringToRow(S : String; MaxRows : Word) : Word;
|
|||
|
{ Converts a string to a Rown }
|
|||
|
var
|
|||
|
R : Longint;
|
|||
|
Error : Integer;
|
|||
|
begin
|
|||
|
StringToRow := 0; { Return 0 by default to indicate a bad row }
|
|||
|
if S = '' then
|
|||
|
Exit;
|
|||
|
Val(S, R, Error);
|
|||
|
if (Error = 0) and (R <= MaxRows) then
|
|||
|
StringToRow := R;
|
|||
|
end; { StringToRow }
|
|||
|
|
|||
|
procedure ClearInputBuffer;
|
|||
|
{ Clears the keyboard buffer }
|
|||
|
var
|
|||
|
Ch : Char;
|
|||
|
begin
|
|||
|
while KeyPressed do
|
|||
|
Ch := ReadKey;
|
|||
|
end; { ClearInputBuffer }
|
|||
|
|
|||
|
{$F+}
|
|||
|
|
|||
|
function UtilHeapError(Size : Word) : Integer;
|
|||
|
{ Simple heap error handler - returns a nil pointer if allocation was not
|
|||
|
successful }
|
|||
|
begin
|
|||
|
UtilHeapError := 1;
|
|||
|
end; { UtilHeapError }
|
|||
|
|
|||
|
procedure UtilExit;
|
|||
|
{ Called on exit to print abort message and restore exit procedure }
|
|||
|
begin
|
|||
|
if AbortMessage <> '' then
|
|||
|
Writeln(AbortMessage + '.');
|
|||
|
ExitProc := SavedExitProc;
|
|||
|
end; { UtilExit }
|
|||
|
|
|||
|
{$F-}
|
|||
|
|
|||
|
begin
|
|||
|
SavedExitProc := ExitProc;
|
|||
|
HeapError := @UtilHeapError;
|
|||
|
ExitProc := @UtilExit;
|
|||
|
end.
|
|||
|
|