dos_compilers/Borland Turbo Pascal v6/DEMOS/TCALC/TCUTIL.PAS
2024-07-02 07:11:05 -07:00

379 lines
8.9 KiB
Plaintext

{ Copyright (c) 1989,90 by Borland International, Inc. }
unit TCUtil;
{ Turbo Pascal 6.0 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.