mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 07:31:49 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			1207 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			1207 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| {
 | ||
|     *********************************************************************
 | ||
|     $Id$
 | ||
|     Copyright (C) 1997, 1998 Gertjan Schouten
 | ||
| 
 | ||
|     This program is free software; you can redistribute it and/or modify
 | ||
|     it under the terms of the GNU General Public License as published by
 | ||
|     the Free Software Foundation; either version 2 of the License, or
 | ||
|     (at your option) any later version.
 | ||
| 
 | ||
|     This program is distributed in the hope that it will be useful,
 | ||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||
|     GNU General Public License for more details.
 | ||
| 
 | ||
|     You should have received a copy of the GNU General Public License
 | ||
|     along with this program; if not, write to the Free Software
 | ||
|     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | ||
|     *********************************************************************
 | ||
| 
 | ||
|     System Utilities For Free Pascal
 | ||
| }
 | ||
| 
 | ||
| {   NewStr creates a new PString and assigns S to it
 | ||
|     if length(s) = 0 NewStr returns Nil   }
 | ||
| 
 | ||
| function NewStr(const S: string): PString;
 | ||
| begin
 | ||
|   if (S='') then
 | ||
|    Result:=nil
 | ||
|   else
 | ||
|    begin
 | ||
|      getmem(Result,length(s)+1);
 | ||
|      if (Result<>nil) then
 | ||
|       Result^:=s;
 | ||
|    end;
 | ||
| end;
 | ||
| 
 | ||
| {   DisposeStr frees the memory occupied by S   }
 | ||
| 
 | ||
| procedure DisposeStr(S: PString);
 | ||
| begin
 | ||
|   if S <> Nil then
 | ||
|    begin
 | ||
|      Freemem(S,Length(S^)+1);
 | ||
|      S:=nil;
 | ||
|    end;
 | ||
| end;
 | ||
| 
 | ||
| {   AssignStr assigns S to P^   }
 | ||
| 
 | ||
| procedure AssignStr(var P: PString; const S: string);
 | ||
| begin
 | ||
|   P^ := s;
 | ||
| end ;
 | ||
| 
 | ||
| {   AppendStr appends S to Dest   }
 | ||
| 
 | ||
| procedure AppendStr(var Dest: String; const S: string);
 | ||
| begin
 | ||
| Dest := Dest + S;
 | ||
| end ;
 | ||
| 
 | ||
| {   UpperCase returns a copy of S where all lowercase characters ( from a to z )
 | ||
|     have been converted to uppercase   }
 | ||
| 
 | ||
| function UpperCase(const S: string): string;
 | ||
| var i: integer;
 | ||
| begin
 | ||
| result := S;
 | ||
| i := Length(S);
 | ||
| while i <> 0 do begin
 | ||
|    if (result[i] in ['a'..'z']) then result[i] := char(byte(result[i]) - 32);
 | ||
|    Dec(i);
 | ||
|    end;
 | ||
| end;
 | ||
| 
 | ||
| {   LowerCase returns a copy of S where all uppercase characters ( from A to Z )
 | ||
|     have been converted to lowercase  }
 | ||
| 
 | ||
| function LowerCase(const S: string): string;
 | ||
| var i: integer;
 | ||
| begin
 | ||
| result := S;
 | ||
| i := Length(result);
 | ||
| while i <> 0 do begin
 | ||
|    if (result[i] in ['A'..'Z']) then result[i] := char(byte(result[i]) + 32);
 | ||
|    dec(i);
 | ||
|    end;
 | ||
| end;
 | ||
| 
 | ||
| {   CompareStr compares S1 and S2, the result is the based on
 | ||
|     substraction of the ascii values of the characters in S1 and S2
 | ||
|     case     result
 | ||
|     S1 < S2  < 0
 | ||
|     S1 > S2  > 0
 | ||
|     S1 = S2  = 0     }
 | ||
| 
 | ||
| function CompareStr(const S1, S2: string): Integer;
 | ||
| var count, count1, count2: integer;
 | ||
| begin
 | ||
| result := 0;
 | ||
| Count1 := Length(S1);
 | ||
| Count2 := Length(S2);
 | ||
| if Count1 > Count2 then Count := Count2
 | ||
| else Count := Count1;
 | ||
| result := CompareMem(Pointer(S1),Pointer(S2), Count);
 | ||
| if (result = 0) and (Count1 <> Count2) then begin
 | ||
|    if Count1 > Count2 then result := ord(s1[Count1 + 1])
 | ||
|    else result := -ord(s2[Count2 + 1]);
 | ||
|    end ;
 | ||
| end ;
 | ||
| 
 | ||
| {   CompareMem returns the result of comparison of Length bytes at P1 and P2
 | ||
|     case       result
 | ||
|     P1 < P2    < 0
 | ||
|     P1 > P2    > 0
 | ||
|     P1 = P2    = 0    }
 | ||
| 
 | ||
| function CompareMem(P1, P2: Pointer; Length: cardinal): integer;
 | ||
| var i: integer;
 | ||
| begin
 | ||
| i := 0;
 | ||
| result := 0;
 | ||
| while (result = 0) and (i < length) do begin
 | ||
|    result := byte(P1^) - byte(P2^);
 | ||
|    P1 := P1 + 1;
 | ||
|    P2 := P2 + 1;
 | ||
|    i := i + 1;
 | ||
|    end ;
 | ||
| end ;
 | ||
| 
 | ||
| {   CompareText compares S1 and S2, the result is the based on
 | ||
|     substraction of the ascii values of characters in S1 and S2
 | ||
|     comparison is case-insensitive
 | ||
|     case     result
 | ||
|     S1 < S2  < 0
 | ||
|     S1 > S2  > 0
 | ||
|     S1 = S2  = 0     }
 | ||
| 
 | ||
| function CompareText(const S1, S2: string): integer;
 | ||
| var i, count, count1, count2: integer; Chr1, Chr2: byte;
 | ||
| begin
 | ||
| result := 0;
 | ||
| Count1 := Length(S1);
 | ||
| Count2 := Length(S2);
 | ||
| if Count1 > Count2 then Count := Count2
 | ||
| else Count := Count1;
 | ||
| i := 0;
 | ||
| while (result = 0) and (i < count) do begin
 | ||
|    inc (i);
 | ||
|    Chr1 := byte(s1[i]);
 | ||
|    Chr2 := byte(s2[i]);
 | ||
|    if Chr1 in [97..122] then dec(Chr1,32);
 | ||
|    if Chr2 in [97..122] then dec(Chr2,32);
 | ||
