home *** CD-ROM | disk | FTP | other *** search
- {$B-,D-,F-,I-,L+,N-,R-,S-,T-,V-} {TP4 directives}
-
- Unit GetFns; {functions}
- {
- Uses routines by Richard Sadowsky (Tools v1.0) and Jim LeMay (Maxmin)
- }
- Interface
-
- Uses Dos;
-
-
- Type
-
- edit =
-
- (help, {help!}
- other, {not a valid command, don't do anything}
- escapefrom, {escape}
- goto_top, {cursor to top of file}
- goto_bottom, {cursor to end file}
- leftchar, {cursor left one character}
- rightchar, {cursor right one character}
- upchar, {accept string as is and exit with current cursor pos}
- downchar, { as above }
- scrollup, {scroll display up}
- scrolldown, {scroll display down}
- pageup, {page display up}
- pagedown, {page display down}
- abort, {abandon edits, restore original string}
- exit_screen, {}
- quit, {}
- oops, {undo edits}
- reset, {reset: relax validation e.g.}
- tabover, {tab}
- tabback, {tab back}
- goto_start, {cursor to the start of the string}
- goto_end, {cursor to the end of the string}
- carriage_return, {accept string and exit with cursor set to position 1}
- enter_default, {enter default value if there is one}
- insert_line, {insert a line}
- leftword, {cursor left one word}
- rightword, {cursor right one word}
- backspace, {delete character to the left}
- del_char, {delete character under the cursor}
- del_to_start, {delete to the beginning of the line}
- del_to_end, {delete to the end of the line}
- del_line, {delete the line}
- del_word, {delete the next word}
- del_block, {delete block, e.g. date field = block of 3 fields}
- restore_block, {block equivalent of oops}
- toggle_mode, {toggle between insert and overwrite modes}
- post_letter); {enter a letter in the string}
-
-
- screen_text = string[255];
- numstring = string[40];
-
- Str3 = String[3]; {RS}
- Str80 = String[80]; {"}
- Path = String[70]; {"}
-
-
- Const
-
- maxword = 65535; {maxlongint and maxint already defined}
- maxbyte = 255;
- maxshortint = 127;
- billion = 1000000000;
-
- strminlongint = '-2147483648';
- strmaxlongint = '2417483647';
-
- _EQUAL_ = 0; {RSadowsky}
-
- Alt_A = $011E; Alt_B = $0130; Alt_C = $012E; Alt_D = $0120; Alt_E = $0112;
- Alt_F = $0121; Alt_G = $0122; Alt_H = $0123; Alt_I = $0117; Alt_J = $0124;
- Alt_K = $0125; Alt_L = $0126; Alt_M = $0132; Alt_N = $0131; Alt_O = $0118;
- Alt_P = $0119; Alt_Q = $0110; Alt_R = $0113; Alt_S = $011F; Alt_T = $0114;
- Alt_U = $0116; Alt_V = $012F; Alt_W = $0111; Alt_X = $012D; Alt_Y = $0115;
- Alt_Z = $012C;
-
- UpKey = $0148; DownKey = $0150;
- LeftKey = $014B; RightKey = $014D;
- Ctrl_LeftKey = $0173; Ctrl_RightKey = $0174;
- InsKey = $0152; DelKey = $0153;
- HomeKey = $0147; EndKey = $014F;
- PgUpKey = $0149; PgDnKey = $0151;
- Ctrl_HomeKey = $0177; Ctrl_EndKey = $0175;
- Ctrl_PgUpKey = $0184; Ctrl_PgDnKey = $0176;
-
- F1 = $013B; F2 = $013C; F3 = $013D; F4 = $013E; F5 = $013F;
- F6 = $0140; F7 = $0141; F8 = $0142; F9 = $0143; F10= $0144;
-
- Shift_F1 = $0154; Shift_F2 = $0155; Shift_F3 = $0156; Shift_F4 = $0157;
- Shift_F5 = $0158; Shift_F6 = $0159; Shift_F7 = $015A; Shift_F8 = $015B;
- Shift_F9 = $015C; Shift_F10= $015D;
-
- Alt_F1 = $0168; Alt_F2 = $0169; Alt_F3 = $016A; Alt_F4 = $016B;
- Alt_F5 = $016C; Alt_F6 = $016D; Alt_F7 = $016E; Alt_F8 = $016F;
- Alt_F9 = $0170; Alt_F10= $0171;
-
- Ctrl_F1 = $015E; Ctrl_F2 = $015F; Ctrl_F3 = $0160; Ctrl_F4 = $0161;
- Ctrl_F5 = $0162; Ctrl_F6 = $0163; Ctrl_F7 = $0164; Ctrl_F8 = $0165;
- Ctrl_F9 = $0166; Ctrl_F10= $0167;
-
-
- Var
-
- action: edit;
-
- asciicode,
- scancode: byte;
- command: word absolute asciicode;
-
- ExtendedKey, { Returns true if last key was extended false if not }
- ASCIIKey: Boolean; { Returns exactly opposite of ExtendedKey }
-
-
-
- function length_without_tears (message: screen_text; sentinel: char): byte;
- function get_edit (var cmd: word): edit;
- function trunk (number: real): longint;
- function powerof (number,power: integer): integer;
- function log (lnum: real): real; {log base 10}
- function reallog (number, base: real): real;
- function RoundTo (number: real; places: byte): real;
- function FracToInt (infrac: real; places: integer): longint;
- function IntToFrac (inint: integer): real;
- function digits (fingers: real): longint;
- procedure strval (var number: real; decimal_places: integer);
- function RealToString (inreal: real;decimal_places: integer): numstring;
- function StrLastChar (instr: string): char;
-
- {Jim LeMay's MaxMin functions}
-
- function MaxW (Value1,Value2: word): word;
- function MinW (Value1,Value2: word): word;
- function MaxI (Value1,Value2: integer): integer;
- function MinI (Value1,Value2: integer): integer;
- function MaxL (Value1,Value2: longint): longint;
- function MinL (Value1,Value2: longint): longint;
-
- { Neil Rubenking's function to pad a string with spaces }
-
- function PadString (s:string; n:byte):string;
-
- {Richard Sadowsky's tools}
-
- function UpperCase(S : String) : String;
-
- function CompMem(var Block1,Block2; Size : Word) : Word;
- {
- return 0 if Block1 and Block2 are equal for Size bytes
- if not equal, return the position of first non matching byte
- the first byte is considered to be 1
- }
-
- function ExpandTabs(var S : String) : String;
- { expands each tab into a single space. Used before parsing }
-
- function Trim(var S : String) : String;
- { FAST assembly language Trim routine, trims leading and trailing }
-
- function SearchBlock(var FindStr; FindSize : Word; var Block;
- BlockSize : Word) : Word;
- { generic Block search routine. Takes untyped VAR parameters }
-
- procedure ReplaceString(StrToFind,StrToRep : Str80; var S : String);
- { Finds StrToFind and replaces it with StrToRep in string S. }
- { ignores case when searching for the string to replace. }
-
- function RightStr(S : String; Number : Word) : String;
- { returns all characters to the right of character Number }
-
- function LeftStr(_S : String; Number : Word) : String;
- {
- returns all the characters from beginning of str to the
- character at position Number. A NULL string is returned if
- Number is Number = 0, _S = ''. If Number is greater than
- the length of _S then the entire string _S is returned.
- }
-
- function ParseWord(var S : String; DelimChar : Char) : String;
- { parses input string S up to the first occurance of DelimChar. }
- { The parsed string is returned, and chopped out of the string S}
- { see WordOnLine implementation for sample use of ParseWord }
-
- function WordOnLine(var The_Word,The_Line : String) : Boolean;
- { returns TRUE if The_Word appears on The_Line }
-
- function FileExt(PName : Path; Extension : Str3) : Path;
- { force a file extension }
-
- function InKey(var ScanCode : Byte) : Char;
- { return character and scancode with a single call }
-
- { adapted from David Bennett's extkey }
-
- function ExtendKey : Word;
- {
- Return ascii value and scan code; sets booleans ASCIIkey and ExtendedKey.
- If extendedkey: high byte returned with $01.
- }
-
- {PON's continuted}
-
- function StringIsBlank(blankstr: string): boolean;
-
- function TestBit (var bite: byte; bitnumber: byte): boolean;
- function ByteToStr (Bite: byte): string;
- function StrToByte (bitstr: string): byte;
-
- procedure SetBit (var bite: byte; bitnumber: byte);
- procedure ClearBit (var bite: byte; bitnumber: byte);
-
-
- procedure value
-
- (instr: numstring;
- var number: longint;
- maxvalue: longint;
- var code: integer);
-
- procedure real_value
-
- (instr: numstring;
- var number: real;
- var code: integer);
-
-
- Implementation
-
- { JLM's routine's}
-
- {$L MaxW.obj}
- function MaxW; external;
- {$L MinW.obj}
- function MinW; external;
-
- {$L MaxI.obj}
- function MaxI; external;
- {$L MinI.obj}
- function MinI; external;
-
- {$L MaxL.obj}
- function MaxL; external;
- {$L MinL.obj}
- function MinL; external;
-
- { end of JLM's code }
-
- {** R. Sadowsky's: }
-
- {$L UCASE.OBJ}
- {$L MEMCOMP.OBJ}
- {$L EXPTABS.OBJ}
- {$L TRIM.OBJ}
- {$L SEARCH.OBJ}
- {$L PARSE.OBJ}
- {$L INKEY.OBJ}
- {$L RIGHTSTR.OBJ}
- {$L LEFTSTR.OBJ}
-
- function UpperCase(S : String) : String; External;
-
- function CompMem(var Block1,Block2; Size : Word) : Word; External;
-
- function ExpandTabs(var S : String) : String; External;
-
- function Trim(var S : String) : String; External;
-
- function SearchBlock(var FindStr; FindSize : Word; var Block;
- BlockSize : Word) : Word; External;
-
- function ParseWord(var S : String; DelimChar : Char) : String; External;
-
- function InKey(var ScanCode : Byte) : Char; External;
-
- function RightStr(S : String; Number : Word) : String; External;
-
- function LeftStr(_S : String; Number : Word) : String; External;
-
- procedure ReplaceString(StrToFind,StrToRep : Str80; var S : String);
-
- var
- L,P : Word;
- SS : String; {scratch string }
- STF,STR : Str80;
-
- begin
- SS := UpperCase(S); {use the scratch string }
- STF := UpperCase(StrToFind);
- STR := UpperCase(StrToRep);
- L := Length(SS);
- P := SearchBlock(STF[1],Length(STF),SS[1],L);
-
- if P > 0 then begin
- Delete(S,P,Length(StrToFind));
- if Length(StrToRep) > 0 then
- Insert(StrToRep,S,P);
- end;
-
- end;
-
- function WordOnLine(var The_Word,The_Line : String) : Boolean;
- { returns TRUE if The_Word appears on The_Line }
-
- var
- S : String; {scratch string }
- Wrd : Str80; { the parsed word }
-
- begin
- S := Trim(The_Line);
- while Length(S) > 0 do begin
- Wrd := ParseWord(S,' ');
- S := Trim(S);
- if CompMem(Wrd,The_Word,
- Succ(Length(Wrd))) = _EQUAL_ then begin
- WordOnLine := TRUE;
- Exit;
- end;
- end;
- WordOnLine := FALSE;
- end;
-
- function FileExt(PName : Path; Extension : Str3) : Path;
-
- var
- Position,L : Word;
-
- PathName : Path;
-
- const
- Period : String[1] = '.';
-
- begin
- PathName := PName;
- Position := Pos(Period,PathName);
- if Position > 0 then begin
- L := Length(PathName);
- PathName[0] := Char(L - Succ(L - Position));
- end;
- FileExt := PathName + '.' + Extension;
- end;
-
- {** end of R. Sadowsky's **}
-
-
- function PadString (s:string; n:byte):string;
- begin
- if length(s) < n then
- fillchar(s[succ(length(s))], n-length(s), ' ');
- s[0] := chr(n);
- padstring := s;
- end;
-
-
- Function ExtendKey : Word;
- {
- David Bennett's extendkey modified to use Richard Sadowksy's inkey.
- }
- Var
- asciivalue: char;
- scanvalue: byte;
-
- begin
- asciivalue := inkey(scanvalue);
- extendedkey := (asciivalue = #0);
- asciikey := not extendedkey;
-
- if extendedkey then
- extendkey := $0100+Ord(scanvalue)
- else
- extendkey := Ord(asciivalue);
- end;
-
-
-
- function get_edit (var cmd: word): edit;
- {
- Given a command as input this function returns either the editing
- action to be taken or the character to be entered in a string.
- WordStar commands are supported, with the following extension:
-
- Delete to the beginning of the line/string: ^Q^H or ^Q<backspace>
- }
- var a: edit;
- begin
- if scancode = 0 then {not an extended key}
-
- case asciicode of
- $00 : a := quit;
- $01 : a := leftword; { ^A }
- $03 : a := pagedown; { ^C }
- $04 : a := rightchar; { ^D }
- $05 : a := upchar; { ^E }
- $06 : a := rightword; { ^F }
- $07 : a := del_char; { ^G }
- $08,$7F: a := backspace; { ^H }
- $09 : a := tabover; { ^I }
- $0A : a := enter_default; { ^J }
- $0D : a := carriage_return; { ^M }
- $0E : a := insert_line; { ^N }
- $10 : begin { ^P }
- {insert literal}
- cmd := extendkey;
- if scancode = 0 then
- a := post_letter
- else a := other;
- end;
- $11 : begin { ^Q }
- cmd := extendkey;
- case asciicode of
- $12,$72,52 : a := goto_top; { ^R, R, r }
- $03,$63,$43 : a := goto_bottom; { ^C, C, c }
- $13,$73,$53 : a := goto_start; { ^S, S, s }
- $04,$64,$44 : a := goto_end; { ^D, D, d }
- $0C,$6C,$4C : a := oops; { ^L, L, l }
- $19,$79,$59 : a := del_to_end; { ^Y, Y, y }
- $08,$7F : a := del_to_start; { ^H, del }
- else a := other;
- end; {case}
- end;
- $12 : a := pageup; { ^R }
- $13 : a := leftchar; { ^S }
- $14 : a := del_word; { ^T }
- $15 : a := oops; { ^U }
- $16 : a := toggle_mode; { ^V }
- $17 : a := scrolldown; { ^W }
- $18 : a := downchar; { ^X }
- $19 : a := del_line; { ^Y }
- $1A : a := scrollup; { ^Z }
- $1B : a := escapefrom; { ^[ <Esc> }
- else
- if (ord(asciicode) > 31) and (ord(asciicode) < 256) then
- a := post_letter
- else a := other;
- end {case}
-
- else {extended key}
-
- begin
-
- case asciicode of
- $3B: a := help; { F1-Help! }
- $0F: a := tabback; { shift tab }
- $52: a := toggle_mode; { Insert/Overwrite }
- $53: a := del_char; { Delete character }
- $73: a := leftword; { ctrl left arrow }
- $74: a := rightword; { ctrl right arrow }
- $77: a := goto_top; { ^home }
- $75: a := goto_bottom; { ^end }
- $47: a := goto_start; { home }
- $4F: a := goto_end; { end }
- $48: a := upchar; { up arrow }
- $50: a := downchar; { down arrow }
- $4B: a := leftchar; { left arrow }
- $4D: a := rightchar; { right arrow }
- $49: a := pageup; { PgUp }
- $51: a := pagedown; { PgDn }
- $84: a := scrollup; { Ctrl PgUp }
- $76: a := scrolldown; { Ctrl PgDn }
- $13: a := reset; { Alt-R }
- $15: a := del_block; { Alt-Y }
- $16: a := restore_block; { Alt-U }
- $2D: a := exit_screen; { Alt-X }
- else a := other
- end; {case}
-
- end;
-
- get_edit := a;
- end;
-
-
- function length_without_tears (message: screen_text; sentinel: char): byte;
- var I,J: byte;
- {
- Returns the length of a string minus sentinel characters
- }
- begin
- I := length(message);
- J := I;
- while I > 0 do
- begin
- if message[I] = sentinel then
- dec(J);
- dec(I);
- end;
- length_without_tears := J;
- end;
-
-
- function trunk (number: real): longint;
- {
- Replacement for built-in 'trunc' procedure which bombs if given -2147483648
- }
- begin
- if number <= pred(-maxlongint) then
- trunk := pred(-maxlongint)
- else if number >= maxlongint then
- trunk := maxlongint
- else trunk := trunc(number);
- end;
-
-
- function powerof (number,power: integer): integer;
- {
- Note: natural log of a negative number is undefined. Use error handler.
- Enable 1st IF clause if powerof is changed to return real numbers (and
- remove round from 1st ELSE clause).
- }
- begin
- {
- if power < 0 then
- powerof := 1 div powerof(number,abs(power))
- else
- }
- if power = 0 then
- powerof := 1
- else powerof := round(exp(power * ln(number)));
- end;
-
-
- function log (lnum: real): real;
- const e = 0.43429448191; {base 10 conversion constant}
- begin
- if lnum <= 0 then
- log := lnum { or use error handler }
- else log := ln(lnum) * e;
- end;
-
-
- function reallog (number, base: real): real;
- {
- Calculate log to any positive base other than 1.0
- }
- begin
- reallog := ln(number) / ln(base);
- end;
-
-
- function RoundTo (number: real; places: byte): real;
- {
- The built-in procedures Round or Trunc will do for converting a real to
- an integer. This procedure will round a real to a given number of places.
- }
- var I: integer;
- begin
- for I := 1 to abs(places) do
- if places > 0 then
- number := number * 10.0
- else number := number / 10.0;
-
- number := int(number + ord(number > 0) - 0.5);
-
- for I := 1 to abs(places) do
- if places > 0 then
- number := number / 10.0
- else number := number * 10.0;
-
- RoundTo := number;
- end;
-
-
- function FracToInt (infrac: real;places: integer): longint;
- {
- Converts the decimal part (up to 10 places) of a real to an integer.
- Multiplying by 10 until the remainder is 0 doesn't work!
- }
- var outint: integer;
- fstr: numstring;
- negative: boolean;
-
- begin
- negative := infrac < 0;
- infrac := abs(frac(infrac));
-
- if not places in [0..10] then
- places := 10; {maxlongint is 10 long}
-
- str(infrac:0:places,fstr);
- delete(fstr,1,2); {remove '0.'}
-
- while(fstr[length(fstr)] = '0') do
- dec(ord(fstr[0])); {remove trailing 0s}
-
- outint := 0;
-
- while length(fstr) > 0 do
- begin
- outint := outint * 10 + ord(fstr[1]) - 48;
- delete(fstr,1,1);
- end;
-
- if negative then
- outint := -outint;
-
- FracToInt := outint;
- end;
-
-
- function IntToFrac (inint: integer): real;
- {
- Converts integer to decimal fraction, e.g. 247 to 0.247
- }
- var outfrac: real;
- begin
- outfrac := inint;
- while abs(int(outfrac)) > 0 do
- outfrac := outfrac / 10;
- IntToFrac := outfrac;
- end;
-
-
- function digits (fingers: real): longint;
- {
- Returns the number of digits in an integer, minus sign counts as one digit.
- Integer input expected. Type real of fingers is for log function.
- }
- var sign: integer;
- begin
- if fingers < 0 then
- sign := 1
- else sign := 0;
- if fingers = 0 then
- digits := 1 {sore thumb}
- else digits := sign + succ(trunk(int(log(abs(fingers)))));
- end;
-
-
- function StringIsBlank (blankstr: string): boolean;
- {
- Tests if a string is blank. String with just spaces is considered blank.
- }
- begin
- StringIsBlank := trim(blankstr) = '';
- end;
-
-
- function StrLastChar (instr: string): char;
- begin
- StrLastChar := instr[ord(instr[0])];
- end;
-
-
- function TestBit (var bite: byte; bitnumber: byte): boolean;
- {
- Tests a bit in a byte for true or false. Bits numbered 7 to 0.
- }
- begin
- TestBit := bite AND (1 SHL bitnumber) <> 0;
- end;
-
-
- procedure SetBit (var bite: byte; bitnumber: byte);
- begin
- bite := bite OR (1 SHL bitnumber);
- end;
-
-
- procedure ClearBit(var bite: byte; bitnumber: byte);
- begin
- bite := bite AND not (1 SHL bitnumber);
- end;
-
-
- function ByteToStr (bite: byte): string;
- var
- I,bit: byte;
- begin
- ByteToStr[0] := chr(8);
- I := 8;
- for bit := 0 to 7 do
- begin
- ByteToStr[I] := chr(48 + ord(Testbit(bite,bit)));
- dec(I);
- end;
- end;
-
-
- function StrToByte (bitstr: string): byte;
- {
- Packs a string of (0 to 8) 0s and 1s into a byte, right justified.
- }
- var I,J,strbyte: byte;
- begin
- strbyte := $0;
- I := ord(bitstr[0]);
- J := 0;
- while I > 0 do
- begin
- if bitstr[I] = '1' then
- setbit(strbyte,J);
- dec(I);
- inc(J);
- end;
- StrToByte := strbyte;
- end;
-
-
- procedure strval (var number: real; decimal_places: integer);
- {
- This procedure is used to ensure the arithmetic equivalence of numeric
- and string representations of real numbers.
- }
- var tempstr: numstring;
- width,
- code: integer;
- begin
-
- width := digits(number) + decimal_places;
- str(number:width:decimal_places,tempstr);
-
- str(number,tempstr);
- val(tempstr,number,code);
- end;
-
-
- function RealToString (inreal: real;decimal_places: integer): numstring;
- var rstring: numstring;
- begin
- str(inreal:digits(inreal):decimal_places,rstring);
- RealToString := rstring;
- end;
-
-
- procedure value
-
- (instr: numstring;
- var number: longint;
- maxvalue: longint;
- var code: integer);
- {
- Converts numeric string instr to number. Used by getnumber procedure (e.g.)
- Returns code = -1 if number is outside range for type implied by maxvalue
- }
- var minvalue: longint;
- triminstr: string;
- begin
- if (maxvalue = maxword) or (maxvalue = maxbyte) then
- minvalue := 0
- else minvalue := pred(- maxvalue);
-
- triminstr := instr;
- instr := trim(triminstr) ;
-
- if (instr = '') or (instr = '-') then
- instr := '0';
-
- if instr = strminlongint then {'-2147483648'}
- begin
- number := pred(-maxlongint);
- code := 0;
- end
- {needed because of TP4 val bug: converts to 0}
- else val(instr,number,code); {string -> number}
-
- if code = 0 then {range check for implied type}
- if (number < minvalue) or (number > maxvalue) then
- dec(code);
- end;
-
-
- procedure real_value
-
- (instr: numstring;
- var number: real;
- var code: integer);
- {
- Used to constrain size of reals. Checks that integer part of string
- real is within range for longint type. Decimal part expected to be
- zero if integer part is maxlongint or minlongint. Note number will
- be rounded by Turbo if attempt is made to exceed 11 digit precision
- of reals.
-
- anyreal := -214743647.99; write(anyreal:10:2); -> -2147483648.00
- }
- var value_number: longint;
- cutoff: integer;
- tmpinstr: numstring;
- begin
- value_number := trunk(number);
-
- if (instr = '') or (instr = '-') then
- instr := '0'; {for val}
- if StrLastChar(instr) = '.' then
- instr := instr + '0'; {also for val}
-
- cutoff := pos('.',instr);
- if cutoff = 0 then
- cutoff := length(instr)
- else dec(cutoff);
-
- tmpinstr := copy(instr,1,cutoff);
- value(tmpinstr,value_number,maxlongint,code);
- if code = 0 then
- val(instr,number,code);
- end;
-
-
- end. {unit}
-