summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarco <marco@3ad0048d-3df7-0310-abae-a5850022a9f2>2016-05-25 14:02:13 +0000
committermarco <marco@3ad0048d-3df7-0310-abae-a5850022a9f2>2016-05-25 14:02:13 +0000
commit57d7db4f8e31fa9c1dedad156ec2d5bb9de51276 (patch)
tree82705a8dad54cdb7b60c55085e84282db8ae261f
parent683dae6a0e5c2a0bd0169501cfddcb2af1223bb5 (diff)
downloadfpc-57d7db4f8e31fa9c1dedad156ec2d5bb9de51276.tar.gz
--- Merging r32264 into '.':
U utils/tply/lextable.pas U utils/tply/plex.pas --- Recording mergeinfo for merge of r32264 into '.': G . # revisions: 32264 git-svn-id: http://svn.freepascal.org/svn/fpc/branches/fixes_3_0@33789 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--rtl/amicommon/sysutils.pp2
-rw-r--r--rtl/embedded/sysutils.pp5
-rw-r--r--rtl/emx/sysutils.pp2
-rw-r--r--rtl/gba/sysutils.pp2
-rw-r--r--rtl/go32v2/sysutils.pp2
-rw-r--r--rtl/inc/ustringh.inc16
-rw-r--r--rtl/inc/ustrings.inc7
-rw-r--r--rtl/macos/sysutils.pp2
-rw-r--r--rtl/msdos/sysutils.pp2
-rw-r--r--rtl/nativent/sysutils.pp2
-rw-r--r--rtl/nds/sysutils.pp3
-rw-r--r--rtl/netware/sysutils.pp2
-rw-r--r--rtl/netwlibc/sysutils.pp2
-rw-r--r--rtl/objpas/fpwidestring.pp49
-rw-r--r--rtl/objpas/sysutils/syshelp.inc1618
-rw-r--r--rtl/objpas/sysutils/syshelpb.inc36
-rw-r--r--rtl/objpas/sysutils/syshelpf.inc235
-rw-r--r--rtl/objpas/sysutils/syshelph.inc616
-rw-r--r--rtl/objpas/sysutils/syshelpo.inc71
-rw-r--r--rtl/objpas/sysutils/sysuni.inc8
-rw-r--r--rtl/objpas/sysutils/sysutilh.inc3
-rw-r--r--rtl/objpas/sysutils/sysutils.inc4
-rw-r--r--rtl/objpas/sysutils/syswide.inc8
-rw-r--r--rtl/os2/sysucode.inc11
-rw-r--r--rtl/os2/sysutils.pp2
-rw-r--r--rtl/unix/cwstring.pp49
-rw-r--r--rtl/unix/sysutils.pp2
-rw-r--r--rtl/watcom/sysutils.pp2
-rw-r--r--rtl/wii/sysutils.pp3
-rw-r--r--rtl/win/sysutils.pp44
-rw-r--r--rtl/win/wininc/defines.inc1
-rw-r--r--rtl/wince/sysutils.pp2
-rw-r--r--utils/tply/lextable.pas4
-rw-r--r--utils/tply/plex.pas4
34 files changed, 2756 insertions, 65 deletions
diff --git a/rtl/amicommon/sysutils.pp b/rtl/amicommon/sysutils.pp
index d06e32e22c..d824da8ca1 100644
--- a/rtl/amicommon/sysutils.pp
+++ b/rtl/amicommon/sysutils.pp
@@ -27,6 +27,8 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
{$DEFINE OS_FILESETDATEBYNAME}
{$DEFINE HAS_SLEEP}
diff --git a/rtl/embedded/sysutils.pp b/rtl/embedded/sysutils.pp
index 61ab9e31dc..7f9569f6ba 100644
--- a/rtl/embedded/sysutils.pp
+++ b/rtl/embedded/sysutils.pp
@@ -20,6 +20,11 @@ unit sysutils;
interface
+{$DEFINE HAS_SLEEP}
+{$DEFINE HAS_OSERROR}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
+
{ used OS file system APIs use ansistring }
{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
{ OS has an ansistring/single byte environment variable API }
diff --git a/rtl/emx/sysutils.pp b/rtl/emx/sysutils.pp
index 44a9896511..d449e1db6d 100644
--- a/rtl/emx/sysutils.pp
+++ b/rtl/emx/sysutils.pp
@@ -21,6 +21,8 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
uses
Dos;
diff --git a/rtl/gba/sysutils.pp b/rtl/gba/sysutils.pp
index f21003e040..2680be0bc7 100644
--- a/rtl/gba/sysutils.pp
+++ b/rtl/gba/sysutils.pp
@@ -28,6 +28,8 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
{$DEFINE HAS_SLEEP}
{$DEFINE HAS_OSERROR}
diff --git a/rtl/go32v2/sysutils.pp b/rtl/go32v2/sysutils.pp
index 44579a8b4c..fc3a136a93 100644
--- a/rtl/go32v2/sysutils.pp
+++ b/rtl/go32v2/sysutils.pp
@@ -23,6 +23,8 @@ interface
{$MODESWITCH out}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
uses
go32,dos;
diff --git a/rtl/inc/ustringh.inc b/rtl/inc/ustringh.inc
index 51f14c7474..502e9bd852 100644
--- a/rtl/inc/ustringh.inc
+++ b/rtl/inc/ustringh.inc
@@ -52,7 +52,11 @@ procedure DefaultUnicode2AnsiMove(source:punicodechar;var dest:RawByteString;cp
procedure DefaultAnsi2UnicodeMove(source:pchar;cp : TSystemCodePage;var dest:unicodestring;len:SizeInt);
Type
- TStandardCodePageEnum = (
+ TCompareOption = (coLingIgnoreCase, coLingIgnoreDiacritic, coIgnoreCase,
+ coIgnoreKanaType, coIgnoreNonSpace, coIgnoreSymbols, coIgnoreWidth,
+ coLingCasing, coDigitAsNumbers, coStringSort);
+ TCompareOptions = set of TCompareOption;
+ TStandardCodePageEnum = (
scpAnsi, // system Ansi code page (GetACP on windows)
scpConsoleInput, // system console input code page (GetConsoleCP on windows)
scpConsoleOutput, // system console output code page (GetConsoleOutputCP on windows)
@@ -78,8 +82,9 @@ Type
CompUCS2 : function(p1,p2:PUCS2Char) : shortint;
CompUCS4 : function(p1,p2:PUC42Char) : shortint;
}
- CompareWideStringProc : function(const s1, s2 : WideString) : PtrInt;
- CompareTextWideStringProc : function(const s1, s2 : WideString): PtrInt;
+ CompareWideStringProc : function(const s1, s2 : WideString; Options : TCompareOptions) : PtrInt;
+ // CompareTextWideStringProc is CompareWideStringProc with coIgnoreCase in options.
+// CompareTextWideStringProc : function(const s1, s2 : WideString): PtrInt;
{ return value: number of code points in the string. Whenever an invalid
code point is encountered, all characters part of this invalid code point
are considered to form one "character" and the next character is
@@ -109,8 +114,9 @@ Type
Ansi2UnicodeMoveProc : procedure(source:pchar;cp : TSystemCodePage;var dest:unicodestring;len:SizeInt);
UpperUnicodeStringProc : function(const S: UnicodeString): UnicodeString;
LowerUnicodeStringProc : function(const S: UnicodeString): UnicodeString;
- CompareUnicodeStringProc : function(const s1, s2 : UnicodeString) : PtrInt;
- CompareTextUnicodeStringProc : function(const s1, s2 : UnicodeString): PtrInt;
+ CompareUnicodeStringProc : function(const s1, s2 : UnicodeString; Options : TCompareOptions) : PtrInt;
+ // CompareTextUnicodeStringProc is CompareUnicodeStringProc with coIgnoreCase in options.
+ /// CompareTextUnicodeStringProc : function(const s1, s2 : UnicodeString): PtrInt;
{ codepage retrieve function }
GetStandardCodePageProc: function(const stdcp: TStandardCodePageEnum): TSystemCodePage;
diff --git a/rtl/inc/ustrings.inc b/rtl/inc/ustrings.inc
index 038af0b0fd..88b0cb21fb 100644
--- a/rtl/inc/ustrings.inc
+++ b/rtl/inc/ustrings.inc
@@ -2291,7 +2291,7 @@ function StubUnicodeCase(const s : UnicodeString) : UnicodeString;
unimplementedunicodestring;
end;
-function StubCompareUnicodeString(const s1, s2 : UnicodeString) : PtrInt;
+function StubCompareUnicodeString(const s1, s2 : UnicodeString; Options : TCompareOptions) : PtrInt;
begin
unimplementedunicodestring;
end;
@@ -2301,7 +2301,7 @@ function StubWideCase(const s: WideString): WideString;
unimplementedunicodestring;
end;
-function StubCompareWideString(const s1, s2 : WideString) : PtrInt;
+function StubCompareWideString(const s1, s2 : WideString; Options : TCompareOptions) : PtrInt;
begin
unimplementedunicodestring;
end;
@@ -2324,9 +2324,8 @@ procedure initunicodestringmanager;
widestringmanager.LowerUnicodeStringProc:=@StubUnicodeCase;
{$endif HAS_WIDESTRINGMANAGER}
widestringmanager.CompareWideStringProc:=@StubCompareWideString;
- widestringmanager.CompareTextWideStringProc:=@StubCompareWideString;
+// widestringmanager.CompareTextWideStringProc:=@StubCompareWideString;
widestringmanager.CompareUnicodeStringProc:=@StubCompareUnicodeString;
- widestringmanager.CompareTextUnicodeStringProc:=@StubCompareUnicodeString;
widestringmanager.CharLengthPCharProc:=@DefaultCharLengthPChar;
widestringmanager.CodePointLengthProc:=@DefaultCodePointLength;
widestringmanager.GetStandardCodePageProc:=@DefaultGetStandardCodePage;
diff --git a/rtl/macos/sysutils.pp b/rtl/macos/sysutils.pp
index bfb4c3d057..3ef79bbc80 100644
--- a/rtl/macos/sysutils.pp
+++ b/rtl/macos/sysutils.pp
@@ -24,6 +24,8 @@ interface
{$modeswitch out}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
uses
MacOSTP;
diff --git a/rtl/msdos/sysutils.pp b/rtl/msdos/sysutils.pp
index 7cecf2248f..2f5f252e41 100644
--- a/rtl/msdos/sysutils.pp
+++ b/rtl/msdos/sysutils.pp
@@ -23,6 +23,8 @@ interface
{$MODESWITCH out}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
uses
{go32,}dos;
diff --git a/rtl/nativent/sysutils.pp b/rtl/nativent/sysutils.pp
index 631b7bb5ad..8a7eafb97a 100644
--- a/rtl/nativent/sysutils.pp
+++ b/rtl/nativent/sysutils.pp
@@ -21,6 +21,8 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
uses
ndk;
diff --git a/rtl/nds/sysutils.pp b/rtl/nds/sysutils.pp
index 03def9994f..93cc9d09d5 100644
--- a/rtl/nds/sysutils.pp
+++ b/rtl/nds/sysutils.pp
@@ -28,6 +28,9 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
+
{$DEFINE HAS_OSERROR}
{$DEFINE HAS_SLEEP}
{ used OS file system APIs use ansistring }
diff --git a/rtl/netware/sysutils.pp b/rtl/netware/sysutils.pp
index d0f1aeb3e1..e866039ef1 100644
--- a/rtl/netware/sysutils.pp
+++ b/rtl/netware/sysutils.pp
@@ -21,6 +21,8 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
uses DOS;
diff --git a/rtl/netwlibc/sysutils.pp b/rtl/netwlibc/sysutils.pp
index 56fd22d1ff..be20af62fe 100644
--- a/rtl/netwlibc/sysutils.pp
+++ b/rtl/netwlibc/sysutils.pp
@@ -20,6 +20,8 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
uses Libc,DOS;
diff --git a/rtl/objpas/fpwidestring.pp b/rtl/objpas/fpwidestring.pp
index 5c74af793c..8ba01a2119 100644
--- a/rtl/objpas/fpwidestring.pp
+++ b/rtl/objpas/fpwidestring.pp
@@ -406,10 +406,22 @@ begin
Result := CompareUnicodeStringUCA(p1,p2,l1,l2);
end;
-function CompareUnicodeString(const s1, s2 : UnicodeString) : PtrInt;
+function CompareUnicodeString(const s1, s2 : UnicodeString;Options : TCompareOptions) : PtrInt;
+Var
+ us1,us2 : UnicodeString;
begin
if (current_Collation=nil) then
- exit(OldManager.CompareUnicodeStringProc(s1,s2));
+ exit(OldManager.CompareUnicodeStringProc(s1,s2,Options));
+ if (coIgnoreCase in Options) then
+ begin
+ us1:=UpperUnicodeString(s1);
+ us2:=UpperUnicodeString(s2);
+ end
+ else
+ begin
+ us1:=S1;
+ us2:=S2;
+ end;
Result:=CompareUnicodeString(
PUnicodeChar(Pointer(s1)),
PUnicodeChar(Pointer(s2)),
@@ -417,25 +429,39 @@ begin
);
end;
-function CompareWideString(const s1, s2 : WideString) : PtrInt;
+function CompareWideString(const s1, s2 : WideString; Options : TCompareOptions) : PtrInt;
+
+Var
+ us1,us2 : WideString;
+
begin
if (current_Collation=nil) then
- exit(OldManager.CompareWideStringProc(s1,s2));
+ exit(OldManager.CompareWideStringProc(s1,s2,Options));
+ if (coIgnoreCase in Options) then
+ begin
+ us1:=UpperWideString(s1);
+ us2:=UpperWideString(s2);
+ end
+ else
+ begin
+ us1:=S1;
+ us2:=S2;
+ end;
Result:=CompareUnicodeString(
- PUnicodeChar(Pointer(s1)),
- PUnicodeChar(Pointer(s2)),
- Length(s1),Length(s2)
+ PUnicodeChar(Pointer(us1)),
+ PUnicodeChar(Pointer(us2)),
+ Length(us1),Length(us2)
);
end;
function CompareTextUnicodeString(const s1, s2 : UnicodeString) : PtrInt;
begin
- Result:=CompareUnicodeString(UpperUnicodeString(s1),UpperUnicodeString(s2));
+ Result:=CompareUnicodeString(s1,s2,[coIgnoreCase]);
end;
function CompareTextWideString(const s1, s2 : WideString) : PtrInt;
begin
- Result:=CompareWideString(UpperWideString(s1),UpperWideString(s2));
+ Result:=CompareWideString(s1,s2,[coIgnoreCase]);
end;
procedure EnsureAnsiLen(var S: AnsiString; const len: SizeInt); inline;
@@ -649,7 +675,7 @@ begin
Ansi2UnicodeMove(S1,DefaultSystemCodePage,a,Len1);
b := '';
Ansi2UnicodeMove(S2,DefaultSystemCodePage,b,Len2);
- Result := CompareUnicodeString(a,b);
+ Result := CompareUnicodeString(a,b,[]);
end;
function StrLCompAnsiString(S1, S2: PAnsiChar; MaxLen: PtrUInt): PtrInt;
@@ -746,7 +772,6 @@ begin
LowerWideStringProc:=@LowerWideString;
CompareWideStringProc:=@CompareWideString;
- CompareTextWideStringProc:=@CompareTextWideString;
{$else FPC_WIDESTRING_EQUAL_UNICODESTRING}
Ansi2WideMoveProc:=@Ansi2UnicodeMove;
@@ -754,7 +779,6 @@ begin
LowerWideStringProc:=@LowerUnicodeString;
CompareWideStringProc:=@CompareUnicodeString;
- CompareTextWideStringProc:=@CompareTextUnicodeString;
{$endif FPC_WIDESTRING_EQUAL_UNICODESTRING}
CharLengthPCharProc:=@CharLengthPChar;
@@ -778,7 +802,6 @@ begin
UpperUnicodeStringProc:=@UpperUnicodeString;
LowerUnicodeStringProc:=@LowerUnicodeString;
CompareUnicodeStringProc:=@CompareUnicodeString;
- CompareTextUnicodeStringProc:=@CompareTextUnicodeString;
end;
SetUnicodeStringManager(locWideStringManager);
diff --git a/rtl/objpas/sysutils/syshelp.inc b/rtl/objpas/sysutils/syshelp.inc
new file mode 100644
index 0000000000..e16865da13
--- /dev/null
+++ b/rtl/objpas/sysutils/syshelp.inc
@@ -0,0 +1,1618 @@
+{%mainunit syshelpers.pp}
+
+{ ---------------------------------------------------------------------
+ TGUIDHelper
+ ---------------------------------------------------------------------}
+
+Procedure NotImplemented(S : String);
+
+begin
+ Raise Exception.Create('Not yet implemented : '+S);
+end;
+
+Class function TGUIDHelper.Create(const Data; BigEndian: Boolean): TGUID; overload; static;
+
+Const
+ GUIDSize = SizeOf(TGUID);
+
+Var
+ B : Array[1..GUIDSize] of Byte;
+
+begin
+ Move(Data,B,GUIDSize);
+ Result:=Create(B,0,BigEndian);
+end;
+
+class function TGUIDHelper.Create(const Data: array of Byte; AStartIndex: Cardinal; BigEndian: Boolean): TGUID; overload; static;
+
+Var
+ A : Cardinal;
+ B,C : Word;
+
+begin
+ if ((System.Length(Data)-AStartIndex)<16) then
+ raise EArgumentException.CreateFmt('The length of a GUID array must be at least %d',[]);
+ Move(Data[AStartIndex],A,SizeOf(Cardinal));
+ Move(Data[AStartIndex+4],B,SizeOf(Word));
+ Move(Data[AStartIndex+6],C,SizeOf(Word));
+// Writeln('BigEndian : ',BigEndian,', CPU bigendian : ',(CPUendian=TEndian.Big));
+ if BigEndian<>(CPUendian=TEndian.Big) then
+ begin
+// Writeln('Swapping');
+ A:=SwapEndian(A);
+ B:=SwapEndian(B);
+ C:=SwapEndian(C);
+ end;
+ Result:=Create(A,B,C,Data[AStartIndex+8],Data[AStartIndex+9],Data[AStartIndex+10],Data[AStartIndex+11],Data[AStartIndex+12],Data[AStartIndex+13],Data[AStartIndex+14],Data[AStartIndex+15]);
+end;
+
+Class Function TGUIDHelper.Create(const Data; DataEndian: TEndian = CPUEndian): TGUID; overload; static; inline;
+
+begin
+ Result:=Create(Data,DataEndian=TEndian.Big)
+end;
+
+Class Function TGUIDHelper.Create(const B: TBytes; DataEndian: TEndian = CPUEndian): TGUID; overload; static; inline;
+
+begin
+ Result:=Create(B,0,DataEndian);
+end;
+
+Class Function TGUIDHelper.Create(const B: TBytes; AStartIndex: Cardinal; DataEndian: TEndian = CPUEndian): TGUID; overload; static;
+
+begin
+ if ((System.Length(B)-AStartIndex)<16) then
+ raise EArgumentException.CreateFmt('The length of a GUID array must be at least %d',[]);
+ Result:=Create(B,AStartIndex,DataEndian=TEndian.Big);
+end;
+
+Class Function TGUIDHelper.Create(const S: string): TGUID; overload; static;
+
+begin
+ Result:=StringToGUID(S);
+end;
+
+Class Function TGUIDHelper.Create(A: Integer; B: SmallInt; C: SmallInt; const D: TBytes): TGUID; overload; static;
+
+begin
+ if (System.Length(D)<>8) then
+ raise EArgumentException.CreateFmt('The length of a GUID array must be %d',[]);
+ Result:=Create(Cardinal(A),Word(B),Word(C),D[0],D[1],D[2],D[3],D[4],D[5],D[6],D[7]);
+end;
+
+Class Function TGUIDHelper.Create(A: Integer; B: SmallInt; C: SmallInt; D, E, F, G, H, I, J, K: Byte): TGUID; overload; static;
+
+begin
+ Result:=Create(Cardinal(A),Word(B),Word(C),D,E,F,G,H,I,J,K);
+end;
+
+Class Function TGUIDHelper.Create(A: Cardinal; B: Word; C: Word; D, E, F, G, H, I, J, K: Byte): TGUID; overload; static;
+
+begin
+ Result.D1 := Cardinal(A);
+ Result.D2 := Word(B);
+ Result.D3 := Word(C);
+ Result.D4[0] := D;
+ Result.D4[1] := E;
+ Result.D4[2] := F;
+ Result.D4[3] := G;
+ Result.D4[4] := H;
+ Result.D4[5] := I;
+ Result.D4[6] := J;
+ Result.D4[7] := K;
+end;
+
+Class Function TGUIDHelper.NewGuid: TGUID; static;
+
+begin
+ CreateGUID(Result)
+end;
+
+Function TGUIDHelper.ToByteArray(DataEndian: TEndian = CPUEndian): TBytes;
+
+begin
+ SetLength(Result, 16);
+ if DataEndian<>CPUEndian then
+ begin
+ PCardinal(@Result[0])^ := SwapEndian(D1);
+ PWord(@Result[4])^ := SwapEndian(D2);
+ PWord(@Result[6])^ := SwapEndian(D3);
+ Move(D4, Result[8], 8);
+ end
+ else
+ Move(D1, Result[0], SizeOf(Self));
+
+end;
+
+Function TGUIDHelper.ToString(SkipBrackets : Boolean = False): string;
+
+begin
+ Result:=GuidToString(Self);
+ If SkipBrackets then
+ Result:=Copy(Result,2,Length(Result)-2);
+end;
+
+{ ---------------------------------------------------------------------
+ TStringHelper
+ ---------------------------------------------------------------------}
+
+Function HaveChar(AChar : Char; const AList: array of Char) : Boolean;
+
+Var
+ I : Integer;
+
+begin
+ I:=0;
+ Result:=False;
+ While (Not Result) and (I<Length(AList)) do
+ begin
+ Result:=(AList[i]=AChar);
+ Inc(I);
+ end;
+end;
+
+function TStringHelper.GetChar(AIndex: Integer): Char;
+begin
+ Result:=Self[AIndex+1];
+end;
+
+
+function TStringHelper.GetLength: Integer;
+
+begin
+ Result:=System.Length(Self);
+end;
+
+
+class function TStringHelper.Compare(const A: string; const B: string): Integer;
+begin
+ Result:=Compare(A,0,B,0,System.Length(B),[]);
+end;
+
+
+class function TStringHelper.Compare(const A: string; const B: string;
+ IgnoreCase: Boolean): Integer; //deprecated 'Use same with TCompareOptions';
+begin
+ if IgnoreCase then
+ Result:=Compare(A,B,[coIgnoreCase])
+ else
+ Result:=Compare(A,B,[]);
+end;
+
+
+class function TStringHelper.Compare(const A: string; const B: string;
+ Options: TCompareOptions): Integer;
+begin
+ Result:=Compare(A,0,B,0,System.Length(B),Options);
+end;
+
+
+class function TStringHelper.Compare(const A: string; IndexA: Integer;
+ const B: string; IndexB: Integer; ALen: Integer): Integer;
+begin
+ Result:=Compare(A,IndexA,B,IndexB,ALen,[]);
+end;
+
+
+class function TStringHelper.Compare(const A: string; IndexA: Integer;
+ const B: string; IndexB: Integer; ALen: Integer; IgnoreCase: Boolean
+ ): Integer; //deprecated 'Use same with TCompareOptions';
+begin
+ if IgnoreCase then
+ Result:=Compare(A,IndexA,B,IndexB,ALen,[coIgnoreCase])
+ else
+ Result:=Compare(A,IndexA,B,IndexB,ALen,[])
+end;
+
+
+class function TStringHelper.Compare(const A: string; IndexA: Integer;
+ const B: string; IndexB: Integer; ALen: Integer; Options: TCompareOptions
+ ): Integer;
+
+Var
+ l : Integer;
+
+begin
+ L:=ALen;
+ If (L>system.Length(A)-IndexA) then
+ L:=system.Length(A)-IndexA;
+ If (L>system.Length(B)-IndexB) then
+ L:=system.Length(B)-IndexB;
+ if (coIgnoreCase in Options) then
+ begin
+ Result:=strlicomp(PAnsiChar(@A[IndexA+1]),PAnsiChar(@B[IndexB+1]),L)
+ end
+ else
+ Result:=strlcomp(PAnsiChar(@A[IndexA+1]),PAnsiChar(@B[IndexB+1]),L);
+end;
+
+
+class function TStringHelper.CompareOrdinal(const A: string; const B: string
+ ): Integer;
+
+Var
+ L : Integer;
+
+begin
+ L:=System.Length(B);
+ if L>System.Length(A) then
+ L:=System.Length(A);
+ Result:=CompareOrdinal(A,0,B,0,L);
+end;
+
+
+class function TStringHelper.CompareOrdinal(const A: string; IndexA: Integer;
+ const B: string; IndexB: Integer; ALen: Integer): Integer;
+
+begin
+ Result:=StrLComp(PAnsiChar(@A[IndexA+1]), PAnsiChar(@B[IndexB+1]), ALen);
+end;
+
+
+class function TStringHelper.CompareText(const A: string; const B: string
+ ): Integer;
+begin
+ Result:=Sysutils.CompareText(A,B);
+end;
+
+
+class function TStringHelper.Copy(const Str: string): string;
+begin
+ Result:=Str;
+ UniqueString(Result);
+end;
+
+
+class function TStringHelper.Create(AChar: Char; ACount: Integer): string;
+begin
+ Result:=StringOfChar(AChar,ACount);
+end;
+
+
+class function TStringHelper.Create(const AValue: array of Char): string;
+
+begin
+ Result:=Create(AValue,0,System.Length(AValue));
+end;
+
+
+class function TStringHelper.Create(const AValue: array of Char;
+ StartIndex: Integer; ALen: Integer): string;
+begin
+ SetLength(Result,ALen);
+ if ALen>0 then
+ Move(AValue[StartIndex],Result[1],ALen);
+end;
+
+
+class function TStringHelper.EndsText(const ASubText, AText: string): Boolean;
+begin
+ Result:=(ASubText<>'') and (sysutils.CompareText(System.Copy(AText,System.Length(AText)-System.Length(ASubText)+1,System.Length(ASubText)),ASubText)=0);
+end;
+
+
+class function TStringHelper.Equals(const a: string; const b: string): Boolean;
+begin
+ Result:=A=B;
+end;
+
+
+class function TStringHelper.Format(const AFormat: string;
+ const args: array of const): string;
+begin
+ Result:=Sysutils.Format(AFormat,Args);
+end;
+
+
+class function TStringHelper.IsNullOrEmpty(const AValue: string): Boolean;
+begin
+ Result:=system.Length(AValue)=0;
+end;
+
+
+class function TStringHelper.IsNullOrWhiteSpace(const AValue: string): Boolean;
+begin
+ Result:=system.Length(SysUtils.Trim(AValue))=0;
+end;
+
+
+class function TStringHelper.Join(const Separator: string;
+ const Values: array of const): string;
+
+Var
+ SValues : Array of string;
+ I,L : Integer;
+ S : String;
+ P : ^TVarRec;
+
+begin
+ L:=System.Length(Values);
+ SetLength(SValues,L);
+ Dec(L);
+ for I:=0 to L do
+ begin
+ S:='';
+ P:=@Values[I];
+ Case P^.VType of
+ vtInteger : S:=IntToStr(P^.VInteger);
+ vtBoolean : S:=BoolToStr(P^.VBoolean, True);
+ vtChar : S:=P^.VChar;
+ vtPChar : S:= string(P^.VPChar);
+ {$ifndef FPUNONE}
+ vtExtended : S:=FloatToStr(P^.VExtended^);
+ {$endif}
+ vtObject : S:=TObject(P^.VObject).Classname;
+ vtClass : S:=P^.VClass.Classname;
+ vtCurrency : S:=CurrToStr(P^.VCurrency^);
+ vtVariant : S:=(P^.VVariant^);
+ vtInt64 : S:=IntToStr(PInt64(P^.VInt64)^);
+ vtQword : S:=IntToStr(PQWord(P^.VQword)^);
+ vtWideChar : S:=WideString(P^.VWideChar);
+ vtPWideChar : S:=WideString(P^.VPWideChar);
+ vtUnicodeString : S:=UnicodeString(P^.VUnicodeString);
+ vtAnsiString : S:=Ansistring(P^.VAnsiString);
+ else
+ S:=Format('Unknown type: %d',[P^.VType]);
+ end;
+ SValues[I]:=S;
+ end;
+ Result:=Join(Separator,SValues);
+end;
+
+
+class function TStringHelper.Join(const Separator: string;
+ const Values: array of string): string;
+begin
+ Result:=Join(Separator,Values,0,System.Length(Values));
+end;
+
+
+class function TStringHelper.Join(const Separator: string;
+ const Values: array of string; StartIndex: Integer; ACount: Integer): string;
+
+Var
+ I,L,VLen : integer;
+
+begin
+ VLen:=High(Values);
+ If (ACount<0) or ((StartIndex>0) and (StartIndex>VLen)) then
+ raise ERangeError.Create(SRangeError);
+ If (ACount=0) or (VLen<0) then
+ Result:=''
+ else
+ begin
+ L:=StartIndex+ACount-1;
+ if L>Vlen then
+ L:=VLen;
+ Result:=Values[StartIndex];
+ For I:=StartIndex+1 to L do
+ Result:=Result+Separator+Values[I];
+ end;
+end;
+
+
+class function TStringHelper.LowerCase(const S: string): string;
+begin
+ Result:=sysutils.Lowercase(S);
+end;
+
+
+class function TStringHelper.Parse(const AValue: Boolean): string;
+begin
+ Result:=BoolToStr(AValue);
+end;
+
+
+class function TStringHelper.Parse(const AValue: Extended): string;
+begin
+ Result:=FloatToStr(AValue);
+end;
+
+
+class function TStringHelper.Parse(const AValue: Int64): string;
+begin
+ Result:=IntToStr(AValue);
+end;
+
+
+class function TStringHelper.Parse(const AValue: Integer): string;
+begin
+ Result:=IntToStr(AValue);
+end;
+
+
+class function TStringHelper.ToBoolean(const S: string): Boolean;
+begin
+ Result:=StrToBool(S);
+end;
+
+
+class function TStringHelper.ToDouble(const S: string): Double;
+begin
+ Result:=StrToFloat(S);
+end;
+
+
+class function TStringHelper.ToExtended(const S: string): Extended;
+begin
+ Result:=StrToFloat(S);
+end;
+
+
+class function TStringHelper.ToInt64(const S: string): Int64;
+begin
+ Result:=StrToInt64(S);
+end;
+
+
+class function TStringHelper.ToInteger(const S: string): Integer;
+begin
+ Result:=StrToInt(S);
+end;
+
+
+class function TStringHelper.ToSingle(const S: string): Single;
+begin
+ Result:=StrToFloat(S);
+end;
+
+
+class function TStringHelper.UpperCase(const S: string): string;
+begin
+ Result:=sysutils.Uppercase(S);
+end;
+
+
+function TStringHelper.CompareTo(const B: string): Integer;
+begin
+ // Order is important
+ Result:=sysUtils.StrComp(PChar(Self),PChar(B));
+end;
+
+procedure TStringHelper.CopyTo(SourceIndex: Integer; var destination: array of Char; DestinationIndex: Integer; ACount: Integer);
+
+Var
+ P1,P2 : PChar;
+begin
+// Writeln('((',DestinationIndex,'+',ACount,')<',System.Length(Destination),') : ', ((DestinationIndex+ACount)<System.Length(Destination)));
+ if ((DestinationIndex+ACount)<=System.Length(Destination)) then
+ begin
+// Writeln('AHA');
+ P1:=@Self[SourceIndex+1];
+ P2:=@Destination[DestinationIndex];
+ Move(P1^,P2^,ACount*SizeOf(Char));
+ end;
+end;
+
+function TStringHelper.Contains(const AValue: string): Boolean;
+begin
+ Result:=Pos(AValue,Self)>0;
+end;
+
+
+function TStringHelper.CountChar(const C: Char): Integer;
+
+Var
+ S : Char;
+begin
+ Result:=0;
+ For S in Self do
+ if (S=C) then
+ Inc(Result);
+end;
+
+
+function TStringHelper.DeQuotedString: string;
+begin
+ Result:=DeQuotedString('''');
+end;
+
+
+function TStringHelper.DeQuotedString(const AQuoteChar: Char): string;
+
+var
+ L,I : Integer;
+ Res : Array of Char;
+ PS,PD : PChar;
+ IsQuote : Boolean;
+
+begin
+ L:=System.Length(Self);
+ if (L<2) or Not ((Self[1]=AQuoteChar) and (Self[L]=AQuoteChar)) then
+ Exit(Self);
+ SetLength(Res,L);
+ IsQuote:=False;
+ PS:=@Self[2];
+ PD:=@Res[0];
+ For I:=2 to L-1 do
+ begin
+ if (PS^=AQuoteChar) then
+ begin
+ IsQuote:=Not IsQuote;
+ if Not IsQuote then
+ begin
+ PD^:=PS^;
+ Inc(PD);
+ end;
+ end
+ else
+ begin
+ if IsQuote then
+ IsQuote:=false;
+ PD^:=PS^;
+ Inc(PD);
+ end;
+ Inc(PS);
+ end;
+ SetString(Result,@Res[0],PD-@Res[0]);
+end;
+
+
+function TStringHelper.EndsWith(const AValue: string): Boolean;
+begin
+ Result:=EndsWith(AValue,False);
+end;
+
+
+function TStringHelper.EndsWith(const AValue: string; IgnoreCase: Boolean): Boolean;
+
+Var
+ L : integer;
+ S : String;
+begin
+ L:=system.Length(AVAlue);
+ Result:=L>0;
+ if Result then
+ begin
+ S:=system.Copy(Self,Length-L+1,L);
+ Result:=system.Length(S)=L;
+ if Result then
+ if IgnoreCase then
+ Result:=CompareText(S,AValue)=0
+ else
+ Result:=S=AValue;
+ end;
+end;
+
+function TStringHelper.Equals(const AValue: string): Boolean;
+begin
+ Result:=(Self=AValue);
+end;
+
+function TStringHelper.Format(const args: array of const): string;
+begin
+ Result:=Format(Self,Args);
+end;
+
+
+function TStringHelper.GetHashCode: Integer;
+
+// Taken from contnrs, fphash
+var
+ P,pmax : PChar;
+begin
+{$push}
+{$Q-}
+ Result:=0;
+ P:=Pchar(Self);
+ pmax:=p+length;
+ while (p<pmax) do
+ begin
+ Result:=LongWord(LongInt(Result shl 5) - LongInt(Result)) xor LongWord(P^);
+ Inc(p);
+ end;
+{$pop}
+end;
+
+
+function TStringHelper.IndexOf(AValue: Char): Integer;
+begin
+ Result:=IndexOf(AValue,0,Length);
+end;
+
+
+function TStringHelper.IndexOf(const AValue: string): Integer;
+begin
+ Result:=IndexOf(AValue,0,Length);
+end;
+
+
+function TStringHelper.IndexOf(AValue: Char; StartIndex: Integer): Integer;
+begin
+ Result:=IndexOf(AValue,StartIndex,Length);
+end;
+
+
+function TStringHelper.IndexOf(const AValue: string; StartIndex: Integer
+ ): Integer;
+begin
+ Result:=IndexOf(AValue,StartIndex,Length);
+end;
+
+
+function TStringHelper.IndexOf(AValue: Char; StartIndex: Integer;
+ ACount: Integer): Integer;
+
+Var
+ S : String;
+
+begin
+ S:=System.Copy(Self,StartIndex+1,ACount);
+ Result:=Pos(AValue,S)-1;
+ if Result<>-1 then
+ Result:=Result+StartIndex;
+end;
+
+
+function TStringHelper.IndexOf(const AValue: string; StartIndex: Integer;
+ ACount: Integer): Integer;
+
+Var
+ S : String;
+
+begin
+ S:=System.Copy(Self,StartIndex+1,ACount);
+ Result:=Pos(AValue,S)-1;
+ if Result<>-1 then
+ Result:=Result+StartIndex;
+end;
+
+function TStringHelper.IndexOfUnQuoted(const AValue: string; StartQuote,
+ EndQuote: Char; StartIndex: Integer = 0): Integer;
+
+Var
+ LV : Integer;
+
+ Function MatchAt(I : Integer) : Boolean ; Inline;
+
+ Var
+ J : integer;
+
+ begin
+ J:=1;
+ Repeat
+ Result:=(Self[I+J-1]=AValue[j]);
+ Inc(J);
+ Until (Not Result) or (J>LV);
+ end;
+
+Var
+ I,L: Integer;
+ Q : Integer;
+
+begin
+ Result:=-1;
+ LV:=system.Length(AValue);
+ L:=Length-LV+1;
+ if L<0 then
+ L:=0;
+ I:=StartIndex+1;
+ Q:=0;
+ if StartQuote=EndQuote then
+ begin
+ While (Result=-1) and (I<=L) do
+ begin
+ if (Self[I]=StartQuote) then
+ Q:=1-Q;
+ if (Q=0) and MatchAt(i) then
+ Result:=I-1;
+ Inc(I);
+ end;
+ end
+ else
+ begin
+ While (Result=-1) and (I<=L) do
+ begin
+ if Self[I]=StartQuote then
+ Inc(Q)
+ else if (Self[I]=EndQuote) and (Q>0) then
+ Dec(Q);
+ if (Q=0) and MatchAt(i) then
+ Result:=I-1;
+ Inc(I);
+ end;
+ end;
+end;
+
+
+function TStringHelper.IndexOfAny(const AnyOf: array of Char): Integer;
+begin
+ Result:=IndexOfAny(AnyOf,0,Length);
+end;
+
+
+function TStringHelper.IndexOfAny(const AnyOf: array of Char;
+ StartIndex: Integer): Integer;
+begin
+ Result:=IndexOfAny(AnyOf,StartIndex,Length);
+end;
+
+
+function TStringHelper.IndexOfAny(const AnyOf: array of Char;
+ StartIndex: Integer; ACount: Integer): Integer;
+
+Var
+ i,L : Integer;
+
+begin
+ I:=StartIndex+1;
+ L:=I+ACount-1;
+ If L>Length then
+ L:=Length;
+ Result:=-1;
+ While (Result=-1) and (I<=L) do
+ begin
+ if HaveChar(Self[i],AnyOf) then
+ Result:=I-1;
+ Inc(I);
+ end;
+end;
+
+function TStringHelper.IndexOfAny(const AnyOf: array of String): Integer;
+begin
+ Result:=IndexOfAny(AnyOf,0,Length);
+end;
+
+function TStringHelper.IndexOfAny(const AnyOf: array of String;
+ StartIndex: Integer): Integer;
+begin
+ Result:=IndexOfAny(AnyOf,StartIndex,Length-StartIndex);
+end;
+
+function TStringHelper.IndexOfAny(const AnyOf: array of String;
+ StartIndex: Integer; ACount: Integer): Integer;
+
+Var
+ M : Integer;
+
+begin
+ Result:=IndexOfAny(AnyOf,StartIndex,ACount,M);
+end;
+
+function TStringHelper.IndexOfAny(const AnyOf: array of String;
+ StartIndex: Integer; ACount: Integer; out AMatch: Integer): Integer;
+
+Var
+ L,I : Integer;
+
+begin
+ Result:=-1;
+ For I:=0 to System.Length(AnyOf)-1 do
+ begin
+ L:=IndexOf(AnyOf[i],StartIndex,ACount);
+ If (L>=0) and ((Result=-1) or (L<Result)) then
+ begin
+ Result:=L;
+ AMatch:=I;
+ end;
+ end;
+end;
+
+
+function TStringHelper.IndexOfAnyUnquoted(const AnyOf: array of Char;
+ StartQuote, EndQuote: Char): Integer;
+begin
+ Result:=IndexOfAnyUnquoted(AnyOf,StartQuote,EndQuote,0,Length);
+end;
+
+
+function TStringHelper.IndexOfAnyUnquoted(const AnyOf: array of Char;
+ StartQuote, EndQuote: Char; StartIndex: Integer): Integer;
+begin
+ Result:=IndexOfAnyUnquoted(AnyOf,StartQuote,EndQuote,StartIndex,Length);
+end;
+
+
+function TStringHelper.IndexOfAnyUnquoted(const AnyOf: array of Char;
+ StartQuote, EndQuote: Char; StartIndex: Integer; ACount: Integer): Integer;
+
+Var
+ I,L : Integer;
+ Q : Integer;
+
+begin
+ Result:=-1;
+ L:=StartIndex+ACount-1;
+ if L>Length then
+ L:=Length;
+ I:=StartIndex+1;
+ Q:=0;
+ if StartQuote=EndQuote then
+ begin
+ While (Result=-1) and (I<=L) do
+ begin
+ if (Self[I]=StartQuote) then
+ Q:=1-Q;
+ if (Q=0) and HaveChar(Self[i],AnyOf) then
+ Result:=I-1;
+ Inc(I);
+ end;
+ end
+ else
+ begin
+ While (Result=-1) and (I<=L) do
+ begin
+ if Self[I]=StartQuote then
+ Inc(Q)
+ else if (Self[I]=EndQuote) and (Q>0) then
+ Dec(Q);
+ if (Q=0) and HaveChar(Self[i],AnyOf) then
+ Result:=I-1;
+ Inc(I);
+ end;
+ end;
+
+end;
+
+function TStringHelper.IndexOfAnyUnquoted(const AnyOf: array of string;
+ StartQuote, EndQuote: Char; StartIndex: Integer; out Matched: Integer
+ ): Integer;
+
+Var
+ L,I : Integer;
+
+begin
+ Result:=-1;
+ For I:=0 to System.Length(AnyOf)-1 do
+ begin
+ L:=IndexOfUnquoted(AnyOf[i],StartQuote,EndQuote,StartIndex);
+ If (L>=0) and ((Result=-1) or (L<Result)) then
+ begin
+ Result:=L;
+ Matched:=I;
+ end;
+ end;
+end;
+
+
+function TStringHelper.Insert(StartIndex: Integer; const AValue: string
+ ): string;
+begin
+ system.Insert(AValue,Self,StartIndex+1);
+ Result:=Self;
+end;
+
+
+function TStringHelper.IsDelimiter(const Delimiters: string; Index: Integer
+ ): Boolean;
+begin
+ Result:=sysutils.IsDelimiter(Delimiters,Self,Index+1);
+end;
+
+
+function TStringHelper.IsEmpty: Boolean;
+begin
+ Result:=(Length=0)
+end;
+
+
+function TStringHelper.LastDelimiter(const Delims: string): Integer;
+begin
+ Result:=sysutils.LastDelimiter(Delims,Self)-1;
+end;
+
+
+function TStringHelper.LastIndexOf(AValue: Char): Integer;
+begin
+ Result:=LastIndexOf(AValue,Length-1,Length);
+end;
+
+
+function TStringHelper.LastIndexOf(const AValue: string): Integer;
+begin
+ Result:=LastIndexOf(AValue,Length-1,Length);
+end;
+
+
+function TStringHelper.LastIndexOf(AValue: Char; AStartIndex: Integer): Integer;
+begin
+ Result:=LastIndexOf(AValue,AStartIndex,Length);
+end;
+
+
+function TStringHelper.LastIndexOf(const AValue: string; AStartIndex: Integer
+ ): Integer;
+begin
+ Result:=LastIndexOf(AValue,AStartIndex,Length);
+end;
+
+
+function TStringHelper.LastIndexOf(AValue: Char; AStartIndex: Integer;
+ ACount: Integer): Integer;
+
+Var
+ Min : Integer;
+
+begin
+ Result:=AStartIndex+1;
+ Min:=Result-ACount+1;
+ If Min<1 then
+ Min:=1;
+ While (Result>=Min) and (Self[Result]<>AValue) do
+ Dec(Result);
+ if Result<Min then
+ Result:=-1
+ else
+ Result:=Result-1;
+end;
+
+
+function TStringHelper.LastIndexOf(const AValue: string; AStartIndex: Integer;
+ ACount: Integer): Integer;
+begin
+ Result:=LastIndexOf(AValue,AStartIndex,AStartIndex+1);
+end;
+
+
+function TStringHelper.LastIndexOfAny(const AnyOf: array of Char): Integer;
+begin
+ Result:=LastIndexOfAny(AnyOf,Length-1,Length);
+end;
+
+
+function TStringHelper.LastIndexOfAny(const AnyOf: array of Char;
+ AStartIndex: Integer): Integer;
+begin
+ Result:=LastIndexOfAny(AnyOf,AStartIndex,Length);
+end;
+
+
+function TStringHelper.LastIndexOfAny(const AnyOf: array of Char;
+ AStartIndex: Integer; ACount: Integer): Integer;
+
+Var
+ Min : Integer;
+
+begin
+ Result:=AStartIndex+1;
+ Min:=Result-ACount+1;
+ If Min<1 then
+ Min:=1;
+ While (Result>=Min) and Not HaveChar(Self[Result],AnyOf) do
+ Dec(Result);
+ if Result<Min then
+ Result:=-1
+ else
+ Result:=Result-1;
+end;
+
+
+function TStringHelper.PadLeft(ATotalWidth: Integer): string;
+begin
+ Result:=PadLeft(ATotalWidth,' ');
+end;
+
+
+function TStringHelper.PadLeft(ATotalWidth: Integer; PaddingChar: Char): string;
+Var
+ L : Integer;
+
+begin
+ Result:=Self;
+ L:=ATotalWidth-Length;
+ If L>0 then
+ Result:=StringOfChar(PaddingChar,L)+Result;
+end;
+
+
+function TStringHelper.PadRight(ATotalWidth: Integer): string;
+begin
+ Result:=PadRight(ATotalWidth,' ');
+end;
+
+
+function TStringHelper.PadRight(ATotalWidth: Integer; PaddingChar: Char
+ ): string;
+
+Var
+ L : Integer;
+
+begin
+ Result:=Self;
+ L:=ATotalWidth-Length;
+ If L>0 then
+ Result:=Result+StringOfChar(PaddingChar,L);
+end;
+
+
+function TStringHelper.QuotedString: string;
+begin
+ Result:=QuotedStr(Self);
+end;
+
+
+function TStringHelper.QuotedString(const AQuoteChar: Char): string;
+begin
+ Result:=AnsiQuotedStr(Self,AQuoteChar);
+end;
+
+
+function TStringHelper.Remove(StartIndex: Integer): string;
+begin
+ Result:=Remove(StartIndex,Self.Length-StartIndex);
+end;
+
+
+function TStringHelper.Remove(StartIndex: Integer; ACount: Integer): string;
+begin
+ Result:=Self;
+ System.Delete(Result,StartIndex+1,ACount);
+end;
+
+
+function TStringHelper.Replace(OldChar: Char; NewChar: Char): string;
+begin
+ Result:=Replace(OldChar,NewChar,[rfReplaceAll]);
+end;
+
+
+function TStringHelper.Replace(OldChar: Char; NewChar: Char;
+ ReplaceFlags: TReplaceFlags): string;
+begin
+ Result:=StringReplace(Self,OldChar,NewChar,ReplaceFlags);
+end;
+
+
+function TStringHelper.Replace(const OldValue: string; const NewValue: string
+ ): string;
+begin
+ Result:=Replace(OldValue,NewValue,[rfReplaceAll]);
+end;
+
+
+function TStringHelper.Replace(const OldValue: string; const NewValue: string;
+ ReplaceFlags: TReplaceFlags): string;
+begin
+ Result:=StringReplace(Self,OldValue,NewValue,ReplaceFlags);
+end;
+
+
+function TStringHelper.Split(const Separators: array of Char): TStringArray;
+begin
+ Result:=SPlit(Separators,#0,#0,Length,TStringSplitOptions([]));
+end;
+
+
+function TStringHelper.Split(const Separators: array of Char; ACount: Integer
+ ): TStringArray;
+begin
+ Result:=SPlit(Separators,#0,#0,ACount,TStringSplitOptions([]));
+end;
+
+
+function TStringHelper.Split(const Separators: array of Char;
+ Options: TStringSplitOptions): TStringArray;
+begin
+ Result:=SPlit(Separators,Length,Options);
+end;
+
+
+function TStringHelper.Split(const Separators: array of Char; ACount: Integer;
+ Options: TStringSplitOptions): TStringArray;
+begin
+ Result:=SPlit(Separators,#0,#0,ACount,Options);
+end;
+
+
+function TStringHelper.Split(const Separators: array of string): TStringArray;
+begin
+ Result:=Split(Separators,Length);
+end;
+
+
+function TStringHelper.Split(const Separators: array of string; ACount: Integer
+ ): TStringArray;
+begin
+ Result:=Split(Separators,ACount,TStringSplitOptions([]));
+end;
+
+
+function TStringHelper.Split(const Separators: array of string;
+ Options: TStringSplitOptions): TStringArray;
+begin
+ Result:=Split(Separators,Length,Options);
+end;
+
+
+function TStringHelper.Split(const Separators: array of string;
+ ACount: Integer; Options: TStringSplitOptions): TStringArray;
+begin
+ Result:=Split(Separators,#0,#0,ACount,Options);
+end;
+
+
+function TStringHelper.Split(const Separators: array of Char; AQuote: Char
+ ): TStringArray;
+begin
+ Result:=Split(Separators,AQuote,AQuote);
+end;
+
+
+function TStringHelper.Split(const Separators: array of Char; AQuoteStart,
+ AQuoteEnd: Char): TStringArray;
+begin
+ Result:=Split(Separators,AQuoteStart,AQuoteEnd,TStringSplitOptions([]));
+end;
+
+
+function TStringHelper.Split(const Separators: array of Char; AQuoteStart,
+ AQuoteEnd: Char; Options: TStringSplitOptions): TStringArray;
+begin
+ Result:=Split(Separators,AQuoteStart,AQuoteEnd,Length,Options);
+end;
+
+
+function TStringHelper.Split(const Separators: array of Char; AQuoteStart,
+ AQuoteEnd: Char; ACount: Integer): TStringArray;
+begin
+ Result:=Split(Separators,AQuoteStart,AQuoteEnd,ACount,TStringSplitOptions([]));
+end;
+
+
+function TStringHelper.Split(const Separators: array of Char; AQuoteStart,
+ AQuoteEnd: Char; ACount: Integer; Options: TStringSplitOptions): TStringArray;
+
+Const
+ BlockSize = 10;
+
+ Function NextSep(StartIndex : integer) : Integer;
+
+ begin
+ if (AQuoteStart<>#0) then
+ Result:=Self.IndexOfAnyUnQuoted(Separators,AQuoteStart,AQuoteEnd,StartIndex)
+ else
+ Result:=Self.IndexOfAny(Separators,StartIndex);
+ end;
+
+ Procedure MaybeGrow(Curlen : Integer);
+
+ begin
+ if System.Length(Result)<=CurLen then
+ SetLength(Result,System.Length(Result)+BlockSize);
+ end;
+
+Var
+ Sep,LastSep,Len : integer;
+ T : String;
+
+begin
+ SetLength(Result,BlockSize);
+ Len:=0;
+ LastSep:=0;
+ Sep:=NextSep(0);
+ While (Sep<>-1) and ((ACount=0) or (Len<ACount)) do
+ begin
+ T:=SubString(LastSep,Sep-LastSep);
+// Writeln('Examining >',T,'< at pos,',LastSep,' till pos ',Sep);
+ If (T<>'') or (not (ExcludeEmpty=Options)) then
+ begin
+ MaybeGrow(Len);
+ Result[Len]:=T;
+ Inc(Len);
+ end;
+ LastSep:=Sep+1;
+ Sep:=NextSep(LastSep);
+ end;
+ if (LastSep<Length-1) and ((ACount=0) or (Len<ACount)) then
+ begin
+ T:=SubString(LastSep);
+// Writeln('Examining >',T,'< at pos,',LastSep,' till pos ',Sep);
+ MaybeGrow(Len);
+ Result[Len]:=T;
+ Inc(Len);
+ end;
+ SetLength(Result,Len);
+end;
+
+
+function TStringHelper.Split(const Separators: array of string; AQuote: Char
+ ): TStringArray;
+begin
+ Result:=SPlit(Separators,AQuote,AQuote);
+end;
+
+
+function TStringHelper.Split(const Separators: array of string; AQuoteStart,
+ AQuoteEnd: Char): TStringArray;
+begin
+ Result:=SPlit(Separators,AQuoteStart,AQuoteEnd,Length,TStringSplitOptions([]));
+end;
+
+
+function TStringHelper.Split(const Separators: array of string; AQuoteStart,
+ AQuoteEnd: Char; Options: TStringSplitOptions): TStringArray;
+begin
+ Result:=SPlit(Separators,AQuoteStart,AQuoteEnd,Length,Options);
+end;
+
+
+function TStringHelper.Split(const Separators: array of string; AQuoteStart,
+ AQuoteEnd: Char; ACount: Integer): TStringArray;
+begin
+ Result:=SPlit(Separators,AQuoteStart,AQuoteEnd,ACount,TStringSplitOptions([]));
+end;
+
+
+function TStringHelper.Split(const Separators: array of string; AQuoteStart,
+ AQuoteEnd: Char; ACount: Integer; Options: TStringSplitOptions): TStringArray;
+Const
+ BlockSize = 10;
+
+ Function NextSep(StartIndex : integer; out Match : Integer) : Integer;
+
+ begin
+ if (AQuoteStart<>#0) then
+ Result:=Self.IndexOfAnyUnQuoted(Separators,AQuoteStart,AQuoteEnd,StartIndex,Match)
+ else
+ Result:=Self.IndexOfAny(Separators,StartIndex,Length,Match);
+ if Result<>-1 then
+ end;
+
+ Procedure MaybeGrow(Curlen : Integer);
+
+ begin
+ if System.Length(Result)<=CurLen then
+ SetLength(Result,System.Length(Result)+BlockSize);
+ end;
+
+Var
+ Sep,LastSep,Len,Match : integer;
+ T : String;
+
+begin
+ SetLength(Result,BlockSize);
+ Len:=0;
+ LastSep:=0;
+ Sep:=NextSep(0,Match);
+ While (Sep<>-1) and ((ACount=0) or (Len<ACount)) do
+ begin
+ T:=SubString(LastSep,Sep-LastSep);
+ If (T<>'') or (not (ExcludeEmpty=Options)) then
+ begin
+ MaybeGrow(Len);
+ Result[Len]:=T;
+ Inc(Len);
+ end;
+ LastSep:=Sep+System.Length(Separators[Match]);
+ Sep:=NextSep(LastSep,Match);
+ end;
+ if (LastSep<Length-1) and ((ACount=0) or (Len<ACount)) then
+ begin
+ T:=SubString(LastSep);
+// Writeln('Examining >',T,'< at pos,',LastSep,' till pos ',Sep);
+ MaybeGrow(Len);
+ Result[Len]:=T;
+ Inc(Len);
+ end;
+ SetLength(Result,Len);
+end;
+
+
+function TStringHelper.StartsWith(const AValue: string): Boolean;
+begin
+ Result:=StartsWith(AValue,False);
+end;
+
+
+function TStringHelper.StartsWith(const AValue: string; IgnoreCase: Boolean
+ ): Boolean;
+Var
+ L : Integer;
+begin
+ L:=System.Length(AValue);
+ Result:=L>0;
+ if Result then
+ if IgnoreCase then
+ Result:=StrLiComp(PChar(AValue),PChar(Self),L)=0
+ else
+ Result:=StrLComp(PChar(AValue),PChar(Self),L)=0
+end;
+
+
+function TStringHelper.Substring(AStartIndex: Integer): string;
+begin
+ Result:=Self.SubString(AStartIndex,Self.Length-AStartIndex);
+end;
+
+
+function TStringHelper.Substring(AStartIndex: Integer; ALen: Integer): string;
+begin
+ Result:=system.Copy(Self,AStartIndex+1,ALen);
+end;
+
+
+function TStringHelper.ToBoolean: Boolean;
+begin
+ Result:=StrToBool(Self);
+end;
+
+
+function TStringHelper.ToInteger: Integer;
+begin
+ Result:=StrToInt(Self);
+end;
+
+
+function TStringHelper.ToInt64: Int64;
+begin
+ Result:=StrToInt64(Self);
+end;
+
+
+function TStringHelper.ToSingle: Single;
+begin
+ Result:=StrToFLoat(Self);
+end;
+
+
+function TStringHelper.ToDouble: Double;
+begin
+ Result:=StrToFLoat(Self);
+end;
+
+
+function TStringHelper.ToExtended: Extended;
+begin
+ Result:=StrToFLoat(Self);
+end;
+
+
+function TStringHelper.ToCharArray: TCharArray;
+
+begin
+ Result:=ToCharArray(0,Self.Length);
+end;
+
+
+function TStringHelper.ToCharArray(AStartIndex: Integer; ALen: Integer
+ ): TCharArray;
+
+Var
+ I : Integer;
+
+begin
+ SetLength(Result,ALen);
+ For I:=0 to ALen-1 do
+ Result[I]:=Self[AStartIndex+I+1];
+end;
+
+
+function TStringHelper.ToLower: string;
+begin
+ Result:=LowerCase(Self);
+end;
+
+
+function TStringHelper.ToLowerInvariant: string;
+begin
+ Result:=LowerCase(Self);
+end;
+
+
+function TStringHelper.ToUpper: string;
+begin
+ Result:=UpperCase(Self);
+end;
+
+
+function TStringHelper.ToUpperInvariant: string;
+begin
+ Result:=UpperCase(Self);
+end;
+
+
+function TStringHelper.Trim: string;
+begin
+ Result:=SysUtils.Trim(Self);
+end;
+
+
+function TStringHelper.TrimLeft: string;
+begin
+ Result:=SysUtils.TrimLeft(Self);
+end;
+
+
+function TStringHelper.TrimRight: string;
+begin
+ Result:=SysUtils.TrimRight(Self);
+end;
+
+
+function TStringHelper.Trim(const ATrimChars: array of Char): string;
+begin
+ Result:=Self.TrimLeft(ATrimChars).TrimRight(ATrimChars);
+end;
+
+
+function TStringHelper.TrimLeft(const ATrimChars: array of Char): string;
+
+Var
+ I,Len : Integer;
+
+begin
+ I:=1;
+ Len:=Self.Length;
+ While (I<=Len) and HaveChar(Self[i],ATrimChars) do Inc(I);
+ if I=1 then
+ Result:=Self
+ else if I>Len then
+ Result:=''
+ else
+ Result:=system.Copy(Self,I,Len-I+1);
+end;
+
+
+function TStringHelper.TrimRight(const ATrimChars: array of Char): string;
+
+Var
+ I,Len : Integer;
+
+begin
+ Len:=Self.Length;
+ I:=Len;
+ While (I>=1) and HaveChar(Self[i],ATrimChars) do Dec(I);
+ if I<1 then
+ Result:=''
+ else if I=Len then
+ Result:=Self
+ else
+ Result:=system.Copy(Self,1,I);
+end;
+
+
+function TStringHelper.TrimEnd(const ATrimChars: array of Char): string;
+begin
+ Result:=TrimRight(ATrimChars);
+end;
+
+
+function TStringHelper.TrimStart(const ATrimChars: array of Char): string;
+begin
+ Result:=TrimLeft(ATrimChars);
+end;
+
+{ ---------------------------------------------------------------------
+ TSingleHelper
+ ---------------------------------------------------------------------}
+
+{$MACRO ON}
+
+{$IFDEF FPC_HAS_TYPE_SINGLE}
+{$define TFLOATHELPER:=TSingleHelper}
+{$define FLOATTYPE:=Single}
+{$i syshelpf.inc}
+{$ENDIF FPC_HAS_TYPE_SINGLE}
+
+{ ---------------------------------------------------------------------
+ TDoubleHelper
+ ---------------------------------------------------------------------}
+{$IFDEF FPC_HAS_TYPE_DOUBLE}
+{$define TFLOATHELPER:=TDoubleHelper}
+{$define FLOATTYPE:=Double}
+{$i syshelpf.inc}
+{$ENDIF FPC_HAS_TYPE_DOUBLE}
+
+{ ---------------------------------------------------------------------
+ TExtendedHelper
+ ---------------------------------------------------------------------}
+
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+{$define TFLOATHELPER:=TExtendedHelper}
+{$define FLOATTYPE:=Extended}
+{$i syshelpf.inc}
+{$ENDIF FPC_HAS_TYPE_EXTENDED}
+
+{ ---------------------------------------------------------------------
+ TByteHelper
+ ---------------------------------------------------------------------}
+
+{$define TORDINALHELPER:=TByteHelper}
+{$define TORDINALTYPE:=Byte}
+{$i syshelpo.inc}
+
+{ ---------------------------------------------------------------------
+ TShortintHelper
+ ---------------------------------------------------------------------}
+
+{$define TORDINALHELPER:=TShortIntHelper}
+{$define TORDINALTYPE:=ShortInt}
+{$i syshelpo.inc}
+
+{ ---------------------------------------------------------------------
+ TSmallintHelper
+ ---------------------------------------------------------------------}
+
+{$define TORDINALHELPER:=TSmallIntHelper}
+{$define TORDINALTYPE:=SmallInt}
+{$i syshelpo.inc}
+
+{ ---------------------------------------------------------------------
+ TWordHelper
+ ---------------------------------------------------------------------}
+
+{$define TORDINALHELPER:=TWordHelper}
+{$define TORDINALTYPE:=Word}
+{$i syshelpo.inc}
+
+{ ---------------------------------------------------------------------
+ TCardinalHelper
+ ---------------------------------------------------------------------}
+
+{$define TORDINALHELPER:=TCardinalHelper}
+{$define TORDINALTYPE:=Cardinal}
+{$i syshelpo.inc}
+
+{ ---------------------------------------------------------------------
+ TIntegerHelper
+ ---------------------------------------------------------------------}
+
+{$define TORDINALHELPER:=TIntegerHelper}
+{$define TORDINALTYPE:=Integer}
+{$i syshelpo.inc}
+
+{ ---------------------------------------------------------------------
+ TInt64Helper
+ ---------------------------------------------------------------------}
+
+{$define TORDINALHELPER:=TInt64Helper}
+{$define TORDINALTYPE:=Int64}
+{$i syshelpo.inc}
+
+{ ---------------------------------------------------------------------
+ TQWordHelper
+ ---------------------------------------------------------------------}
+
+{$define TORDINALHELPER:=TQWordHelper}
+{$define TORDINALTYPE:=QWord}
+{$i syshelpo.inc}
+
+{ ---------------------------------------------------------------------
+ TNativeIntHelper
+ ---------------------------------------------------------------------}
+
+{$define TORDINALHELPER:=TNativeIntHelper}
+{$define TORDINALTYPE:=NativeInt}
+{$i syshelpo.inc}
+
+{ ---------------------------------------------------------------------
+ TNativeUIntHelper
+ ---------------------------------------------------------------------}
+
+{$define TORDINALHELPER:=TNativeUIntHelper}
+{$define TORDINALTYPE:=NativeUInt}
+{$i syshelpo.inc}
+
+{ ---------------------------------------------------------------------
+ TBooleanHelper
+ ---------------------------------------------------------------------}
+
+{$define TBOOLHELPER:=TBooleanHelper}
+{$define TBOOLTYPE:=Boolean}
+{$i syshelpb.inc}
+
+{ ---------------------------------------------------------------------
+ TByteBoolHelper
+ ---------------------------------------------------------------------}
+
+{$define TBOOLHELPER:=TByteBoolHelper}
+{$define TBOOLTYPE:=ByteBool}
+{$i syshelpb.inc}
+
+{ ---------------------------------------------------------------------
+ TWordBoolHelper
+ ---------------------------------------------------------------------}
+
+{$define TBOOLHELPER:=TWordBoolHelper}
+{$define TBOOLTYPE:=WordBool}
+{$i syshelpb.inc}
+
+{ ---------------------------------------------------------------------
+ TLongBoolHelper
+ ---------------------------------------------------------------------}
+
+
+{$define TBOOLHELPER:=TLongBoolHelper}
+{$define TBOOLTYPE:=LongBool}
+{$i syshelpb.inc}
+
diff --git a/rtl/objpas/sysutils/syshelpb.inc b/rtl/objpas/sysutils/syshelpb.inc
new file mode 100644
index 0000000000..09149a11be
--- /dev/null
+++ b/rtl/objpas/sysutils/syshelpb.inc
@@ -0,0 +1,36 @@
+
+Class Function TBOOLHELPER.Parse(const S: string): Boolean; inline; static;
+
+begin
+ Result:=StrToBool(S);
+end;
+
+Class Function TBOOLHELPER.Size: Integer; inline; static;
+
+begin
+ Result:=SizeOf(TBOOLTYPE);
+end;
+
+Class Function TBOOLHELPER.ToString(const AValue: Boolean; UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline; static;
+
+begin
+ Result:=BoolToStr(AValue,UseBoolStrs=TUseBoolStrs.True);
+end;
+
+Class Function TBOOLHELPER.TryToParse(const S: string; out AValue: Boolean): Boolean; inline; static;
+
+begin
+ Result:=TryStrToBool(S,AValue);
+end;
+
+Function TBOOLHELPER.ToInteger: Integer; inline;
+
+begin
+ Result:=Integer(Self);
+end;
+
+Function TBOOLHELPER.ToString(UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline;
+
+begin
+ Result:=BoolToStr(Self,UseBoolStrs=TUseBoolStrs.True);
+end;
diff --git a/rtl/objpas/sysutils/syshelpf.inc b/rtl/objpas/sysutils/syshelpf.inc
new file mode 100644
index 0000000000..8f39d67fc1
--- /dev/null
+++ b/rtl/objpas/sysutils/syshelpf.inc
@@ -0,0 +1,235 @@
+Class Function TFLOATHELPER.IsNan(const AValue: FLOATTYPE): Boolean; overload; inline; static;
+
+begin
+ Result:=AValue=Nan;
+end;
+
+Class Function TFLOATHELPER.IsInfinity(const AValue: FLOATTYPE): Boolean; overload; inline; static;
+
+begin
+ Result:=(AValue=PositiveInfinity) or (AValue=NegativeInfinity);
+end;
+
+Class Function TFLOATHELPER.IsNegativeInfinity(const AValue: FLOATTYPE): Boolean; overload; inline; static;
+
+begin
+ Result:=AValue=NegativeInfinity;
+end;
+
+Class Function TFLOATHELPER.IsPositiveInfinity(const AValue: FLOATTYPE): Boolean; overload; inline; static;
+
+begin
+ Result:=(AValue=PositiveInfinity);
+end;
+
+Class Function TFLOATHELPER.Parse(const AString: string): FLOATTYPE; overload; inline; static;
+
+begin
+ Result:=StrToFloat(AString,DefaultFormatSettings);
+end;
+
+Class Function TFLOATHELPER.Parse(const AString: string; const AFormatSettings: TFormatSettings): FLOATTYPE; overload; inline; static;
+
+begin
+ Result:=StrToFloat(AString,AFormatSettings);
+end;
+
+Class Function TFLOATHELPER.Size: Integer; inline; static;
+
+begin
+ Result:=SizeOf(FLOATTYPE);
+end;
+
+Class Function TFLOATHELPER.ToString(const AValue: FLOATTYPE): string; overload; inline; static;
+
+begin
+ Result:=FloatToStr(AValue,DefaultFormatSettings);
+end;
+
+Class Function TFLOATHELPER.ToString(const AValue: FLOATTYPE; const AFormatSettings: TFormatSettings): string; overload; inline; static;
+
+begin
+ Result:=FloatToStr(AValue,AFormatSettings);
+end;
+
+Class Function TFLOATHELPER.ToString(const AValue: FLOATTYPE; const AFormat: TFloatFormat; const APrecision, ADigits: Integer): string; overload; inline; static;
+
+begin
+ Result:=FloatToStrF(AValue,AFormat,APrecision,ADigits,DefaultFormatSettings);
+end;
+
+Class Function TFLOATHELPER.ToString(const AValue: FLOATTYPE; const AFormat: TFloatFormat; const APrecision, ADigits: Integer; const AFormatSettings: TFormatSettings): string;
+overload; inline; static;
+
+begin
+ Result:=FloatToStrF(AValue,AFormat,APrecision,ADigits,AFormatSettings);
+end;
+
+Class Function TFLOATHELPER.TryParse(const AString: string; out AValue: FLOATTYPE): Boolean; overload; inline; static;
+
+begin
+ Result:=TryStrToFloat(AString,AValue,DefaultFormatSettings);
+end;
+
+Class Function TFLOATHELPER.TryParse(const AString: string; out AValue: FLOATTYPE; const AFormatSettings: TFormatSettings): Boolean; overload; inline;
+static;
+
+begin
+ Result:=TryStrToFloat(AString,AValue,AFormatSettings);
+end;
+
+
+Function TFLOATHELPER.GetB(AIndex: Cardinal): Byte;
+
+begin
+ if (AIndex>=SizeOf(FLOATTYPE)) then
+ system.Error(reRangeError);
+ Result:=PByte(@Self)[AIndex];
+end;
+
+Function TFLOATHELPER.GetW(AIndex: Cardinal): Word;
+
+begin
+ if (AIndex>=(SizeOf(FLOATTYPE) div SizeOf(Word))) then
+ system.Error(reRangeError);
+ Result:=PWord(@Self)[AIndex];
+end;
+
+Function TFLOATHELPER.GetE: QWord; inline;
+
+begin
+end;
+
+Function TFLOATHELPER.GetF: QWord; inline;
+
+begin
+end;
+
+Function TFLOATHELPER.GetS: Boolean; inline;
+
+begin
+end;
+
+procedure TFLOATHELPER.SetB(AIndex: Cardinal; const AValue: Byte);
+
+begin
+ if (AIndex>=SizeOf(FLOATTYPE)) then
+ system.Error(reRangeError);
+ PByte(@Self)[AIndex]:=AValue;
+end;
+
+procedure TFLOATHELPER.SetW(AIndex: Cardinal; const AValue: Word);
+
+begin
+ if (AIndex>=(SizeOf(FLOATTYPE) div SizeOf(Word))) then
+ system.Error(reRangeError);
+ PWord(@Self)[AIndex]:=AValue;
+end;
+
+procedure TFLOATHELPER.SetE(AValue: QWord);
+
+begin
+end;
+
+procedure TFLOATHELPER.SetF(AValue: QWord);
+
+begin
+end;
+
+procedure TFLOATHELPER.SetS(AValue: Boolean);
+
+begin
+end;
+
+
+Procedure TFLOATHELPER.BuildUp(const ASignFlag: Boolean; const AMantissa: QWord; const AExponent: Integer);
+
+begin
+ Self := 0.0;
+ SetS(ASignFlag);
+ SetE(AExponent + $3FF);
+ SetF(AMantissa and $000FFFFFFFFFFFFF);
+end;
+
+Function TFLOATHELPER.Exponent: Integer;
+
+var
+ F,E : QWord;
+begin
+ Result:=0; // Zero, inf, Nan
+ E:=GetE;
+ F:=GetF;
+ if (0<E) and (E<$77FF) then
+ Result:=E-$3FF
+ else if (E=0) and (F<>0) then
+ Result:=-1022
+end;
+
+Function TFLOATHELPER.Fraction: Extended;
+
+begin
+end;
+
+Function TFLOATHELPER.IsInfinity: Boolean; overload; inline;
+
+begin
+ Result:=(Self=PositiveInfinity) or (Self=NegativeInfinity);
+end;
+
+Function TFLOATHELPER.IsNan: Boolean; overload; inline;
+
+begin
+ Result:=(Self=Nan);
+end;
+
+Function TFLOATHELPER.IsNegativeInfinity: Boolean; overload; inline;
+
+begin
+ Result:=(Self=NegativeInfinity);
+end;
+
+Function TFLOATHELPER.IsPositiveInfinity: Boolean; overload; inline;
+
+begin
+ Result:=(Self=PositiveInfinity);
+end;
+
+Function TFLOATHELPER.Mantissa: QWord;
+
+begin
+end;
+
+Function TFLOATHELPER.SpecialType: TFloatSpecial;
+
+begin
+ if IsNan then
+ Result:=fsNan
+ else if IsNegativeInfinity then
+ Result:=fsNInf
+ else if IsPositiveInfinity then
+ Result:=fsInf
+end;
+
+Function TFLOATHELPER.ToString(const AFormat: TFloatFormat; const APrecision, ADigits: Integer): string; overload; inline;
+
+begin
+ Result:=FloatToStrF(Self,AFormat,APrecision,ADigits,DefaultFormatSettings);
+end;
+
+Function TFLOATHELPER.ToString(const AFormat: TFloatFormat; const APrecision, ADigits: Integer; const AFormatSettings: TFormatSettings): string; overload; inline;
+
+begin
+ Result:=FloatToStrF(Self,AFormat,APrecision,ADigits,AFormatSettings);
+end;
+
+Function TFLOATHELPER.ToString(const AFormatSettings: TFormatSettings): string; overload; inline;
+
+begin
+ Result:=FloatToStr(Self,AFormatSettings);
+end;
+
+Function TFLOATHELPER.ToString: string; overload; inline;
+
+begin
+ Result:=FloatToStr(Self,DefaultFormatSettings);
+end;
diff --git a/rtl/objpas/sysutils/syshelph.inc b/rtl/objpas/sysutils/syshelph.inc
new file mode 100644
index 0000000000..fa30f1225e
--- /dev/null
+++ b/rtl/objpas/sysutils/syshelph.inc
@@ -0,0 +1,616 @@
+{%mainunit syshelpers.pp}
+
+Type
+ generic TArray<T> = array of T;
+ TStringArray = Array of string;
+ TCharArray = Array of char;
+{$SCOPEDENUMS ON}
+ TEndian = (Little,Big);
+{$SCOPEDENUMS OFF}
+
+Const
+ CPUEndian = {$IFDEF FPC_LITTLE_ENDIAN}TEndian.Little{$ELSE}TEndian.Big{$ENDIF};
+
+Type
+ TGuidHelper = record helper for TGUID
+ Class function Create(const Data; BigEndian: Boolean): TGUID; overload; static;
+ class function Create(const Data: array of Byte; AStartIndex: Cardinal; BigEndian: Boolean): TGUID; overload; static;
+ Class Function Create(const Data; DataEndian: TEndian = CPUEndian): TGUID; overload; static; inline;
+ Class Function Create(const B: TBytes; DataEndian: TEndian = CPUEndian): TGUID; overload; static; inline;
+ Class Function Create(const B: TBytes; AStartIndex: Cardinal; DataEndian: TEndian = CPUEndian): TGUID; overload; static;
+ Class Function Create(const S: string): TGUID; overload; static;
+ Class Function Create(A: Integer; B: SmallInt; C: SmallInt; const D: TBytes): TGUID; overload; static;
+ Class Function Create(A: Integer; B: SmallInt; C: SmallInt; D, E, F, G, H, I, J, K: Byte): TGUID; overload; static;
+ Class Function Create(A: Cardinal; B: Word; C: Word; D, E, F, G, H, I, J, K: Byte): TGUID; overload; static;
+ Class Function NewGuid: TGUID; static;
+ Function ToByteArray(DataEndian: TEndian = CPUEndian): TBytes;
+ Function ToString(SkipBrackets: Boolean = False): string;
+ end;
+
+
+ TCompareOption = system.TCompareOption;
+ TCompareOptions = system.TCompareOptions;
+
+ TStringSplitOptions = (None, ExcludeEmpty);
+
+ { TStringHelper }
+
+ TStringHelper = Type Helper for AnsiString
+ Private
+ Function GetChar(AIndex : Integer) : Char;
+ Function GetLength : Integer;
+ public
+ const Empty = '';
+ // Methods
+ Class Function Compare(const A: string; const B: string): Integer; overload; static; //inline;
+ Class Function Compare(const A: string; const B: string; IgnoreCase: Boolean): Integer; overload; static; //inline; //deprecated 'Use same with TCompareOptions';
+ Class Function Compare(const A: string; const B: string; Options: TCompareOptions): Integer; overload; static; // inline;
+ Class Function Compare(const A: string; IndexA: Integer; const B: string; IndexB: Integer; ALen: Integer): Integer; overload; static; // inline;
+ Class Function Compare(const A: string; IndexA: Integer; const B: string; IndexB: Integer; ALen: Integer; IgnoreCase: Boolean): Integer; overload; static; // inline; //deprecated 'Use same with TCompareOptions';
+ Class Function Compare(const A: string; IndexA: Integer; const B: string; IndexB: Integer; ALen: Integer; Options: TCompareOptions): Integer; overload; static;// inline;
+ Class Function CompareOrdinal(const A: string; const B: string): Integer; overload; static;
+ Class Function CompareOrdinal(const A: string; IndexA: Integer; const B: string; IndexB: Integer; ALen: Integer): Integer; overload; static;
+ Class Function CompareText(const A: string; const B: string): Integer; static; inline;
+ Class Function Copy(const Str: string): string; inline; static;
+ Class Function Create(AChar: Char; ACount: Integer): string; overload; inline; static;
+ Class Function Create(const AValue: array of Char): string; overload; static;
+ Class Function Create(const AValue: array of Char; StartIndex: Integer; ALen: Integer): string; overload; static;
+ Class Function EndsText(const ASubText, AText: string): Boolean; static;
+ Class Function Equals(const a: string; const b: string): Boolean; overload; static;
+ Class Function Format(const AFormat: string; const args: array of const): string; overload; static;
+ Class Function IsNullOrEmpty(const AValue: string): Boolean; static;
+ Class Function IsNullOrWhiteSpace(const AValue: string): Boolean; static;
+ Class Function Join(const Separator: string; const Values: array of const): string; overload; static;
+ Class Function Join(const Separator: string; const Values: array of string): string; overload; static;
+ Class Function Join(const Separator: string; const Values: array of string; StartIndex: Integer; ACount: Integer): string; overload; static;
+ Class Function LowerCase(const S: string): string; overload; static; inline;
+ Class Function Parse(const AValue: Boolean): string; overload; static; inline;
+ Class Function Parse(const AValue: Extended): string; overload; static;inline;
+ Class Function Parse(const AValue: Int64): string; overload; static; inline;
+ Class Function Parse(const AValue: Integer): string; overload; static; inline;
+ Class Function ToBoolean(const S: string): Boolean; overload; static; inline;
+ Class Function ToDouble(const S: string): Double; overload; static; inline;
+ Class Function ToExtended(const S: string): Extended; overload; static; inline;
+ Class Function ToInt64(const S: string): Int64; overload; static; inline;
+ Class Function ToInteger(const S: string): Integer; overload; static; inline;
+ Class Function ToSingle(const S: string): Single; overload; static; inline;
+ Class Function UpperCase(const S: string): string; overload; static; inline;
+ Function CompareTo(const B: string): Integer;
+ Function Contains(const AValue: string): Boolean;
+ procedure CopyTo(SourceIndex: Integer; var destination: array of Char; DestinationIndex: Integer; ACount: Integer);
+ Function CountChar(const C: Char): Integer;
+ Function DeQuotedString: string; overload;
+ Function DeQuotedString(const AQuoteChar: Char): string; overload;
+ Function EndsWith(const AValue: string): Boolean; overload; inline;
+ Function EndsWith(const AValue: string; IgnoreCase: Boolean): Boolean; overload;
+ Function Equals(const AValue: string): Boolean; overload;
+ Function Format(const args: array of const): string; overload;
+ Function GetHashCode: Integer;
+ Function IndexOf(AValue: Char): Integer; overload; inline;
+ Function IndexOf(const AValue: string): Integer; overload; inline;
+ Function IndexOf(AValue: Char; StartIndex: Integer): Integer; overload;
+ Function IndexOf(const AValue: string; StartIndex: Integer): Integer; overload;
+ Function IndexOf(AValue: Char; StartIndex: Integer; ACount: Integer): Integer; overload;
+ Function IndexOf(const AValue: string; StartIndex: Integer; ACount: Integer): Integer; overload;
+ Function IndexOfUnQuoted(const AValue: string; StartQuote, EndQuote: Char; StartIndex: Integer = 0): Integer; overload;
+ Function IndexOfAny(const AnyOf: array of Char): Integer; overload;
+ Function IndexOfAny(const AnyOf: array of Char; StartIndex: Integer): Integer; overload;
+ Function IndexOfAny(const AnyOf: array of Char; StartIndex: Integer; ACount: Integer): Integer; overload;
+ Function IndexOfAny(const AnyOf: array of String): Integer; overload;
+ Function IndexOfAny(const AnyOf: array of String; StartIndex: Integer): Integer; overload;
+ Function IndexOfAny(const AnyOf: array of String; StartIndex: Integer; ACount: Integer): Integer; overload;
+ Function IndexOfAny(const AnyOf: array of String; StartIndex: Integer; ACount: Integer; Out AMatch : Integer): Integer; overload;
+ Function IndexOfAnyUnquoted(const AnyOf: array of Char; StartQuote, EndQuote: Char): Integer; overload;
+ Function IndexOfAnyUnquoted(const AnyOf: array of Char; StartQuote, EndQuote: Char; StartIndex: Integer): Integer; overload;
+ Function IndexOfAnyUnquoted(const AnyOf: array of Char; StartQuote, EndQuote: Char; StartIndex: Integer; ACount: Integer): Integer; overload;
+ function IndexOfAnyUnquoted(const AnyOf: array of string; StartQuote, EndQuote: Char; StartIndex: Integer; Out Matched: Integer): Integer; overload;
+ Function Insert(StartIndex: Integer; const AValue: string): string;
+ Function IsDelimiter(const Delimiters: string; Index: Integer): Boolean;
+ Function IsEmpty: Boolean;
+ Function LastDelimiter(const Delims: string): Integer;
+ Function LastIndexOf(AValue: Char): Integer; overload;
+ Function LastIndexOf(const AValue: string): Integer; overload;
+ Function LastIndexOf(AValue: Char; AStartIndex: Integer): Integer; overload;
+ Function LastIndexOf(const AValue: string; AStartIndex: Integer): Integer; overload;
+ Function LastIndexOf(AValue: Char; AStartIndex: Integer; ACount: Integer): Integer; overload;
+ Function LastIndexOf(const AValue: string; AStartIndex: Integer; ACount: Integer): Integer; overload;
+ Function LastIndexOfAny(const AnyOf: array of Char): Integer; overload;
+ Function LastIndexOfAny(const AnyOf: array of Char; AStartIndex: Integer): Integer; overload;
+ Function LastIndexOfAny(const AnyOf: array of Char; AStartIndex: Integer; ACount: Integer): Integer; overload;
+ Function PadLeft(ATotalWidth: Integer): string; overload; inline;
+ Function PadLeft(ATotalWidth: Integer; PaddingChar: Char): string; overload; inline;
+ Function PadRight(ATotalWidth: Integer): string; overload; inline;
+ Function PadRight(ATotalWidth: Integer; PaddingChar: Char): string; overload; inline;
+ Function QuotedString: string; overload;
+ Function QuotedString(const AQuoteChar: Char): string; overload;
+ Function Remove(StartIndex: Integer): string; overload; inline;
+ Function Remove(StartIndex: Integer; ACount: Integer): string; overload; inline;
+ Function Replace(OldChar: Char; NewChar: Char): string; overload;
+ Function Replace(OldChar: Char; NewChar: Char; ReplaceFlags: TReplaceFlags): string; overload;
+ Function Replace(const OldValue: string; const NewValue: string): string; overload;
+ Function Replace(const OldValue: string; const NewValue: string; ReplaceFlags: TReplaceFlags): string; overload;
+ Function Split(const Separators: array of Char): TStringArray; overload;
+ Function Split(const Separators: array of Char; ACount: Integer): TStringArray; overload;
+ Function Split(const Separators: array of Char; Options: TStringSplitOptions): TStringArray; overload;
+ Function Split(const Separators: array of Char; ACount: Integer; Options: TStringSplitOptions): TStringArray; overload;
+ Function Split(const Separators: array of string): TStringArray; overload;
+ Function Split(const Separators: array of string; ACount: Integer): TStringArray; overload;
+ Function Split(const Separators: array of string; Options: TStringSplitOptions): TStringArray; overload;
+ Function Split(const Separators: array of string; ACount: Integer; Options: TStringSplitOptions): TStringArray; overload;
+ Function Split(const Separators: array of Char; AQuote: Char): TStringArray; overload;
+ Function Split(const Separators: array of Char; AQuoteStart, AQuoteEnd: Char): TStringArray; overload;
+ Function Split(const Separators: array of Char; AQuoteStart, AQuoteEnd: Char; Options: TStringSplitOptions): TStringArray; overload;
+ Function Split(const Separators: array of Char; AQuoteStart, AQuoteEnd: Char; ACount: Integer): TStringArray; overload;
+ Function Split(const Separators: array of Char; AQuoteStart, AQuoteEnd: Char; ACount: Integer; Options: TStringSplitOptions): TStringArray; overload;
+ Function Split(const Separators: array of string; AQuote: Char): TStringArray; overload;
+ Function Split(const Separators: array of string; AQuoteStart, AQuoteEnd: Char): TStringArray; overload;
+ Function Split(const Separators: array of string; AQuoteStart, AQuoteEnd: Char; Options: TStringSplitOptions): TStringArray; overload;
+ Function Split(const Separators: array of string; AQuoteStart, AQuoteEnd: Char; ACount: Integer): TStringArray; overload;
+ Function Split(const Separators: array of string; AQuoteStart, AQuoteEnd: Char; ACount: Integer; Options: TStringSplitOptions): TStringArray; overload;
+ Function StartsWith(const AValue: string): Boolean; overload; inline;
+ Function StartsWith(const AValue: string; IgnoreCase: Boolean): Boolean; overload;
+ Function Substring(AStartIndex: Integer): string; overload;
+ Function Substring(AStartIndex: Integer; ALen: Integer): string; overload;
+ Function ToBoolean: Boolean; overload; inline;
+ Function ToInteger: Integer; overload; inline;
+ Function ToInt64: Int64; overload; inline;
+ Function ToSingle: Single; overload; inline;
+ Function ToDouble: Double; overload; inline;
+ Function ToExtended: Extended; overload; inline;
+ Function ToCharArray: TCharArray; overload;
+ Function ToCharArray(AStartIndex: Integer; ALen: Integer): TCharArray; overload;
+ Function ToLower: string; overload; inline;
+ Function ToLowerInvariant: string;
+ Function ToUpper: string; overload; inline;
+ Function ToUpperInvariant: string; inline;
+ Function Trim: string; overload;
+ Function TrimLeft: string; overload;
+ Function TrimRight: string; overload;
+ Function Trim(const ATrimChars: array of Char): string; overload;
+ Function TrimLeft(const ATrimChars: array of Char): string; overload;
+ Function TrimRight(const ATrimChars: array of Char): string; overload;
+ Function TrimEnd(const ATrimChars: array of Char): string; deprecated 'Use TrimRight';
+ Function TrimStart(const ATrimChars: array of Char): string; deprecated 'Use TrimLeft';
+ property Chars[AIndex: Integer]: Char read GetChar;
+ property Length: Integer read GetLength;
+ end;
+
+{$IFDEF FPC_HAS_TYPE_SINGLE}
+ TSingleHelper = Type Helper for Single
+ Function GetB(AIndex: Cardinal): Byte;
+ Function GetW(AIndex: Cardinal): Word;
+ Function GetE: QWord; inline;
+ Function GetF: QWord; inline;
+ Function GetS: Boolean; inline;
+ procedure SetB(AIndex: Cardinal; const AValue: Byte);
+ procedure SetW(AIndex: Cardinal; const AValue: Word);
+ procedure SetE(AValue: QWord);
+ procedure SetF(AValue: QWord);
+ procedure SetS(AValue: Boolean);
+ public
+{$push}
+{$R-}
+{$Q-}
+ const
+ Epsilon : Single = 1.4012984643248170709e-45;
+ MaxValue : Single = 340282346638528859811704183484516925440.0;
+ MinValue : Single = -340282346638528859811704183484516925440.0;
+ PositiveInfinity : Single = 1.0/0.0;
+ NegativeInfinity : Single = -1.0/0.0;
+ NaN : Single = 0.0/0.0;
+{$POP}
+ Class Function IsNan(const AValue: Single): Boolean; overload; inline; static;
+ Class Function IsInfinity(const AValue: Single): Boolean; overload; inline; static;
+ Class Function IsNegativeInfinity(const AValue: Single): Boolean; overload; inline; static;
+ Class Function IsPositiveInfinity(const AValue: Single): Boolean; overload; inline; static;
+ Class Function Parse(const AString: string): Single; overload; inline; static;
+ Class Function Parse(const AString: string; const AFormatSettings: TFormatSettings): Single; overload; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Single): string; overload; inline; static;
+ Class Function ToString(const AValue: Single; const AFormatSettings: TFormatSettings): string; overload; inline; static;
+ Class Function ToString(const AValue: Single; const AFormat: TFloatFormat; const APrecision, ADigits: Integer): string; overload; inline; static;
+ Class Function ToString(const AValue: Single; const AFormat: TFloatFormat; const APrecision, ADigits: Integer;
+ const AFormatSettings: TFormatSettings): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Single): Boolean; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Single; const AFormatSettings: TFormatSettings): Boolean; overload; inline; static;
+
+ Procedure BuildUp(const ASignFlag: Boolean; const AMantissa: QWord; const AExponent: Integer);
+ Function Exponent: Integer;
+ Function Fraction: Extended;
+ Function IsInfinity: Boolean; overload; inline;
+ Function IsNan: Boolean; overload; inline;
+ Function IsNegativeInfinity: Boolean; overload; inline;
+ Function IsPositiveInfinity: Boolean; overload; inline;
+ Function Mantissa: QWord;
+ Function SpecialType: TFloatSpecial;
+ Function ToString(const AFormat: TFloatFormat; const APrecision, ADigits: Integer): string; overload; inline;
+ Function ToString(const AFormat: TFloatFormat; const APrecision, ADigits: Integer; const AFormatSettings: TFormatSettings): string; overload; inline;
+ Function ToString(const AFormatSettings: TFormatSettings): string; overload; inline;
+ Function ToString: string; overload; inline;
+
+ property Bytes[AIndex: Cardinal]: Byte read GetB write SetB;
+ property Words[AIndex: Cardinal]: Word read GetW write SetW;
+ property Sign: Boolean read GetS write SetS;
+ property Exp: QWord read GetE write SetE;
+ property Frac: QWord read GetF write SetF;
+ end;
+{$ENDIF FPC_HAS_TYPE_SINGLE}
+
+{$IFDEF FPC_HAS_TYPE_DOUBLE}
+ TDoubleHelper = Type Helper for Double
+ private
+ Function GetB(AIndex: Cardinal): Byte;
+ Function GetW(AIndex: Cardinal): Word;
+ Function GetE: QWord; inline;
+ Function GetF: QWord; inline;
+ Function GetS: Boolean; inline;
+ procedure SetB(AIndex: Cardinal; const AValue: Byte);
+ procedure SetW(AIndex: Cardinal; const AValue: Word);
+ procedure SetE(AValue: QWord);
+ procedure SetF(AValue: QWord);
+ procedure SetS(AValue: Boolean);
+ public
+ const
+ {$push}
+ {$R-}
+ {$Q-}
+ Epsilon : Double = 4.9406564584124654418e-324;
+ MaxValue : Double = 1.7976931348623157081e+308;
+ MinValue : Double = -1.7976931348623157081e+308;
+ PositiveInfinity : Double = 1.0/0.0;
+ NegativeInfinity : Double = -1.0/0.0;
+ NaN : Double = 0.0/0.0;
+ {$POP}
+ Class Function IsInfinity(const AValue: Double): Boolean; overload; inline; static;
+ Class Function IsNan(const AValue: Double): Boolean; overload; inline; static;
+ Class Function IsNegativeInfinity(const AValue: Double): Boolean; overload; inline; static;
+ Class Function IsPositiveInfinity(const AValue: Double): Boolean; overload; inline; static;
+ Class Function Parse(const AString: string): Double; overload; inline; static;
+ Class Function Parse(const AString: string; const AFormatSettings: TFormatSettings): Double; overload; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Double): string; overload; inline; static;
+ Class Function ToString(const AValue: Double; const AFormat: TFloatFormat; const APrecision, ADigits: Integer): string; overload; inline; static;
+ Class Function ToString(const AValue: Double; const AFormat: TFloatFormat; const APrecision, ADigits: Integer; const AFormatSettings: TFormatSettings): string; overload; inline; static;
+ Class Function ToString(const AValue: Double; const AFormatSettings: TFormatSettings): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Double): Boolean; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Double; const AFormatSettings: TFormatSettings): Boolean; overload; inline; static;
+
+ Procedure BuildUp(const ASignFlag: Boolean; const AMantissa: QWord; const AExponent: Integer);
+ Function Exponent: Integer;
+ Function Fraction: Extended;
+ Function IsInfinity: Boolean; overload; inline;
+ Function IsNan: Boolean; overload; inline;
+ Function IsNegativeInfinity: Boolean; overload; inline;
+ Function IsPositiveInfinity: Boolean; overload; inline;
+ Function Mantissa: QWord;
+ Function SpecialType: TFloatSpecial;
+ Function ToString(const AFormat: TFloatFormat; const APrecision, ADigits: Integer): string; overload; inline;
+ Function ToString(const AFormat: TFloatFormat; const APrecision, ADigits: Integer; const AFormatSettings: TFormatSettings): string; overload; inline;
+ Function ToString(const AFormatSettings: TFormatSettings): string; overload; inline;
+ Function ToString: string; overload; inline;
+
+ property Bytes[AIndex: Cardinal]: Byte read GetB write SetB; // 0..7
+ property Words[AIndex: Cardinal]: Word read GetW write SetW; // 0..3
+ property Sign: Boolean read GetS write SetS;
+ property Exp: QWord read GetE write SetE;
+ property Frac: QWord read GetF write SetF;
+ end;
+{$ENDIF FPC_HAS_TYPE_DOUBLE}
+
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+ TExtendedHelper = Type Helper for Extended
+ private
+ Function GetB(AIndex: Cardinal): Byte;
+ Function GetW(AIndex: Cardinal): Word;
+ Function GetE: QWord; inline;
+ Function GetF: QWord; inline;
+ Function GetS: Boolean; inline;
+ procedure SetB(AIndex: Cardinal; const AValue: Byte);
+ procedure SetW(AIndex: Cardinal; const AValue: Word);
+ procedure SetE(AValue: QWord);
+ procedure SetF(AValue: QWord);
+ procedure SetS(AValue: Boolean);
+ public
+ {$push}
+ {$R-}
+ {$Q-}
+ const
+ Epsilon : Extended = 3.64519953188247460253e-4951;
+ MaxValue : Extended = 1.18973149535723176505e+4932;
+ MinValue : Extended = -1.18973149535723176505e+4932;
+ PositiveInfinity : Extended = 1.0/0.0;
+ NegativeInfinity : Extended = -1.0/0.0;
+ NaN : Extended = 0.0/0.0;
+ {$POP}
+ Class Function ToString(const AValue: Extended): string; overload; inline; static;
+ Class Function ToString(const AValue: Extended; const AFormatSettings: TFormatSettings): string; overload; inline; static;
+ Class Function ToString(const AValue: Extended; const AFormat: TFloatFormat; const APrecision, ADigits: Integer): string; overload; inline; static;
+ Class Function ToString(const AValue: Extended; const AFormat: TFloatFormat; const APrecision, ADigits: Integer; const AFormatSettings: TFormatSettings): string; overload; inline; static;
+ Class Function Parse(const AString: string): Extended; overload; inline; static;
+ Class Function Parse(const AString: string; const AFormatSettings: TFormatSettings): Extended; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Extended): Boolean; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Extended; const AFormatSettings: TFormatSettings): Boolean; overload; inline; static;
+ Class Function IsNan(const AValue: Extended): Boolean; overload; inline; static;
+ Class Function IsInfinity(const AValue: Extended): Boolean; overload; inline; static;
+ Class Function IsNegativeInfinity(const AValue: Extended): Boolean; overload; inline; static;
+ Class Function IsPositiveInfinity(const AValue: Extended): Boolean; overload; inline; static;
+ Class Function Size: Integer; inline; static;
+
+ procedure BuildUp(const ASignFlag: Boolean; const AMantissa: QWord; Const AExponent: Integer);
+ Function Exponent: Integer;
+ Function Fraction: Extended;
+ Function IsInfinity: Boolean; overload; inline;
+ Function IsNan: Boolean; overload; inline;
+ Function IsNegativeInfinity: Boolean; overload; inline;
+ Function IsPositiveInfinity: Boolean; overload; inline;
+ Function Mantissa: QWord;
+ Function SpecialType: TFloatSpecial;
+ Function ToString(const AFormat: TFloatFormat; const APrecision, ADigits: Integer): string; overload; inline;
+ Function ToString(const AFormat: TFloatFormat; const APrecision, ADigits: Integer; const AFormatSettings: TFormatSettings): string; overload; inline;
+ Function ToString(const AFormatSettings: TFormatSettings): string; overload; inline;
+ Function ToString: string; overload; inline;
+
+ property Bytes[AIndex: Cardinal]: Byte read GetB write SetB;
+ property Words[AIndex: Cardinal]: Word read GetW write SetW;
+ property Sign: Boolean read GetS write SetS;
+ property Exp: QWord read GetE write SetE;
+ property Frac: QWord read GetF write SetF;
+ end;
+{$ENDIF FPC_HAS_TYPE_EXTENDED}
+
+ TByteHelper = Type Helper for Byte
+ public
+ const
+ MaxValue = 255;
+ MinValue = 0;
+ public
+ Class Function Parse(const AString: string): Byte; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Byte): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Byte): Boolean; inline; static;
+ Public
+ Function ToBoolean: Boolean; inline;
+ Function ToDouble: Double; inline;
+ Function ToExtended: Extended; inline;
+ Function ToHexString(const AMinDigits: Integer): string; overload; inline;
+ Function ToHexString: string; overload; inline;
+ Function ToSingle: Single; inline;
+ Function ToString: string; overload; inline;
+ end;
+
+ TShortIntHelper = Type Helper for ShortInt
+ public
+ const
+ MaxValue = 127;
+ MinValue = -128;
+ public
+ Class Function Parse(const AString: string): ShortInt; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: ShortInt): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: ShortInt): Boolean; inline; static;
+ public
+ Function ToBoolean: Boolean; inline;
+ Function ToDouble: Double; inline;
+ Function ToExtended: Extended; inline;
+ Function ToHexString(const AMinDigits: Integer): string; overload; inline;
+ Function ToHexString: string; overload; inline;
+ Function ToSingle: Single; inline;
+ Function ToString: string; overload; inline;
+ end;
+
+ TSmallIntHelper = Type Helper for SmallInt
+ public
+ const
+ MaxValue = 32767;
+ MinValue = -32768;
+ public
+ Class Function Parse(const AString: string): SmallInt; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: SmallInt): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: SmallInt): Boolean; inline; static;
+ public
+ Function ToString: string; overload; inline;
+ Function ToBoolean: Boolean; inline;
+ Function ToHexString: string; overload; inline;
+ Function ToHexString(const AMinDigits: Integer): string; overload; inline;
+ Function ToSingle: Single; inline;
+ Function ToDouble: Double; inline;
+ Function ToExtended: Extended; inline;
+ end;
+
+ TWordHelper = Type Helper for Word
+ public
+ const
+ MaxValue = 65535;
+ MinValue = 0;
+ Public
+ Class Function Parse(const AString: string): Word; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Word): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Word): Boolean; inline; static;
+ Public
+ Function ToBoolean: Boolean; inline;
+ Function ToDouble: Double; inline;
+ Function ToExtended: Extended; inline;
+ Function ToHexString(const AMinDigits: Integer): string; overload; inline;
+ Function ToHexString: string; overload; inline;
+ Function ToSingle: Single; inline;
+ Function ToString: string; overload; inline;
+ end;
+
+ TCardinalHelper = Type Helper for Cardinal { for LongWord Type too }
+ public
+ const
+ MaxValue = 4294967295;
+ MinValue = 0;
+ Public
+ Class Function Parse(const AString: string): Cardinal; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Cardinal): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Cardinal): Boolean; inline; static;
+ Public
+ Function ToBoolean: Boolean; inline;
+ Function ToDouble: Double; inline;
+ Function ToExtended: Extended; inline;
+ Function ToHexString(const AMinDigits: Integer): string; overload; inline;
+ Function ToHexString: string; overload; inline;
+ Function ToSingle: Single; inline;
+ Function ToString: string; overload; inline;
+ end;
+
+ TIntegerHelper = Type Helper for Integer { for LongInt Type too }
+ public
+ const
+ MaxValue = 2147483647;
+ MinValue = -2147483648;
+ Public
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Integer): string; overload; inline; static;
+ Class Function Parse(const AString: string): Integer; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Integer): Boolean; inline; static;
+ Public
+ Function ToBoolean: Boolean; inline;
+ Function ToDouble: Double; inline;
+ Function ToExtended: Extended; inline;
+ Function ToHexString(const AMinDigits: Integer): string; overload; inline;
+ Function ToHexString: string; overload; inline;
+ Function ToSingle: Single; inline;
+ Function ToString: string; overload; inline;
+ end;
+
+ TInt64Helper = Type Helper for Int64
+ public
+ const
+ MaxValue = 9223372036854775807;
+ MinValue = -9223372036854775808;
+ Public
+ Class Function Parse(const AString: string): Int64; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Int64): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: Int64): Boolean; inline; static;
+ Public
+ Function ToBoolean: Boolean; inline;
+ Function ToDouble: Double; inline;
+ Function ToExtended: Extended; inline;
+ Function ToHexString(const AMinDigits: Integer): string; overload; inline;
+ Function ToHexString: string; overload; inline;
+ Function ToSingle: Single; inline;
+ Function ToString: string; overload; inline;
+ end;
+
+ TQWordHelper = Type Helper for QWord
+ public
+ const
+ MaxValue = 18446744073709551615;
+ MinValue = 0;
+ Public
+ Class Function Parse(const AString: string): QWord; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: QWord): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: QWord): Boolean; inline; static;
+ Public
+ Function ToBoolean: Boolean; inline;
+ Function ToDouble: Double; inline;
+ Function ToExtended: Extended; inline;
+ Function ToHexString(const AMinDigits: Integer): string; overload; inline;
+ Function ToHexString: string; overload; inline;
+ Function ToSingle: Single; inline;
+ Function ToString: string; overload; inline;
+ end;
+
+ TNativeIntHelper = Type Helper for NativeInt
+ public
+ const
+{$IFDEF CPU64BITS}
+ MaxValue = 9223372036854775807;
+ MinValue = -9223372036854775808;
+{$ELSE !CPU64BITS}
+ MaxValue = 2147483647;
+ MinValue = -2147483648;
+{$ENDIF CPU64BITS}
+ Public
+ Class Function Parse(const AString: string): NativeInt; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: NativeInt): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: NativeInt): Boolean; inline; static;
+ Public
+ Function ToBoolean: Boolean; inline;
+ Function ToDouble: Double; inline;
+ Function ToExtended: Extended; inline;
+ Function ToHexString(const AMinDigits: Integer): string; overload; inline;
+ Function ToHexString: string; overload; inline;
+ Function ToSingle: Single; inline;
+ Function ToString: string; overload; inline;
+ end;
+
+ TNativeUIntHelper = Type Helper for NativeUInt
+ public
+ const
+{$IFDEF CPU64BITS}
+ MaxValue = 18446744073709551615;
+{$ELSE !CPU64BITS}
+ MaxValue = 4294967295;
+{$ENDIF CPU64BITS}
+ MinValue = 0;
+ Public
+ Class Function Parse(const AString: string): NativeUInt; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: NativeUInt): string; overload; inline; static;
+ Class Function TryParse(const AString: string; out AValue: NativeUInt): Boolean; inline; static;
+ Public
+ Function ToBoolean: Boolean; inline;
+ Function ToDouble: Double; inline;
+ Function ToExtended: Extended; inline;
+ Function ToHexString(const AMinDigits: Integer): string; overload; inline;
+ Function ToHexString: string; overload; inline;
+ Function ToSingle: Single; inline;
+ Function ToString: string; overload; inline;
+ end;
+
+ {$SCOPEDENUMS ON}
+ TUseBoolStrs = (False, True);
+ {$SCOPEDENUMS OFF}
+
+ TBooleanHelper = Type Helper for Boolean
+ public
+ Class Function Parse(const S: string): Boolean; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Boolean; UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline; static;
+ Class Function TryToParse(const S: string; out AValue: Boolean): Boolean; inline; static;
+ Public
+ Function ToInteger: Integer; inline;
+ Function ToString(UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline;
+ end;
+
+ TByteBoolHelper = Type Helper for ByteBool
+ public
+ Class Function Parse(const S: string): Boolean; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Boolean; UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline; static;
+ Class Function TryToParse(const S: string; out AValue: Boolean): Boolean; inline; static;
+ Public
+ Function ToInteger: Integer; inline;
+ Function ToString(UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline;
+ end;
+
+ TWordBoolHelper = Type Helper for WordBool
+ public
+ Class Function Parse(const S: string): Boolean; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Boolean; UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline; static;
+ Class Function TryToParse(const S: string; out AValue: Boolean): Boolean; inline; static;
+ Public
+ Function ToInteger: Integer; inline;
+ Function ToString(UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline;
+ end;
+
+ TLongBoolHelper = Type Helper for LongBool
+ public
+ Class Function Parse(const S: string): Boolean; inline; static;
+ Class Function Size: Integer; inline; static;
+ Class Function ToString(const AValue: Boolean; UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline; static;
+ Class Function TryToParse(const S: string; out AValue: Boolean): Boolean; inline; static;
+ public
+ Function ToInteger: Integer; inline;
+ Function ToString(UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline;
+ end;
diff --git a/rtl/objpas/sysutils/syshelpo.inc b/rtl/objpas/sysutils/syshelpo.inc
new file mode 100644
index 0000000000..b46896983c
--- /dev/null
+++ b/rtl/objpas/sysutils/syshelpo.inc
@@ -0,0 +1,71 @@
+
+Class Function TORDINALHELPER.Parse(const AString: string): TORDINALTYPE; inline; static;
+
+begin
+ Result:=StrToInt(AString);
+end;
+
+Class Function TORDINALHELPER.Size: Integer; inline; static;
+
+begin
+ Result:=SizeOf(TORDINALTYPE);
+end;
+
+Class Function TORDINALHELPER.ToString(const AValue: TORDINALTYPE): string; overload; inline; static;
+
+begin
+ Result:=IntToStr(AValue);
+end;
+
+Class Function TORDINALHELPER.TryParse(const AString: string; out AValue: TORDINALTYPE): Boolean; inline; static;
+
+Var
+ C : Integer;
+
+begin
+ Val(AString,AValue,C);
+ Result:=(C=0);
+end;
+
+Function TORDINALHELPER.ToBoolean: Boolean; inline;
+
+begin
+ Result:=(Self<>0);
+end;
+
+Function TORDINALHELPER.ToDouble: Double; inline;
+
+begin
+ Result:=Self;
+end;
+
+Function TORDINALHELPER.ToExtended: Extended; inline;
+
+begin
+ Result:=Self;
+end;
+
+Function TORDINALHELPER.ToHexString(const AMinDigits: Integer): string;
+overload; inline;
+
+begin
+ Result:=HexStr(Self,AMinDigits);
+end;
+
+Function TORDINALHELPER.ToHexString: string; overload; inline;
+
+begin
+ Result:=HexStr(Self,SizeOf(TORDINALTYPE)*2);
+end;
+
+Function TORDINALHELPER.ToSingle: Single; inline;
+
+begin
+ Result:=Self;
+end;
+
+Function TORDINALHELPER.ToString: string; overload; inline;
+
+begin
+ Result:=IntToStr(Self);
+end;
diff --git a/rtl/objpas/sysutils/sysuni.inc b/rtl/objpas/sysutils/sysuni.inc
index 5d4bbd7df3..f4a4028788 100644
--- a/rtl/objpas/sysutils/sysuni.inc
+++ b/rtl/objpas/sysutils/sysuni.inc
@@ -108,25 +108,25 @@ function UnicodeLowerCase(const s : UnicodeString) : UnicodeString;{$ifdef SYSUT
function UnicodeCompareStr(const s1, s2 : UnicodeString) : PtrInt;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
- result:=widestringmanager.CompareUnicodeStringProc(s1,s2);
+ result:=widestringmanager.CompareUnicodeStringProc(s1,s2,[]);
end;
function UnicodeSameStr(const s1, s2 : UnicodeString) : Boolean;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
- result:=widestringmanager.CompareUnicodeStringProc(s1,s2)=0;
+ result:=widestringmanager.CompareUnicodeStringProc(s1,s2,[])=0;
end;
function UnicodeCompareText(const s1, s2 : UnicodeString) : PtrInt;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
- result:=widestringmanager.CompareTextUnicodeStringProc(s1,s2);
+ result:=widestringmanager.CompareUnicodeStringProc(s1,s2,[coIgnoreCase]);
end;
function UnicodeSameText(const s1, s2 : UnicodeString) : Boolean;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
- result:=widestringmanager.CompareTextUnicodeStringProc(s1,s2)=0;
+ result:=widestringmanager.CompareUnicodeStringProc(s1,s2,[coIgnoreCase])=0;
end;
diff --git a/rtl/objpas/sysutils/sysutilh.inc b/rtl/objpas/sysutils/sysutilh.inc
index 436f86083f..b6aa27b7f5 100644
--- a/rtl/objpas/sysutils/sysutilh.inc
+++ b/rtl/objpas/sysutils/sysutilh.inc
@@ -307,6 +307,9 @@ Type
{ read thread handling }
{$i systhrdh.inc}
+ { Type Helpers}
+ {$i syshelph.inc}
+
procedure FreeAndNil(var obj);
{ interface handling }
diff --git a/rtl/objpas/sysutils/sysutils.inc b/rtl/objpas/sysutils/sysutils.inc
index 75f9931e79..5950610d7b 100644
--- a/rtl/objpas/sysutils/sysutils.inc
+++ b/rtl/objpas/sysutils/sysutils.inc
@@ -39,7 +39,9 @@
{ variant error codes }
{$i varerror.inc}
-
+
+ { Type helpers}
+ {$i syshelp.inc}
{$ifndef OS_FILEISREADONLY}
Function FileIsReadOnly(const FileName: RawByteString): Boolean;
diff --git a/rtl/objpas/sysutils/syswide.inc b/rtl/objpas/sysutils/syswide.inc
index d73d51fca6..319916a935 100644
--- a/rtl/objpas/sysutils/syswide.inc
+++ b/rtl/objpas/sysutils/syswide.inc
@@ -64,25 +64,25 @@ function WideLowerCase(const s : WideString) : WideString;{$ifdef SYSUTILSINLINE
function WideCompareStr(const s1, s2 : WideString) : PtrInt;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
- result:=widestringmanager.CompareWideStringProc(s1,s2);
+ result:=widestringmanager.CompareWideStringProc(s1,s2,[]);
end;
function WideSameStr(const s1, s2 : WideString) : Boolean;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
- result:=widestringmanager.CompareWideStringProc(s1,s2)=0;
+ result:=widestringmanager.CompareWideStringProc(s1,s2,[])=0;
end;
function WideCompareText(const s1, s2 : WideString) : PtrInt;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
- result:=widestringmanager.CompareTextWideStringProc(s1,s2);
+ result:=widestringmanager.CompareWideStringProc(s1,s2,[coIgnoreCase]);
end;
function WideSameText(const s1, s2 : WideString) : Boolean;{$ifdef SYSUTILSINLINE}inline;{$endif}
begin
- result:=widestringmanager.CompareTextWideStringProc(s1,s2)=0;
+ result:=widestringmanager.CompareWideStringProc(s1,s2,[coIgnoreCase])=0;
end;
diff --git a/rtl/os2/sysucode.inc b/rtl/os2/sysucode.inc
index 68bdc1706c..058a12e0c2 100644
--- a/rtl/os2/sysucode.inc
+++ b/rtl/os2/sysucode.inc
@@ -1252,13 +1252,19 @@ begin
end;
-function OS2CompareUnicodeString (const S1, S2: UnicodeString): PtrInt;
+function OS2CompareUnicodeString (const S1, S2: UnicodeString; Options : TCompareOptions): PtrInt;
var
HS1, HS2: UnicodeString;
+
begin
{ UniStrColl interprets null chars as end-of-string -> filter out }
HS1 := NoNullsUnicodeString (S1);
HS2 := NoNullsUnicodeString (S2);
+ if coIgnoreCase in Options then
+ begin
+ HS1:=OS2UpperUnicodeString(HS1);
+ HS2:=OS2UpperUnicodeString(HS2);
+ end;
Result := Sys_UniStrColl (DefLocObj, PWideChar (HS1), PWideChar (HS2));
if Result < -1 then
Result := -1
@@ -1694,15 +1700,12 @@ begin
WideStringManager.UpperWideStringProc := @OS2UpperUnicodeString;
WideStringManager.LowerWideStringProc := @OS2LowerUnicodeString;
WideStringManager.CompareWideStringProc := @OS2CompareUnicodeString;
- WideStringManager.CompareTextWideStringProc := @OS2CompareTextUnicodeString;
{ Unicode }
WideStringManager.Unicode2AnsiMoveProc := @OS2Unicode2AnsiMove;
WideStringManager.Ansi2UnicodeMoveProc := @OS2Ansi2UnicodeMove;
WideStringManager.UpperUnicodeStringProc := @OS2UpperUnicodeString;
WideStringManager.LowerUnicodeStringProc := @OS2LowerUnicodeString;
WideStringManager.CompareUnicodeStringProc := @OS2CompareUnicodeString;
- WideStringManager.CompareTextUnicodeStringProc :=
- @OS2CompareTextUnicodeString;
{ Codepage }
WideStringManager.GetStandardCodePageProc := @OS2GetStandardCodePage;
(*
diff --git a/rtl/os2/sysutils.pp b/rtl/os2/sysutils.pp
index 65be7cfdb5..d1191a2662 100644
--- a/rtl/os2/sysutils.pp
+++ b/rtl/os2/sysutils.pp
@@ -21,6 +21,8 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
{$DEFINE HAS_SLEEP}
{$DEFINE HAS_OSERROR}
diff --git a/rtl/unix/cwstring.pp b/rtl/unix/cwstring.pp
index f6d1d70925..fa6405606e 100644
--- a/rtl/unix/cwstring.pp
+++ b/rtl/unix/cwstring.pp
@@ -766,36 +766,59 @@ function WideStringToUCS4StringNoNulls(const s : WideString) : UCS4String;
end;
-function CompareWideString(const s1, s2 : WideString) : PtrInt;
+function CompareWideString(const s1, s2 : WideString; Options : TCompareOptions) : PtrInt;
{$if not(defined (aix) and defined(cpupowerpc32))}
var
hs1,hs2 : UCS4String;
+ us1,us2 : WideString;
+
begin
{ wcscoll interprets null chars as end-of-string -> filter out }
- hs1:=WideStringToUCS4StringNoNulls(s1);
- hs2:=WideStringToUCS4StringNoNulls(s2);
+ if coIgnoreCase in Options then
+ begin
+ us1:=UpperWideString(s1);
+ us2:=UpperWideString(s2);
+ end
+ else
+ begin
+ us1:=s1;
+ us2:=s2;
+ end;
+ hs1:=WideStringToUCS4StringNoNulls(us1);
+ hs2:=WideStringToUCS4StringNoNulls(us2);
result:=wcscoll(pwchar_t(hs1),pwchar_t(hs2));
end;
{$else}
{ AIX/PPC32 has a 16 bit wchar_t }
var
i, len: longint;
+ us1,us2 : WideString;
hs1, hs2: array of widechar;
begin
- len:=length(s1);
+ if coIgnoreCase in Options then
+ begin
+ us1:=UpperWideString(s1);
+ us2:=UpperWideString(s2);
+ end
+ else
+ begin
+ us1:=s1;
+ us2:=s2;
+ end;
+ len:=length(us1);
setlength(hs1,len+1);
for i:=1 to len do
- if s1[i]<>#0 then
- hs1[i-1]:=s1[i]
+ if us1[i]<>#0 then
+ hs1[i-1]:=us1[i]
else
hs1[i-1]:=#32;
hs1[len]:=#0;
- len:=length(s2);
+ len:=length(us2);
setlength(hs2,len+1);
for i:=1 to len do
- if s2[i]<>#0 then
- hs2[i-1]:=s2[i]
+ if us2[i]<>#0 then
+ hs2[i-1]:=us2[i]
else
hs2[i-1]:=#32;
hs2[len]:=#0;
@@ -804,11 +827,6 @@ function CompareWideString(const s1, s2 : WideString) : PtrInt;
{$endif}
-function CompareTextWideString(const s1, s2 : WideString): PtrInt;
- begin
- result:=CompareWideString(UpperWideString(s1),UpperWideString(s2));
- end;
-
{ return value: number of code points in the string. Whenever an invalid
code point is encountered, all characters part of this invalid code point
@@ -1080,7 +1098,7 @@ begin
LowerWideStringProc:=@LowerWideString;
CompareWideStringProc:=@CompareWideString;
- CompareTextWideStringProc:=@CompareTextWideString;
+// CompareTextWideStringProc:=@CompareTextWideString;
CharLengthPCharProc:=@CharLengthPChar;
CodePointLengthProc:=@CodePointLength;
@@ -1103,7 +1121,6 @@ begin
UpperUnicodeStringProc:=@UpperWideString;
LowerUnicodeStringProc:=@LowerWideString;
CompareUnicodeStringProc:=@CompareWideString;
- CompareTextUnicodeStringProc:=@CompareTextWideString;
{ CodePage }
GetStandardCodePageProc:=@GetStandardCodePage;
end;
diff --git a/rtl/unix/sysutils.pp b/rtl/unix/sysutils.pp
index 211211bd3b..8877eead6f 100644
--- a/rtl/unix/sysutils.pp
+++ b/rtl/unix/sysutils.pp
@@ -20,6 +20,8 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
{$if (defined(BSD) or defined(SUNOS)) and defined(FPC_USE_LIBC)}
{$define USE_VFORK}
diff --git a/rtl/watcom/sysutils.pp b/rtl/watcom/sysutils.pp
index d5f8b48bf8..aa45838c21 100644
--- a/rtl/watcom/sysutils.pp
+++ b/rtl/watcom/sysutils.pp
@@ -23,6 +23,8 @@ interface
{$modeswitch out}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
uses
watcom,dos;
diff --git a/rtl/wii/sysutils.pp b/rtl/wii/sysutils.pp
index ed70344747..99e3ac9b3e 100644
--- a/rtl/wii/sysutils.pp
+++ b/rtl/wii/sysutils.pp
@@ -28,6 +28,9 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
+
{$DEFINE HAS_SLEEP}
{ used OS file system APIs use ansistring }
{$define SYSUTILS_HAS_ANSISTR_FILEUTIL_IMPL}
diff --git a/rtl/win/sysutils.pp b/rtl/win/sysutils.pp
index 76af549890..c7d76326f9 100644
--- a/rtl/win/sysutils.pp
+++ b/rtl/win/sysutils.pp
@@ -21,6 +21,8 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
uses
windows;
@@ -1283,10 +1285,25 @@ function DoCompareStringW(P1, P2: PWideChar; L1, L2: PtrUInt; Flags: DWORD): Ptr
RaiseLastOSError;
end;
-function Win32CompareWideString(const s1, s2 : WideString) : PtrInt;
- begin
- Result:=DoCompareStringW(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), 0);
- end;
+const
+ WinAPICompareFlags : array [TCompareOption] of LongWord
+ = (LINGUISTIC_IGNORECASE, LINGUISTIC_IGNOREDIACRITIC, NORM_IGNORECASE,
+ NORM_IGNOREKANATYPE, NORM_IGNORENONSPACE, NORM_IGNORESYMBOLS, NORM_IGNOREWIDTH,
+ NORM_LINGUISTIC_CASING, SORT_DIGITSASNUMBERS, SORT_STRINGSORT);
+
+function Win32CompareWideString(const s1, s2 : WideString; Options : TCompareOptions) : PtrInt;
+
+Var
+ O : LongWord;
+ CO : TCompareOption;
+
+begin
+ O:=0;
+ for CO in TCompareOption do
+ if CO in Options then
+ O:=O or WinAPICompareFlags[CO];
+ Result:=DoCompareStringW(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), O);
+end;
function Win32CompareTextWideString(const s1, s2 : WideString) : PtrInt;
@@ -1372,10 +1389,19 @@ function Win32AnsiStrUpper(Str: PChar): PChar;
result:=str;
end;
-function Win32CompareUnicodeString(const s1, s2 : UnicodeString) : PtrInt;
- begin
- Result:=DoCompareStringW(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), 0);
- end;
+function Win32CompareUnicodeString(const s1, s2 : UnicodeString; Options : TCompareOptions) : PtrInt;
+
+Var
+ O : LongWord;
+ CO : TCompareOption;
+
+begin
+ O:=0;
+ for CO in TCompareOption do
+ if CO in Options then
+ O:=O or WinAPICompareFlags[CO];
+ Result:=DoCompareStringW(PWideChar(s1), PWideChar(s2), Length(s1), Length(s2), O);
+end;
function Win32CompareTextUnicodeString(const s1, s2 : UnicodeString) : PtrInt;
@@ -1399,7 +1425,6 @@ procedure InitWin32Widestrings;
> 0 if that's the length in bytes of the code point }
//!!!! CodePointLengthProc : function(const Str: PChar; MaxLookAead: PtrInt): Ptrint;
widestringmanager.CompareWideStringProc:=@Win32CompareWideString;
- widestringmanager.CompareTextWideStringProc:=@Win32CompareTextWideString;
widestringmanager.UpperAnsiStringProc:=@Win32AnsiUpperCase;
widestringmanager.LowerAnsiStringProc:=@Win32AnsiLowerCase;
widestringmanager.CompareStrAnsiStringProc:=@Win32AnsiCompareStr;
@@ -1411,7 +1436,6 @@ procedure InitWin32Widestrings;
widestringmanager.StrLowerAnsiStringProc:=@Win32AnsiStrLower;
widestringmanager.StrUpperAnsiStringProc:=@Win32AnsiStrUpper;
widestringmanager.CompareUnicodeStringProc:=@Win32CompareUnicodeString;
- widestringmanager.CompareTextUnicodeStringProc:=@Win32CompareTextUnicodeString;
end;
{ Platform-specific exception support }
diff --git a/rtl/win/wininc/defines.inc b/rtl/win/wininc/defines.inc
index 5a7a021357..83b9f8518b 100644
--- a/rtl/win/wininc/defines.inc
+++ b/rtl/win/wininc/defines.inc
@@ -332,6 +332,7 @@
NORM_IGNOREKANATYPE = $00010000;
NORM_IGNOREWIDTH = $00020000;
NORM_LINGUISTIC_CASING = $08000000;
+ SORT_DIGITSASNUMBERS = $00000008;
SORT_STRINGSORT = 4096;
LCMAP_BYTEREV = 2048;
LCMAP_FULLWIDTH = 8388608;
diff --git a/rtl/wince/sysutils.pp b/rtl/wince/sysutils.pp
index 65a30a0760..6990aa6255 100644
--- a/rtl/wince/sysutils.pp
+++ b/rtl/wince/sysutils.pp
@@ -21,6 +21,8 @@ interface
{$MODESWITCH OUT}
{ force ansistrings }
{$H+}
+{$modeswitch typehelpers}
+{$modeswitch advancedrecords}
uses
dos,
diff --git a/utils/tply/lextable.pas b/utils/tply/lextable.pas
index 06fd90e0d1..1902196fc3 100644
--- a/utils/tply/lextable.pas
+++ b/utils/tply/lextable.pas
@@ -77,7 +77,7 @@ type
SymTable = array [1..max_keys] of record
pname : StrPtr;
(* print name; empty entries are denoted by pname=nil *)
- case sym_type : ( none, macro_sym, start_state_sym ) of
+ case sym_type : ( none_sym, macro_sym, start_state_sym ) of
macro_sym : ( subst : StrPtr );
(* macro substitution *)
start_state_sym : ( start_state : Integer );
@@ -212,7 +212,7 @@ procedure entry(k : Integer; symbol : String);
with sym_table^[k] do
begin
pname := newStr(symbol);
- sym_type := none;
+ sym_type := none_sym;
end
end(*entry*);
diff --git a/utils/tply/plex.pas b/utils/tply/plex.pas
index 88939a1db9..df2aefd1d3 100644
--- a/utils/tply/plex.pas
+++ b/utils/tply/plex.pas
@@ -96,7 +96,7 @@ procedure define_start_state ( symbol : String; pos : Integer );
{$else}
with sym_table^[key(symbol, max_keys, lookup, entry)] do
{$endif}
- if sym_type=none then
+ if sym_type=none_sym then
begin
inc(n_start_states);
if n_start_states>max_start_states then
@@ -119,7 +119,7 @@ procedure define_macro ( symbol, replacement : String );
{$else}
with sym_table^[key('{'+symbol+'}', max_keys, lookup, entry)] do
{$endif}
- if sym_type=none then
+ if sym_type=none_sym then
begin
sym_type := macro_sym;
subst := newStr(strip(replacement));