|    result := Chr1 - Chr2;
 | ||
|    end ;
 | ||
| if (result = 0) then
 | ||
|   result:=(count1-count2);
 | ||
| end ;
 | ||
| 
 | ||
| {==============================================================================}
 | ||
| {   Ansi string functions                                                      }
 | ||
| {   these functions rely on the character set loaded by the OS                 }
 | ||
| {==============================================================================}
 | ||
| 
 | ||
| 
 | ||
| function AnsiUpperCase(const s: string): string;
 | ||
| var len, i: integer;
 | ||
| begin
 | ||
| len := length(s);
 | ||
| SetLength(result, len);
 | ||
| for i := 1 to len do
 | ||
|    result[i] := UpperCaseTable[ord(s[i])];
 | ||
| end ;
 | ||
| 
 | ||
| function AnsiLowerCase(const s: string): string;
 | ||
| var len, i: integer;
 | ||
| begin
 | ||
| len := length(s);
 | ||
| SetLength(result, len);
 | ||
| for i := 1 to len do
 | ||
|    result[i] := LowerCaseTable[ord(s[i])];
 | ||
| end ;
 | ||
| 
 | ||
| function AnsiCompareStr(const S1, S2: string): integer;
 | ||
| 
 | ||
| Var I,L1,L2 : Longint;
 | ||
| 
 | ||
| begin
 | ||
|   Result:=0;
 | ||
|   L1:=Length(S1);
 | ||
|   L2:=Length(S2);
 | ||
|   I:=1;
 | ||
|   While (Result=0) and ((I<=L1) and (I<=L2)) do
 | ||
|     begin
 | ||
|     Result:=Ord(S1[I])-Ord(S2[I]); //!! Must be replaced by ansi characters !!
 | ||
|     Inc(I);
 | ||
|     end;
 | ||
|   If Result=0 Then
 | ||
|     Result:=L1-L2;
 | ||
| end;
 | ||
| 
 | ||
| function AnsiCompareText(const S1, S2: string): integer;
 | ||
| Var I,L1,L2 : Longint;
 | ||
| 
 | ||
| begin
 | ||
|   Result:=0;
 | ||
|   L1:=Length(S1);
 | ||
|   L2:=Length(S2);
 | ||
|   I:=1;
 | ||
|   While (Result=0) and ((I<=L1) and (I<=L2)) do
 | ||
|     begin
 | ||
|     Result:=Ord(LowerCaseTable[Ord(S1[I])])-Ord(LowerCaseTable[Ord(S2[I])]); //!! Must be replaced by ansi characters !!
 | ||
|     Inc(I);
 | ||
|     end;
 | ||
|   If Result=0 Then
 | ||
|     Result:=L1-L2;
 | ||
| end;
 | ||
| 
 | ||
| function AnsiStrComp(S1, S2: PChar): integer;
 | ||
| 
 | ||
| begin
 | ||
|   Result:=0;
 | ||
|   If S1=Nil then
 | ||
|     begin
 | ||
|     If S2=Nil Then Exit;
 | ||
|     result:=-1;
 | ||
|     end;
 | ||
|   If S2=Nil then
 | ||
|     begin
 | ||
|     Result:=1;
 | ||
|     exit;
 | ||
|     end;
 | ||
|   Repeat
 | ||
|     Result:=Ord(S1[0])-Ord(S2[0]); //!! Must be replaced by ansi characters !!
 | ||
|     Inc(S1);
 | ||
|     Inc(S2);
 | ||
|   Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0))
 | ||
| end;
 | ||
| 
 | ||
| function AnsiStrIComp(S1, S2: PChar): integer;
 | ||
| 
 | ||
| begin
 | ||
|   Result:=0;
 | ||
|   If S1=Nil then
 | ||
|     begin
 | ||
|     If S2=Nil Then Exit;
 | ||
|     result:=-1;
 | ||
|     end;
 | ||
|   If S2=Nil then
 | ||
|     begin
 | ||
|     Result:=1;
 | ||
|     exit;
 | ||
|     end;
 | ||
|   Repeat
 | ||
|     Result:=Ord(LowerCaseTable[Ord(S1[0])])-Ord(LowerCaseTable[Ord(S2[0])]); //!! Must be replaced by ansi characters !!
 | ||
|     Inc(S1);
 | ||
|     Inc(S2);
 | ||
|   Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0))
 | ||
| end;
 | ||
| 
 | ||
| function AnsiStrLComp(S1, S2: PChar; MaxLen: cardinal): integer;
 | ||
| 
 | ||
| Var I : longint;
 | ||
| 
 | ||
| begin
 | ||
|   Result:=0;
 | ||
|   If MaxLen=0 then exit;
 | ||
|   If S1=Nil then
 | ||
|     begin
 | ||
|     If S2=Nil Then Exit;
 | ||
|     result:=-1;
 | ||
|     end;
 | ||
|   If S2=Nil then
 | ||
|     begin
 | ||
|     Result:=1;
 | ||
|     exit;
 | ||
|     end;
 | ||
|   I:=0;
 | ||
|   Repeat
 | ||
|     Result:=Ord(S1[0])-Ord(S2[0]); //!! Must be replaced by ansi characters !!
 | ||
|     Inc(S1);
 | ||
|     Inc(S2);
 | ||
|     Inc(I);
 | ||
|   Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0)) or (I=MaxLen)
 | ||
| end ;
 | ||
| 
 | ||
| function AnsiStrLIComp(S1, S2: PChar; MaxLen: cardinal): integer;
 | ||
| 
 | ||
| Var I : longint;
 | ||
| 
 | ||
| begin
 | ||
|   Result:=0;
 | ||
|   If MaxLen=0 then exit;
 | ||
|   If S1=Nil then
 | ||
|     begin
 | ||
|     If S2=Nil Then Exit;
 | ||
|     result:=-1;
 | ||
|     end;
 | ||
|   If S2=Nil then
 | ||
|     begin
 | ||
|     Result:=1;
 | ||
|     exit;
 | ||
|     end;
 | ||
|   I:=0;
 | ||
|   Repeat
 | ||
|     Result:=Ord(LowerCaseTable[Ord(S1[0])])-Ord(LowerCaseTable[Ord(S2[0])]); //!! Must be replaced by ansi characters !!
 | ||
|     Inc(S1);
 | ||
|     Inc(S2);
 | ||
|     Inc(I);
 | ||
|   Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0)) or (I=MaxLen)
 | ||
| end ;
 | ||
| 
 | ||
| function AnsiStrLower(Str: PChar): PChar;
 | ||
| begin
 | ||
| result := Str;
 | ||
| if Str <> Nil then begin
 | ||
|    while Str^ <> #0 do begin
 | ||
|       Str^ := LowerCaseTable[byte(Str^)];
 | ||
|       Str := Str + 1;
 | ||
|       end ;
 | ||
|    end ;
 | ||
| end ;
 | ||
| 
 | ||
| function AnsiStrUpper(Str: PChar): PChar;
 | ||
| begin
 | ||
| result := Str;
 | ||
| if Str <> Nil then begin
 | ||
|    while Str^ <> #0 do begin
 | ||
|       Str^ := UpperCaseTable[byte(Str^)];
 | ||
|       Str := Str + 1;
 | ||
|       end ;
 | ||
|    end ;
 | ||
| end ;
 | ||
| 
 | ||
| function AnsiLastChar(const S: string): PChar;
 | ||
| 
 | ||
| begin
 | ||
|   //!! No multibyte yet, so we return the last one.
 | ||
|   result:=StrEnd(Pchar(S));
 | ||
|   Dec(Result);
 | ||
| end ;
 | ||
| 
 | ||
| function AnsiStrLastChar(Str: PChar): PChar;
 | ||
| begin
 | ||
|   //!! No multibyte yet, so we return the last one.
 | ||
|   result:=StrEnd(Str);
 | ||
|   Dec(Result);
 | ||
| end ;
 | ||
| 
 | ||
| {==============================================================================}
 | ||
| {  End of Ansi functions                                                       }
 | ||
| {==============================================================================}
 | ||
| 
 | ||
| {   Trim returns a copy of S with blanks characters on the left and right stripped off   }
 | ||
| 
 | ||
| function Trim(const S: string): string;
 | ||
| var Ofs, Len: integer;
 | ||
| begin
 | ||
|   len := Length(S);
 | ||
|   while (Len>0) and (S[Len] = ' ') do
 | ||
|    dec(Len);
 | ||
|   Ofs := 1;
 | ||
|   while (Ofs<=Len) and (S[Ofs] = ' ') do
 | ||
|    Inc(Ofs);
 | ||
|   result := Copy(S, Ofs, 1 + Len - Ofs);
 | ||
| end ;
 | ||
| 
 | ||
| {   TrimLeft returns a copy of S with all blank characters on the left stripped off  }
 | ||
| 
 | ||
| function TrimLeft(const S: string): string;
 | ||
| var i,l:integer;
 | ||
| begin
 | ||
|   l := length(s);
 | ||
|   i := 1;
 | ||
|   while (i<=l) and (s[i] = ' ') do
 | ||
|    inc(i);
 | ||
|   Result := copy(s, i, l);
 | ||
| end ;
 | ||
| 
 | ||
| {   TrimRight returns a copy of S with all blank characters on the right stripped off  }
 | ||
| 
 | ||
| function TrimRight(const S: string): string;
 | ||
| var l:integer;
 | ||
| begin
 | ||
|   l := length(s);
 | ||
|   while (l>0) and (s[l] = ' ') do
 | ||
|    dec(l);
 | ||
|   result := copy(s,1,l);
 | ||
| end ;
 | ||
| 
 | ||
| {   QuotedStr returns S quoted left and right and every single quote in S
 | ||
|     replaced by two quotes   }
 | ||
| 
 | ||
| function QuotedStr(const S: string): string;
 | ||
| begin
 | ||
| result := AnsiQuotedStr(s, '''');
 | ||
| end ;
 | ||
| 
 | ||
| {   AnsiQuotedStr returns S quoted left and right by Quote,
 | ||
|     and every single occurance of Quote replaced by two   }
 | ||
| 
 | ||
| function AnsiQuotedStr(const S: string; Quote: char): string;
 | ||
| var i, j, count: integer;
 | ||
| begin
 | ||
| result := '' + Quote;
 | ||
| count := length(s);
 | ||
| i := 0;
 | ||
| j := 0;
 | ||
| while i < count do begin
 | ||
|    i := i + 1;
 | ||
|    if S[i] = Quote then begin
 | ||
|       result := result + copy(S, 1 + j, i - j) + Quote;
 | ||
|       j := i;
 | ||
|       end ;
 | ||
|    end ;
 | ||
| if i <> j then
 | ||
|    result := result + copy(S, 1 + j, i - j);
 | ||
| result := result + Quote;
 | ||
| end ;
 | ||
| 
 | ||
| {   AnsiExtractQuotedStr returns a copy of Src with quote characters
 | ||
|     deleted to the left and right and double occurances
 | ||
|     of Quote replaced by a single Quote   }
 | ||
| 
 | ||
| function AnsiExtractQuotedStr(Const Src: PChar; Quote: Char): string;
 | ||
| var i: integer; P, Q: PChar;
 | ||
| begin
 | ||
| P := Src;
 | ||
| if Src^ = Quote then P := P + 1;
 | ||
| Q := StrEnd(P);
 | ||
| if PChar(Q - 1)^ = Quote then Q := Q - 1;
 | ||
| SetLength(result, Q - P);
 | ||
| i := 0;
 | ||
| while P <> Q do begin
 | ||
|    i := i + 1;
 | ||
|    result[i] := P^;
 | ||
|    if (P^ = Quote) and (PChar(P + 1)^ = Quote) then
 | ||
|       P := P + 1;
 | ||
|    P := P + 1;
 | ||
|    end ;
 | ||
| SetLength(result, i);
 | ||
| end ;
 | ||
| 
 | ||
| {   AdjustLineBreaks returns S with all CR characters not followed by LF
 | ||
|     replaced with CR/LF  }
 | ||
| //  under Linux all CR characters or CR/LF combinations should be replaced with LF
 | ||
| 
 | ||
| function AdjustLineBreaks(const S: string): string;
 | ||
| var i, j, count: integer;
 | ||
| begin
 | ||
| result := '';
 | ||
| i := 0;
 | ||
| j := 0;
 | ||
| count := Length(S);
 | ||
| while i < count do begin
 | ||
|    i := i + 1;
 | ||
| {$ifndef linux}
 | ||
|    if (S[i] = #13) and ((i = count) or (S[i + 1] <> #10)) then
 | ||
|      begin
 | ||
|      result := result + Copy(S, 1 + j, i - j) + #10;
 | ||
|      j := i;
 | ||
|      end;
 | ||
| {$else}
 | ||
|    If S[i]=#13 then
 | ||
|      begin
 | ||
|      Result:= Result+Copy(S,J+1,i-j-1)+#10;
 | ||
|      If I<>Count Then
 | ||
|        If S[I+1]=#10 then inc(i);
 | ||
|      J :=I;
 | ||
|      end;
 | ||
| {$endif}
 | ||
|    end ;
 | ||
| if j <> i then
 | ||
|    result := result + copy(S, 1 + j, i - j);
 | ||
| end ;
 | ||
| 
 | ||
| {   IsValidIdent returns true if the first character of Ident is in:
 | ||
|     'A' to 'Z', 'a' to 'z' or '_' and the following characters are
 | ||
|     on of: 'A' to 'Z', 'a' to 'z', '0'..'9' or '_'    }
 | ||
| 
 | ||
| function IsValidIdent(const Ident: string): boolean;
 | ||
| var i, len: integer;
 | ||
| begin
 | ||
| result := false;
 | ||
| len := length(Ident);
 | ||
| if len <> 0 then begin
 | ||
|    result := Ident[1] in ['A'..'Z', 'a'..'z', '_'];
 | ||
|    i := 1;
 | ||
|    while (result) and (i < len) do begin
 | ||
|       i := i + 1;
 | ||
|       result := result and (Ident[i] in ['A'..'Z', 'a'..'z', '0'..'9', '_']);
 | ||
|       end ;
 | ||
|    end ;
 | ||
| end ;
 | ||
| 
 | ||
| {   IntToStr returns a string representing the value of Value    }
 | ||
| 
 | ||
| function IntToStr(Value: integer): string;
 | ||
| begin
 | ||
| System.Str(Value, result);
 | ||
| end ;
 | ||
| 
 | ||
| {   IntToHex returns a string representing the hexadecimal value of Value   }
 | ||
| 
 | ||
| const
 | ||
|    HexDigits: array[0..15] of char = '0123456789ABCDEF';
 | ||
| 
 | ||
| function IntToHex(Value: integer; Digits: integer): string;
 | ||
| var i: integer;
 | ||
| begin
 | ||
| SetLength(result, digits);
 | ||
| for i := 0 to digits - 1 do begin
 | ||
|    result[digits - i] := HexDigits[value and 15];
 | ||
|    value := value shr 4;
 | ||
|    end ;
 | ||
| end ;
 | ||
| 
 | ||
| {   StrToInt converts the string S to an integer value,
 | ||
|     if S does not represent a valid integer value EConvertError is raised  }
 | ||
| 
 | ||
| function StrToInt(const S: string): integer;
 | ||
| 
 | ||
| var Error: word;
 | ||
| 
 | ||
| begin
 | ||
|   Val(S, result, Error);
 | ||
|   if Error <> 0 then raise EConvertError.createfmt(SInValidInteger,[S]);
 | ||
| end ;
 | ||
| 
 | ||
| {   StrToIntDef converts the string S to an integer value,
 | ||
|     Default is returned in case S does not represent a valid integer value  }
 | ||
| 
 | ||
| function StrToIntDef(const S: string; Default: integer): integer;
 | ||
| var Error: word;
 | ||
| begin
 | ||
| Val(S, result, Error);
 | ||
| if Error <> 0 then result := Default;
 | ||
| end ;
 | ||
| 
 | ||
| {   LoadStr returns the string resource Ident.   }
 | ||
| 
 | ||
| function LoadStr(Ident: integer): string;
 | ||
| begin
 | ||
|   result:='';
 | ||
| end ;
 | ||
| 
 | ||
| {   FmtLoadStr returns the string resource Ident and formats it accordingly   }
 | ||
| 
 | ||
| 
 | ||
| function FmtLoadStr(Ident: integer; const Args: array of const): string;
 | ||
| begin
 | ||
|   result:='';
 | ||
| end;
 | ||
| 
 | ||
| Const
 | ||
|   feInvalidFormat   = 1;
 | ||
|   feMissingArgument = 2;
 | ||
|   feInvalidArgIndex = 3;
 | ||
| 
 | ||
| Procedure Log (Const S: String);
 | ||
| 
 | ||
| begin
 | ||
|  {$ifdef debug}
 | ||
|  Writeln (S);
 | ||
|  {$endif}
 | ||
| end;
 | ||
| 
 | ||
| Procedure DoFormatError (ErrCode : Longint);
 | ||
| 
 | ||
| Var S : String;
 | ||
| 
 | ||
| begin
 | ||
|   //!! must be changed to contain format string...
 | ||
|   S:='';
 | ||
|   Case ErrCode of
 | ||
|    feInvalidFormat : raise EConvertError.Createfmt(SInvalidFormat,[s]);
 | ||
|    feMissingArgument : raise EConvertError.Createfmt(SArgumentMissing,[s]);
 | ||
|    feInvalidArgIndex : raise EConvertError.Createfmt(SInvalidArgIndex,[s]);
 | ||
|  end;
 | ||
| end;
 | ||
| 
 | ||
| 
 | ||
| Function Format (Const Fmt : String; const Args : Array of const) : String;
 | ||
| 
 | ||
| Var ChPos,OldPos,ArgPos,DoArg,Len : Longint;
 | ||
|     Hs,ToAdd : String;
 | ||
|     Index,Width,Prec : Longint;
 | ||
|     Left : Boolean;
 | ||
|     Fchar : char;
 | ||
| 
 | ||
|   {
 | ||
|     ReadFormat reads the format string. It returns the type character in
 | ||
|     uppercase, and sets index, Width, Prec to their correct values,
 | ||
|     or -1 if not set. It sets Left to true if left alignment was requested.
 | ||
|     In case of an error, DoFormatError is called.
 | ||
|   }
 | ||
| 
 | ||
|   Function ReadFormat : Char;
 | ||
| 
 | ||
|   Var Value : longint;
 | ||
| 
 | ||
|     Procedure ReadInteger;
 | ||
| 
 | ||
|     Var Code : Word;
 | ||
| 
 | ||
|     begin
 | ||
|       If Value<>-1 then exit; // Was already read.
 | ||
|       OldPos:=chPos;
 | ||
|       While (Chpos<Len) and
 | ||
|             (Pos(Fmt[chpos],'1234567890')<>0) do inc(chpos);
 | ||
|       If Chpos=len then DoFormatError(feInvalidFormat);
 | ||
|       If Fmt[Chpos]='*' then
 | ||
|         begin
 | ||
|         If (Chpos>OldPos) or (ArgPos>High(Args))
 | ||
|            or (Args[ArgPos].Vtype<>vtInteger) then
 | ||
|           DoFormatError(feInvalidFormat);
 | ||
|         Value:=Args[ArgPos].VInteger;
 | ||
|         Inc(ArgPos);
 | ||
|         Inc(chPos);
 | ||
|         end
 | ||
|       else
 | ||
|         begin
 | ||
|         If (OldPos<chPos) Then
 | ||
|           begin
 | ||
|           Val (Copy(Fmt,OldPos,ChPos-OldPos),value,code);
 | ||
|           // This should never happen !!
 | ||
|           If Code>0 then DoFormatError (feInvalidFormat);
 | ||
|           end
 | ||
|         else
 | ||
|           Value:=-1;
 | ||
|         end;
 | ||
|     end;
 | ||
| 
 | ||
|     Procedure ReadIndex;
 | ||
| 
 | ||
|     begin
 | ||
|       ReadInteger;
 | ||
|       If Fmt[ChPos]=':' then
 | ||
|         begin
 | ||
|         If Value=-1 then DoFormatError(feMissingArgument);
 | ||
|         Index:=Value;
 | ||
|         Value:=-1;
 | ||
|         Inc(Chpos);
 | ||
|         end;
 | ||
|       Log ('Read index');
 | ||
|     end;
 | ||
| 
 | ||
|     Procedure ReadLeft;
 | ||
| 
 | ||
|     begin
 | ||
|       If Fmt[chpos]='-' then
 | ||
|         begin
 | ||
|         left:=True;
 | ||
|         Inc(chpos);
 | ||
|         end
 | ||
|       else
 | ||
|         Left:=False;
 | ||
|       Log ('Read Left');
 | ||
|     end;
 | ||
| 
 | ||
|     Procedure ReadWidth;
 | ||
| 
 | ||
|     begin
 | ||
|       ReadInteger;
 | ||
|       If Value<>-1 then
 | ||
|         begin
 | ||
|         Width:=Value;
 | ||
|         Value:=-1;
 | ||
|         end;
 | ||
|       Log ('Read width');
 | ||
|     end;
 | ||
| 
 | ||
|     Procedure ReadPrec;
 | ||
| 
 | ||
|     begin
 | ||
|       If Fmt[chpos]='.' then
 | ||
|         begin
 | ||
|         inc(chpos);
 | ||
|         ReadInteger;
 | ||
|         If Value=-1 then DoFormaterror(feMissingArgument);
 | ||
|         prec:=Value;
 | ||
|         end;
 | ||
|       Log ('Read precision');
 | ||
|     end;
 | ||
| 
 | ||
|   begin
 | ||
|     Log ('Start format');
 | ||
|     Index:=-1;
 | ||
|     Width:=-1;
 | ||
|     Prec:=-1;
 | ||
|     Value:=-1;
 | ||
|     inc(chpos);
 | ||
|     If Fmt[Chpos]='%' then exit('%');
 | ||
|     ReadIndex;
 | ||
|     ReadLeft;
 | ||
|     ReadWidth;
 | ||
|     ReadPrec;
 | ||
|     ReadFormat:=Upcase(Fmt[ChPos]);
 | ||
|     Log ('End format');
 | ||
| end;
 | ||
| 
 | ||
| Procedure DumpFormat (C : char);
 | ||
| 
 | ||
| begin
 | ||
|   Write ('Fmt : ',fmt:10);
 | ||
|   Write (' Index : ',Index:3);
 | ||
|   Write (' Left  : ',left:5);
 | ||
|   Write (' Width : ',Width:3);
 | ||
|   Write (' Prec  : ',prec:3);
 | ||
|   Writeln (' Type  : ',C);
 | ||
| end;
 | ||
| 
 | ||
| function Checkarg (AT : Longint;err:boolean):boolean;
 | ||
| {
 | ||
|   Check if argument INDEX is of correct type (AT)
 | ||
|   If Index=-1, ArgPos is used, and argpos is augmented with 1
 | ||
|   DoArg is set to the argument that must be used.
 | ||
| }
 | ||
| begin
 | ||
|   result:=false;
 | ||
|   if Index=-1 then
 | ||
|     begin
 | ||
|     DoArg:=Argpos;
 | ||
|     inc(ArgPos);
 | ||
|     end
 | ||
|   else
 | ||
|     DoArg:=Index;
 | ||
|   If (Doarg>High(Args)) or (Args[Doarg].Vtype<>AT) then
 | ||
|    begin
 | ||
|      if err then
 | ||
|       DoFormatError(feInvalidArgindex);
 | ||
|      dec(ArgPos);
 | ||
|      exit;
 | ||
|    end;
 | ||
|   result:=true;
 | ||
| end;
 | ||
| 
 | ||
| Const Zero = '000000000000000000000000000000000000000000000000000000000000000';
 | ||
| 
 | ||
| begin
 | ||
|   Result:='';
 | ||
|   Len:=Length(Fmt)+1;
 | ||
|   Chpos:=1;
 | ||
|   OldPos:=1;
 | ||
|   ArgPos:=0;
 | ||
|   While chpos<len do
 | ||
|     begin
 | ||
|     // uses shortcut evaluation !!
 | ||
|     While (ChPos<=Len) and (Fmt[chpos]<>'%') do inc(chpos);
 | ||
|     If ChPos>OldPos Then
 | ||
|       Result:=Result+Copy(Fmt,OldPos,Chpos-Oldpos);
 | ||
|     If ChPos<Len then
 | ||
|       begin
 | ||
|       FChar:=ReadFormat;
 | ||
|       {$ifdef debug}
 | ||
|       DumpFormat(FCHar);
 | ||
|       {$endif}
 | ||
|       Case FChar of
 | ||
|         'D' : begin
 | ||
|               Checkarg(vtinteger,true);
 | ||
|               Width:=Abs(width);
 | ||
|               Str(Args[Doarg].VInteger,ToAdd);
 | ||
|               While Length(ToAdd)<Prec do
 | ||
|                 begin
 | ||
|                 Index:=Prec-Length(ToAdd);
 | ||
|                 If Index>64 then Index:=64;
 | ||
|                 ToAdd:=Copy(Zero,1,Index)+ToAdd;
 | ||
|                 end;
 | ||
|               end;
 | ||
|         'E' : begin
 | ||
|               CheckArg(vtExtended,true);
 | ||
|               ToAdd:=FloatToStrF(Args[doarg].VExtended^,ffexponent,Prec,3);
 | ||
|               end;
 | ||
|         'F' : begin
 | ||
|               CheckArg(vtExtended,true);
 | ||
|               ToAdd:=FloatToStrF(Args[doarg].VExtended^,ffFixed,9999,Prec);
 | ||
|               end;
 | ||
|         'G' : begin
 | ||
|               CheckArg(vtExtended,true);
 | ||
|               ToAdd:=FloatToStrF(Args[doarg].VExtended^,ffGeneral,Prec,3);
 | ||
|               end;
 | ||
|         'N' : begin
 | ||
|               CheckArg(vtExtended,true);
 | ||
|               ToAdd:=FloatToStrF(Args[doarg].VExtended^,ffNumber,9999,Prec);
 | ||
|               end;
 | ||
|         'M' : begin
 | ||
|               CheckArg(vtExtended,true);
 | ||
|               ToAdd:=FloatToStrF(Args[doarg].VExtended^,ffCurrency,9999,Prec);
 | ||
|               end;
 | ||
|         'S' : begin
 | ||
|                 if CheckArg(vtString,false) then
 | ||
|                   hs:=Args[doarg].VString^
 | ||
|                 else
 | ||
|                   if CheckArg(vtPChar,false) then
 | ||
|                     hs:=Args[doarg].VPChar
 | ||
|                 else
 | ||
|                   if CheckArg(vtAnsiString,true) then
 | ||
|                     hs:=ansistring(Args[doarg].VAnsiString);
 | ||
|                 Index:=Length(hs);
 | ||
|                 If (Prec<>-1) and (Index>Prec) then
 | ||
|                   Index:=Prec;
 | ||
|                 ToAdd:=Copy(hs,1,Index);
 | ||
|               end;
 | ||
|         'P' : Begin
 | ||
|               CheckArg(vtpointer,true);
 | ||
|               ToAdd:=HexStr(Longint(Args[DoArg].VPointer),8);
 | ||
|               // Insert ':'. Is this needed in 32 bit ? No it isn't.
 | ||
|               // Insert(':',ToAdd,5);
 | ||
|               end;
 | ||
|         'X' : begin
 | ||
|               Checkarg(vtinteger,true);
 | ||
|               If Prec>15 then
 | ||
|                 ToAdd:=HexStr(Args[Doarg].VInteger,15)
 | ||
|               else
 | ||
|                 begin
 | ||
|                 // determine minimum needed number of hex digits.
 | ||
|                 Index:=1;
 | ||
|                 While (DWord(1 shl (Index*4))<DWord(Args[DoArg].VInteger)) and (index<8) do
 | ||
|                  inc(Index);
 | ||
|                 If Index>Prec then
 | ||
|                   Prec:=Index;
 | ||
|                 ToAdd:=HexStr(Args[DoArg].VInteger,Prec);
 | ||
|                 end;
 | ||
|               end;
 | ||
|         '%': ToAdd:='%';
 | ||
|       end;
 | ||
|       If Width<>-1 then
 | ||
|         If Length(ToAdd)<Width then
 | ||
|           If not Left then
 | ||
|             ToAdd:=Space(Width-Length(ToAdd))+ToAdd
 | ||
|           else
 | ||
|             ToAdd:=ToAdd+space(Width-Length(ToAdd));
 | ||
|       Result:=Result+ToAdd;
 | ||
|       end;
 | ||
|     inc(chpos);
 | ||
|     Oldpos:=chpos;
 | ||
|     end;
 | ||
| end;
 | ||
| 
 | ||
| Function FormatBuf (Var Buffer; BufLen : Cardinal;
 | ||
|                      Const Fmt; fmtLen : Cardinal;
 | ||
|                      Const Args : Array of const) : Cardinal;
 | ||
| 
 | ||
| Var S,F : String;
 | ||
| 
 | ||
| begin
 | ||
|   Setlength(F,fmtlen);
 | ||
|   Move(fmt,F[1],fmtlen);
 | ||
|   S:=Format (F,Args);
 | ||
|   If Length(S)>Buflen then
 | ||
|     Result:=Length(S)
 | ||
|   else
 | ||
|     Result:=Buflen;
 | ||
|   Move(S[1],Buffer,Result);
 | ||
| end;
 | ||
| 
 | ||
| Procedure FmtStr(Var Res: String; Const Fmt : String; Const args: Array of const);
 | ||
| 
 | ||
| begin
 | ||
|   Res:=Format(fmt,Args);
 | ||
| end;
 | ||
| 
 | ||
| Function StrFmt(Buffer,Fmt : PChar; Const args: Array of const) : Pchar;
 | ||
| 
 | ||
| begin
 | ||
|   Buffer[FormatBuf(Buffer^,Maxint,Fmt^,strlen(fmt),args)]:=#0;
 | ||
|   Result:=Buffer;
 | ||
| end;
 | ||
| 
 | ||
| Function StrLFmt(Buffer : PCHar; Maxlen : Cardinal;Fmt : PChar; Const args: Array of const) : Pchar;
 | ||
| 
 | ||
| begin
 | ||
|   Buffer[FormatBuf(Buffer^,MaxLen,Fmt^,strlen(fmt),args)]:=#0;
 | ||
|   Result:=Buffer;
 | ||
| end;
 | ||
| 
 | ||
| 
 | ||
| function StrToFloat(Value: string): Extended;
 | ||
| 
 | ||
| var Error: word;
 | ||
| 
 | ||
| begin
 | ||
|   Val(Value, result, Error);
 | ||
|   if Error <> 0 then raise
 | ||
|      EConvertError.createfmt(SInValidFLoat,[Value]);
 | ||
| end ;
 | ||
| 
 | ||
| Function FloatToStr(Value: Extended): String;
 | ||
| Begin
 | ||
|   Result := FloatToStrF(Value, ffGeneral, 15, 0);
 | ||
| End;
 | ||
| 
 | ||
| Function FloatToText(Buffer: PChar; Value: Extended; format: TFloatFormat; Precision, Digits: Integer): Longint;
 | ||
| Var
 | ||
|   Tmp: String[40];
 | ||
| Begin
 | ||
|   Tmp := FloatToStrF(Value, format, Precision, Digits);
 | ||
|   Result := Length(Tmp);
 | ||
|   Move(Tmp[1], Buffer[0], Result);
 | ||
| End;
 | ||
| 
 | ||
| 
 | ||
| Function FloatToStrF(Value: Extended; format: TFloatFormat; Precision, Digits: Integer): String;
 | ||
| Var
 | ||
|   P: Integer;
 | ||
|   Negative, TooSmall, TooLarge: Boolean;
 | ||
| 
 | ||
| 
 | ||
| Begin
 | ||
|   Case format Of
 | ||
| 
 | ||
|     ffGeneral:
 | ||
| 
 | ||
|       Begin
 | ||
|         If (Precision = -1) Or (Precision > 15) Then Precision := 15;
 | ||
|         TooSmall := (Abs(Value) < 0.00001) and (Value>0.0);
 | ||
|         If Not TooSmall Then
 | ||
|         Begin
 | ||
|           Str(Value:0:999, Result);
 | ||
|           P := Pos('.', Result);
 | ||
|           Result[P] := DecimalSeparator;
 | ||
|           TooLarge := P > Precision + 1;
 | ||
|         End;
 | ||
| 
 | ||
|         If TooSmall Or TooLarge Then
 | ||
|           begin
 | ||
|           Result := FloatToStrF(Value, ffExponent, Precision, Digits);
 | ||
|           // Strip unneeded zeroes.
 | ||
|           P:=Pos('E',result)-1;
 | ||
|           If P<>-1 then
 | ||
|              While (P>1) and (Result[P]='0') do
 | ||
|                begin
 | ||
|                system.Delete(Result,P,1);
 | ||
|                Dec(P);
 | ||
|                end;
 | ||
|           end
 | ||
|         else
 | ||
|           begin
 | ||
|           P := Length(Result);
 | ||
|           While Result[P] = '0' Do Dec(P);
 | ||
|           If Result[P] = DecimalSeparator Then Dec(P);
 | ||
|           SetLength(Result, P);
 | ||
|           end;
 | ||
|       End;
 | ||
| 
 | ||
|     ffExponent:
 | ||
| 
 | ||
|       Begin
 | ||
|         If (Precision = -1) Or (Precision > 15) Then Precision := 15;
 | ||
|         Str(Value:Precision + 8, Result);
 | ||
|         Result[3] := DecimalSeparator;
 | ||
|         P:=4;
 | ||
|         While (P>0) and (Digits < P) And (Result[Precision + 5] = '0') do
 | ||
|           Begin
 | ||
|           If P<>1 then
 | ||
|             system.Delete(Result, Precision + 5, 1)
 | ||
|           else
 | ||
|             system.Delete(Result, Precision + 3, 3);
 | ||
|           Dec(P);
 | ||
|           end;
 | ||
|         If Result[1] = ' ' Then
 | ||
|           System.Delete(Result, 1, 1);
 | ||
|       End;
 | ||
| 
 | ||
|     ffFixed:
 | ||
| 
 | ||
|       Begin
 | ||
|         If Digits = -1 Then Digits := 2
 | ||
|         Else If Digits > 15 Then Digits := 15;
 | ||
|         Str(Value:0:Digits, Result);
 | ||
|         If Result[1] = ' ' Then
 | ||
|           System.Delete(Result, 1, 1);
 | ||
|         P := Pos('.', Result);
 | ||
|         If P <> 0 Then Result[P] := DecimalSeparator;
 | ||
|       End;
 | ||
| 
 | ||
|     ffNumber:
 | ||
| 
 | ||
|       Begin
 | ||
|         If Digits = -1 Then Digits := 2
 | ||
|         Else If Digits > 15 Then Digits := 15;
 | ||
|         Str(Value:0:Digits, Result);
 | ||
|         If Result[1] = ' ' Then System.Delete(Result, 1, 1);
 | ||
|         P := Pos('.', Result);
 | ||
|         If P <> 0 Then Result[P] := DecimalSeparator;
 | ||
|         Dec(P, 3);
 | ||
|         While (P > 1) Do
 | ||
|         Begin
 | ||
|           If Result[P - 1] <> '-' Then Insert(ThousandSeparator, Result, P);
 | ||
|           Dec(P, 3);
 | ||
|         End;
 | ||
|       End;
 | ||
| 
 | ||
|     ffCurrency:
 | ||
| 
 | ||
|       Begin
 | ||
|         If Value < 0 Then
 | ||
|         Begin
 | ||
|           Negative := True;
 | ||
|           Value := -Value;
 | ||
|         End
 | ||
|         Else Negative := False;
 | ||
| 
 | ||
|         If Digits = -1 Then Digits := CurrencyDecimals
 | ||
|         Else If Digits > 18 Then Digits := 18;
 | ||
|         Str(Value:0:Digits, Result);
 | ||
|         If Result[1] = ' ' Then System.Delete(Result, 1, 1);
 | ||
|         P := Pos('.', Result);
 | ||
|         If P <> 0 Then Result[P] := DecimalSeparator;
 | ||
|         Dec(P, 3);
 | ||
|         While (P > 1) Do
 | ||
|         Begin
 | ||
|           Insert(ThousandSeparator, Result, P);
 | ||
|           Dec(P, 3);
 | ||
|         End;
 | ||
| 
 | ||
|         If Not Negative Then
 | ||
|         Begin
 | ||
|           Case CurrencyFormat Of
 | ||
|             0: Result := CurrencyString + Result;
 | ||
|             1: Result := Result + CurrencyString;
 | ||
|             2: Result := CurrencyString + ' ' + Result;
 | ||
|             3: Result := Result + ' ' + CurrencyString;
 | ||
|           End
 | ||
|         End
 | ||
|         Else
 | ||
|         Begin
 | ||
|           Case NegCurrFormat Of
 | ||
|             0: Result := '(' + CurrencyString + Result + ')';
 | ||
|             1: Result := '-' + CurrencyString + Result;
 | ||
|             2: Result := CurrencyString + '-' + Result;
 | ||
|             3: Result := CurrencyString + Result + '-';
 | ||
|             4: Result := '(' + Result + CurrencyString + ')';
 | ||
|             5: Result := '-' + Result + CurrencyString;
 | ||
|             6: Result := Result + '-' + CurrencyString;
 | ||
|             7: Result := Result + CurrencyString + '-';
 | ||
|             8: Result := '-' + Result + ' ' + CurrencyString;
 | ||
|             9: Result := '-' + CurrencyString + ' ' + Result;
 | ||
|             10: Result := CurrencyString + ' ' + Result + '-';
 | ||
|           End;
 | ||
|         End;
 | ||
|       End;
 | ||
|   End;
 | ||
| End;
 | ||
| 
 | ||
| {==============================================================================}
 | ||
| {   extra functions                                                            }
 | ||
| {==============================================================================}
 | ||
| 
 | ||
| {   LeftStr returns Count left-most characters from S }
 | ||
| 
 | ||
| function LeftStr(const S: string; Count: integer): string;
 | ||
| begin
 | ||
|   result := Copy(S, 1, Count);
 | ||
| end ;
 | ||
| 
 | ||
| { RightStr returns Count right-most characters from S }
 | ||
| 
 | ||
| function RightStr(const S: string; Count: integer): string;
 | ||
| begin
 | ||
|    If Count>Length(S) then
 | ||
|      Count:=Length(S);
 | ||
|    result := Copy(S, 1 + Length(S) - Count, Count);
 | ||
| end;
 | ||
| 
 | ||
| {    BCDToInt converts the BCD value Value to an integer   }
 | ||
| 
 | ||
| function BCDToInt(Value: integer): integer;
 | ||
| var i, j: integer;
 | ||
| begin
 | ||
| result := 0;
 | ||
| j := 1;
 | ||
| for i := 0 to SizeOf(Value) shr 1 - 1 do begin
 | ||
|    result := result + j * (Value and 15);
 | ||
|    j := j * 10;
 | ||
|    Value := Value shr 4;
 | ||
|    end ;
 | ||
| end ;
 | ||
| 
 | ||
| {
 | ||
|    Case Translation Tables
 | ||
|    Can be used in internationalization support.
 | ||
| 
 | ||
|    Although these tables can be obtained through system calls
 | ||
|    it is better to not use those, since most implementation are not 100%
 | ||
|    WARNING:
 | ||
|    before modifying a translation table make sure that the current codepage
 | ||
|    of the OS corresponds to the one you make changes to
 | ||
| }
 | ||
| 
 | ||
| const
 | ||
|    { upper case translation table for character set 850 }
 | ||
|    CP850UCT: array[128..255] of char =
 | ||
|    ('<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', 'Y', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>');
 | ||
| 
 | ||
|    { lower case translation table for character set 850 }
 | ||
|    CP850LCT: array[128..255] of char =
 | ||
|    ('<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>',
 | ||
|     '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>', '<27>');
 | ||
| 
 | ||
|    { upper case translation table for character set ISO 8859/1  Latin 1  }
 | ||
|    CPISO88591UCT: array[192..255] of char =
 | ||
|    ( #192, #193, #194, #195, #196, #197, #198, #199,
 | ||
|      #200, #201, #202, #203, #204, #205, #206, #207,
 | ||
|      #208, #209, #210, #211, #212, #213, #214, #215,
 | ||
|      #216, #217, #218, #219, #220, #221, #222, #223,
 | ||
|      #192, #193, #194, #195, #196, #197, #198, #199,
 | ||
|      #200, #201, #202, #203, #204, #205, #206, #207,
 | ||
|      #208, #209, #210, #211, #212, #213, #214, #247,
 | ||
|      #216, #217, #218, #219, #220, #221, #222, #89 );
 | ||
| 
 | ||
|    { lower case translation table for character set ISO 8859/1  Latin 1  }
 | ||
|    CPISO88591LCT: array[192..255] of char =
 | ||
|    ( #224, #225, #226, #227, #228, #229, #230, #231,
 | ||
|      #232, #233, #234, #235, #236, #237, #238, #239,
 | ||
|      #240, #241, #242, #243, #244, #245, #246, #215,
 | ||
|      #248, #249, #250, #251, #252, #253, #254, #223,
 | ||
|      #224, #225, #226, #227, #228, #229, #230, #231,
 | ||
|      #232, #233, #234, #235, #236, #237, #238, #239,
 | ||
|      #240, #241, #242, #243, #244, #245, #246, #247,
 | ||
|      #248, #249, #250, #251, #252, #253, #254, #255 );
 | ||
| 
 | ||
| {
 | ||
|   $Log$
 | ||
|   Revision 1.29  1999-11-06 14:41:31  peter
 | ||
|     * truncated log
 | ||
| 
 | ||
|   Revision 1.28  1999/10/12 19:16:27  florian
 | ||
|     * bug 645 fixed: format('%x',...) should writes unsigned hexadecimals, also
 | ||
|       prec fixed: max. value in delphi is 15 (and not 32)
 | ||
| 
 | ||
|   Revision 1.27  1999/10/03 19:42:40  peter
 | ||
|     * fixed comparetext
 | ||
| 
 | ||
|   Revision 1.26  1999/09/04 20:48:34  florian
 | ||
|     * format('%g',[0.0]) returned long format string, fixed
 | ||
| 
 | ||
|   Revision 1.25  1999/08/25 13:13:58  michael
 | ||
|   fixed Formaterror, added missing raise
 | ||
| 
 | ||
|   Revision 1.24  1999/08/16 22:38:53  peter
 | ||
|     * fixed newstr/disposestr
 | ||
| 
 | ||
|   Revision 1.23  1999/07/18 17:27:28  michael
 | ||
|   + Fixed bug in format, reported by Romio Pedchecko
 | ||
| 
 | ||
|   Revision 1.22  1999/06/19 07:39:44  michael
 | ||
|   Implemented strtofloat
 | ||
| 
 | ||
|   Revision 1.21  1999/06/05 20:47:03  michael
 | ||
|   + Final fixes: RightStr
 | ||
| 
 | ||
|   Revision 1.20  1999/05/31 20:50:45  peter
 | ||
|     * removed warnings
 | ||
| 
 | ||
|   Revision 1.19  1999/05/30 07:53:15  michael
 | ||
|   + Small fix. Delete not recognised without system in front of it  ?
 | ||
| 
 | ||
|   Revision 1.18  1999/05/28 20:08:20  michael
 | ||
|   * too may fixes to list
 | ||
| 
 | ||
|   Revision 1.17  1999/04/08 11:31:03  peter
 | ||
|     * removed warnings
 | ||
| 
 | ||
|   Revision 1.16  1999/04/08 10:19:41  peter
 | ||
|     * pchar support for %s
 | ||
| 
 | ||
|   Revision 1.15  1999/04/04 10:19:07  peter
 | ||
|     * format support for ansistring (from mailinglist)
 | ||
|     * fixed length checking in Trim()
 | ||
| 
 | ||
|   Revision 1.14  1999/03/01 12:40:06  michael
 | ||
|   changed delete to system.delete
 | ||
| 
 | ||
|   Revision 1.13  1999/02/28 13:17:35  michael
 | ||
|   + Added internationalization support and more format functions
 | ||
| 
 | ||
|   Revision 1.12  1999/02/24 15:56:29  michael
 | ||
|   + Small fixes. Moved getlocaltime to system-dependent files
 | ||
| 
 | ||
|   Revision 1.11  1999/02/10 22:15:12  michael
 | ||
|   + Changed to ansistrings
 | ||
| 
 | ||
|   Revision 1.10  1998/12/15 22:43:09  peter
 | ||
|     * removed temp symbols
 | ||
| 
 | ||
|   Revision 1.9  1998/11/04 10:20:52  peter
 | ||
|     * ansistring fixes
 | ||
| 
 | ||
| }
 | ||
| 
 | 
