瀏覽代碼

# revisions: 46531,46744,46747,47288,47327,47366,47392,47393,47414

git-svn-id: branches/fixes_3_2@47725 -
marco 4 年之前
父節點
當前提交
0feee25b1e

+ 22 - 0
packages/fcl-res/src/coffconsts.pp

@@ -56,6 +56,7 @@ const
   IMAGE_FILE_MACHINE_EBC             = $0EBC;  // EFI Byte Code
   IMAGE_FILE_MACHINE_EBC             = $0EBC;  // EFI Byte Code
 }
 }
   IMAGE_FILE_MACHINE_AMD64           = $8664;  // AMD64 (K8)
   IMAGE_FILE_MACHINE_AMD64           = $8664;  // AMD64 (K8)
+  IMAGE_FILE_MACHINE_ARM64           = $aa64;  // ARM64 little endian
 {
 {
   IMAGE_FILE_MACHINE_M32R            = $9041;  // M32R little-endian
   IMAGE_FILE_MACHINE_M32R            = $9041;  // M32R little-endian
   IMAGE_FILE_MACHINE_CEE             = $C0EE;
   IMAGE_FILE_MACHINE_CEE             = $C0EE;
@@ -159,6 +160,27 @@ const
   IMAGE_REL_AMD64_PAIR          = $000F;
   IMAGE_REL_AMD64_PAIR          = $000F;
   IMAGE_REL_AMD64_SSPAN32       = $0010;  // 32 bit signed span-dependent value applied at link time
   IMAGE_REL_AMD64_SSPAN32       = $0010;  // 32 bit signed span-dependent value applied at link time
 
 
+// aarch64 relocation types
+
+  IMAGE_REL_ARM64_ABSOLUTE      = $0000;  // The relocation is ignored.
+  IMAGE_REL_ARM64_ADDR32        = $0001;  // The 32-bit VA of the target.
+  IMAGE_REL_ARM64_ADDR32NB      = $0002;  // The 32-bit RVA of the target.
+  IMAGE_REL_ARM64_BRANCH26      = $0003;  // The 26-bit relative displacement to the target, for B and BL instructions.
+  IMAGE_REL_ARM64_PAGEBASE_REL21= $0004;  // The page base of the target, for ADRP instruction.
+  IMAGE_REL_ARM64_REL21         = $0005;  // The 12-bit relative displacement to the target, for instruction ADR
+  IMAGE_REL_ARM64_PAGEOFFSET_12A= $0006;  // The 12-bit page offset of the target, for instructions ADD/ADDS (immediate) with zero shift.
+  IMAGE_REL_ARM64_PAGEOFFSET_12L= $0007;  // The 12-bit page offset of the target, for instruction LDR (indexed, unsigned immediate).
+  IMAGE_REL_ARM64_SECREL        = $0008;  // The 32-bit offset of the target from the beginning of its section. This is used to support debugging information and static thread local storage.
+  IMAGE_REL_ARM64_SECREL_LOW12A = $0009;  // Bit 0:11 of section offset of the target, for instructions ADD/ADDS (immediate) with zero shift.
+  IMAGE_REL_ARM64_SECREL_HIGH12A= $000A;  // Bit 12:23 of section offset of the target, for instructions ADD/ADDS (immediate) with zero shift.
+  IMAGE_REL_ARM64_SECREL_LOW12L = $000B;  // Bit 0:11 of section offset of the target, for instruction LDR (indexed, unsigned immediate).
+  IMAGE_REL_ARM64_TOKEN         = $000C;  // CLR token.
+  IMAGE_REL_ARM64_SECTION       = $000D;  // The 16-bit section index of the section that contains the target. This is used to support debugging information.
+  IMAGE_REL_ARM64_ADDR64        = $000E;  // The 64-bit VA of the relocation target.
+  IMAGE_REL_ARM64_BRANCH19      = $000F;  // The 19-bit offset to the relocation target, for conditional B instruction.
+  IMAGE_REL_ARM64_BRANCH14      = $0010;  // The 14-bit offset to the relocation target, for instructions TBZ and TBNZ.
+  IMAGE_REL_ARM64_REL32         = $0011;  // The 32-bit relative address from the byte following the relocation.
+
 // AIX PPC32/PPC64 relocation types.
 // AIX PPC32/PPC64 relocation types.
 
 
   IMAGE_REL_PPC_POS             = $1F00;  // A(sym) Positive Relocation
   IMAGE_REL_PPC_POS             = $1F00;  // A(sym) Positive Relocation

+ 1 - 1
packages/fcl-res/src/cofftypes.pp

@@ -20,7 +20,7 @@ unit cofftypes;
 interface
 interface
 
 
 type
 type
-  TCoffMachineType = (cmti386, cmtarm, cmtx8664, cmtppc32aix, cmtppc64aix);
+  TCoffMachineType = (cmti386, cmtarm, cmtx8664, cmtppc32aix, cmtppc64aix, cmtaarch64);
 
 
 type
 type
   TSectionName = array [0..7] of char;
   TSectionName = array [0..7] of char;

+ 5 - 2
packages/fcl-res/src/coffwriter.pp

@@ -452,6 +452,7 @@ begin
     cmti386     : Result.machine:=IMAGE_FILE_MACHINE_I386;
     cmti386     : Result.machine:=IMAGE_FILE_MACHINE_I386;
     cmtarm      : Result.machine:=IMAGE_FILE_MACHINE_ARM;
     cmtarm      : Result.machine:=IMAGE_FILE_MACHINE_ARM;
     cmtx8664    : Result.machine:=IMAGE_FILE_MACHINE_AMD64;
     cmtx8664    : Result.machine:=IMAGE_FILE_MACHINE_AMD64;
+    cmtaarch64  : Result.machine:=IMAGE_FILE_MACHINE_ARM64;
     cmtppc32aix : Result.machine:=IMAGE_FILE_MACHINE_POWERPC32_AIX;
     cmtppc32aix : Result.machine:=IMAGE_FILE_MACHINE_POWERPC32_AIX;
     cmtppc64aix : Result.machine:=IMAGE_FILE_MACHINE_POWERPC64_AIX;
     cmtppc64aix : Result.machine:=IMAGE_FILE_MACHINE_POWERPC64_AIX;
   end;
   end;
@@ -527,7 +528,7 @@ procedure TCoffResourceWriter.SetMachineType(AValue: TCoffMachineType);
 begin
 begin
   fMachineType:=AValue;
   fMachineType:=AValue;
 {$IFDEF ENDIAN_BIG}
 {$IFDEF ENDIAN_BIG}
-  if fMachineType in [cmti386,cmtx8664,cmtarm] then
+  if fMachineType in [cmti386,cmtx8664,cmtarm,cmtaarch64] then
     fOppositeEndianess:=true;
     fOppositeEndianess:=true;
 {$ELSE}
 {$ELSE}
   if fMachineType in [cmtppc32aix,cmtppc64aix] then
   if fMachineType in [cmtppc32aix,cmtppc64aix] then
@@ -536,7 +537,8 @@ begin
   case fMachineType of
   case fMachineType of
     cmti386,
     cmti386,
     cmtx8664,
     cmtx8664,
-    cmtarm:
+    cmtarm,
+    cmtaarch64:
       fSymStorageClass:=IMAGE_SYM_CLASS_STATIC;
       fSymStorageClass:=IMAGE_SYM_CLASS_STATIC;
     cmtppc32aix,
     cmtppc32aix,
     cmtppc64aix:
     cmtppc64aix:
@@ -737,6 +739,7 @@ begin
     cmti386     : reloctype:=IMAGE_REL_I386_DIR32NB;
     cmti386     : reloctype:=IMAGE_REL_I386_DIR32NB;
     cmtarm      : reloctype:=IMAGE_REL_ARM_ADDR32NB;
     cmtarm      : reloctype:=IMAGE_REL_ARM_ADDR32NB;
     cmtx8664    : reloctype:=IMAGE_REL_AMD64_ADDR32NB;
     cmtx8664    : reloctype:=IMAGE_REL_AMD64_ADDR32NB;
+    cmtaarch64  : reloctype:=IMAGE_REL_ARM64_ADDR32NB;
     cmtppc32aix : reloctype:=IMAGE_REL_PPC_POS;
     cmtppc32aix : reloctype:=IMAGE_REL_PPC_POS;
     cmtppc64aix : reloctype:=IMAGE_REL_PPC_POS;
     cmtppc64aix : reloctype:=IMAGE_REL_PPC_POS;
   end;
   end;

+ 16 - 37
packages/fcl-xml/src/sax_xml.pp

@@ -175,17 +175,6 @@ begin
             '<':
             '<':
               begin
               begin
                 Inc(BufferPos);
                 Inc(BufferPos);
-                if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='[') then 
-                begin
-                  Inc(BufferPos, 8);
-                  EnterNewScannerContext(scCData);
-                end
-                else if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='-') then 
-                begin
-                  Inc(BufferPos, 3);
-                  EnterNewScannerContext(scComment);
-                end
-                else
                 EnterNewScannerContext(scTag);
                 EnterNewScannerContext(scTag);
               end;
               end;
             else
             else
@@ -206,17 +195,6 @@ begin
             '<':
             '<':
               begin
               begin
                 Inc(BufferPos);
                 Inc(BufferPos);
-                if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='[') then 
-                begin
-                  Inc(BufferPos, 8);
-                  EnterNewScannerContext(scCData);
-                end
-                else if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='-') then 
-                begin
-                  Inc(BufferPos, 3);
-                  EnterNewScannerContext(scComment);
-                end
-                else
                 EnterNewScannerContext(scTag);
                 EnterNewScannerContext(scTag);
               end;
               end;
             else
             else
@@ -232,17 +210,6 @@ begin
             '<':
             '<':
               begin
               begin
                 Inc(BufferPos);
                 Inc(BufferPos);
-                if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='[') then 
-                begin
-                  Inc(BufferPos, 8);
-                  EnterNewScannerContext(scCData);
-                end
-                else if (Buffer[BufferPos]='!') and (Buffer[BufferPos + 1]='-') then 
-                begin
-                  Inc(BufferPos, 3);
-                  EnterNewScannerContext(scComment);
-                end
-                else
                 EnterNewScannerContext(scTag);
                 EnterNewScannerContext(scTag);
               end;
               end;
             else
             else
@@ -252,9 +219,15 @@ begin
             end;
             end;
           end;
           end;
         scCData:
         scCData:
-          if (Buffer[BufferPos] = ']') and (Buffer[BufferPos + 1]=']') and (Buffer[BufferPos + 2]='>') then 
+          if (Length(FRawTokenText) = 0) and (Buffer[BufferPos] = '-') then
+          begin
+            Inc(BufferPos);
+            EnterNewScannerContext(scComment);
+          end
+          else if (Buffer[BufferPos] = '>') and (RightStr(FRawTokenText, 2) = ']]') then
           begin
           begin
-            Inc(BufferPos, 3);
+            FRawTokenText := Copy(FRawTokenText, 8, Length(FRawTokenText)-9);  //delete '[CDATA[' and ']]' from text
+            Inc(BufferPos);
             EnterNewScannerContext(scUnknown);
             EnterNewScannerContext(scUnknown);
           end
           end
           else
           else
@@ -263,9 +236,10 @@ begin
             Inc(BufferPos);
             Inc(BufferPos);
           end;
           end;
         scComment:
         scComment:
-          if (Buffer[BufferPos] = '-') and (Buffer[BufferPos + 1]='-') and (Buffer[BufferPos + 2]='>') then  
+          if (Buffer[BufferPos] = '>') and (RightStr(FRawTokenText, 2) = '--') then
           begin
           begin
-            Inc(BufferPos, 3);
+            FRawTokenText := Copy(FRawTokenText, 2, Length(FRawTokenText)-3);  //delete '-' and '--' from text
+            Inc(BufferPos);
             EnterNewScannerContext(scUnknown);
             EnterNewScannerContext(scUnknown);
           end
           end
           else
           else
@@ -309,6 +283,11 @@ begin
                 FRawTokenText := FRawTokenText + Buffer[BufferPos];
                 FRawTokenText := FRawTokenText + Buffer[BufferPos];
                 Inc(BufferPos);
                 Inc(BufferPos);
               end;
               end;
+            '!':
+              begin
+                Inc(BufferPos);
+                EnterNewScannerContext(scCData);
+              end;
             '>':
             '>':
               begin
               begin
                 Inc(BufferPos);
                 Inc(BufferPos);

+ 2 - 2
packages/rtl-objpas/src/inc/strutils.pp

@@ -355,7 +355,7 @@ type
     i: SizeInt;
     i: SizeInt;
   begin
   begin
     i:=0;
     i:=0;
-    while (aPattern[aPos-i] = aPattern[aPatternSize-1-i]) and (i < aPos) do begin
+    while (i<aPos) and (aPattern[aPos-i] = aPattern[aPatternSize-1-i]) do begin
       inc(i);
       inc(i);
     end;
     end;
     Result:=i;
     Result:=i;
@@ -493,7 +493,7 @@ type
     i: SizeInt;
     i: SizeInt;
   begin
   begin
     i:=0;
     i:=0;
-    while (aPattern[aPos-i] = aPattern[aPatternSize-1-i]) and (i < aPos) do begin
+    while (i<aPos) and (aPattern[aPos-i] = aPattern[aPatternSize-1-i]) do begin
       inc(i);
       inc(i);
     end;
     end;
     Result:=i;
     Result:=i;

+ 163 - 2
packages/rtl-objpas/src/inc/widestrutils.pp

@@ -1,4 +1,18 @@
-unit WideStrUtils;
+{
+    Delphi/Kylix compatibility unit: String handling routines.
+
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2005 by the Free Pascal development team
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+unit widestrutils;
 
 
 {$mode objfpc}
 {$mode objfpc}
 {$H+}
 {$H+}
@@ -7,7 +21,7 @@ unit WideStrUtils;
 interface
 interface
 
 
 uses
 uses
-  SysUtils;
+  SysUtils, Classes;
 
 
 function WideStringReplace(const S, OldPattern, NewPattern: WideString; Flags: TReplaceFlags): WideString;
 function WideStringReplace(const S, OldPattern, NewPattern: WideString; Flags: TReplaceFlags): WideString;
 function WideReplaceStr(const AText, AFromText, AToText: WideString): WideString; inline;
 function WideReplaceStr(const AText, AFromText, AToText: WideString): WideString; inline;
@@ -17,9 +31,87 @@ function UnicodeStringReplace(const S, OldPattern, NewPattern: UnicodeString; Fl
 function UnicodeReplaceStr(const AText, AFromText, AToText: UnicodeString): UnicodeString; inline;
 function UnicodeReplaceStr(const AText, AFromText, AToText: UnicodeString): UnicodeString; inline;
 function UnicodeReplaceText(const AText, AFromText, AToText: UnicodeString): UnicodeString; inline;
 function UnicodeReplaceText(const AText, AFromText, AToText: UnicodeString): UnicodeString; inline;
 
 
+type
+  TEncodeType = (etUSASCII, etUTF8, etANSI);
+
+const
+  sUTF8BOMString: array[1..3] of char = (#$EF, #$BB, #$BF);
+
+function HasUTF8BOM(S: TStream): boolean; overload;
+function HasUTF8BOM(const S: RawByteString): boolean; overload;
+function HasExtendCharacter(const S: RawByteString): boolean;
+function DetectUTF8Encoding(const S: RawByteString): TEncodeType;
+function IsUTF8String(const S: RawByteString): boolean;
+
+type
+  TBufferUTF8State = (u8sUnknown, u8sYes, u8sNo);
+
+//PartialAllowed must be set to true if the buffer is smaller than the file.
+function IsBufferUTF8(buf: PAnsiChar; bufSize: SizeInt; PartialAllowed: boolean): TBufferUTF8State;
 
 
 implementation
 implementation
 
 
+{
+  The IsBufferUtf8 function code was created by Christian Ghisler (ghisler.com)
+  Christian gave code to open-source at Total Commander public forum
+}
+
+const bytesFromUTF8:array[AnsiChar] of byte = (
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  // 32
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  // 64
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  // 96
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  //128
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  //160
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  //192
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  //224
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5); //256
+
+
+function IsFirstUTF8Char(thechar:AnsiChar):boolean; inline;
+{The remaining bytes in a multi-byte sequence have 10 as their two most significant bits.}
+begin
+  result:=(byte(thechar) and (128+64))<>128;
+end;
+
+function IsSecondaryUTF8Char(thechar:AnsiChar):boolean; inline;
+{The remaining bytes in a multi-byte sequence have 10 as their two most significant bits.}
+begin
+  result:=(byte(thechar) and (128+64))=128;
+end;
+
+function IsBufferUTF8(buf: PAnsiChar; bufSize: SizeInt; PartialAllowed: boolean): TBufferUTF8State;
+{Buffer contains only valid UTF-8 characters, no secondary alone,
+no primary without the correct nr of secondary}
+var
+  p: PAnsiChar;
+  i: SizeInt;
+  utf8bytes: integer;
+  hadutf8bytes: boolean;
+begin
+  p:=buf;
+  hadutf8bytes:=false;
+  result:=u8sUnknown;
+  utf8bytes:=0;
+  for i:= 1 to bufSize do
+  begin
+    if utf8bytes>0 then
+    begin  {Expecting secondary AnsiChar}
+      hadutf8bytes:=true;
+      if not IsSecondaryUTF8Char(p^) then exit(u8sNo);  {Fail!}
+      dec(utf8bytes);
+    end
+    else
+    if IsFirstUTF8Char(p^) then
+      utf8bytes:=bytesFromUTF8[p^]
+    else
+    if IsSecondaryUTF8Char(p^) then
+      exit(u8sNo);  {Fail!}
+    inc(p);
+  end;
+  if hadutf8bytes and (PartialAllowed or (utf8bytes=0)) then
+    result:=u8sYes;
+end;
+
 function WideReplaceStr(const AText, AFromText, AToText: WideString): WideString; inline;
 function WideReplaceStr(const AText, AFromText, AToText: WideString): WideString; inline;
 begin
 begin
   Result := WideStringReplace(AText, AFromText, AToText, [rfReplaceAll]);
   Result := WideStringReplace(AText, AFromText, AToText, [rfReplaceAll]);
@@ -52,5 +144,74 @@ begin
   Result:= sysutils.UnicodeStringReplace(S,OldPattern,NewPattern,Flags);
   Result:= sysutils.UnicodeStringReplace(S,OldPattern,NewPattern,Flags);
 end;
 end;
 
 
+function HasUTF8BOM(S: TStream): boolean;
+var
+  OldPos: Int64;
+  Buf: array[1..3] of char;
+begin
+  Result := false;
+  if S.Size<3 then exit;
+  FillChar(Buf, SizeOf(Buf), 0);
+  try
+    OldPos := S.Position;
+    S.Position := 0;
+    if S.Read(Buf, 3)<>3 then exit;
+    Result :=
+      (Buf[1]=sUTF8BOMString[1]) and
+      (Buf[2]=sUTF8BOMString[2]) and
+      (Buf[3]=sUTF8BOMString[3]);
+  finally
+    S.Position := OldPos;
+  end;
+end;
+
+function HasUTF8BOM(const S: RawByteString): boolean;
+begin
+  Result := (Length(S)>=3) and
+    (S[1]=sUTF8BOMString[1]) and
+    (S[2]=sUTF8BOMString[2]) and
+    (S[3]=sUTF8BOMString[3]);
+end;
+
+function HasExtendCharacter(const S: RawByteString): boolean;
+var
+  i: integer;
+begin
+  for i := 1 to Length(S) do
+    if Ord(S[i])>=$80 then
+    begin
+      Result := true;
+      exit;
+    end;
+  Result := false;
+end;
+
+function DetectUTF8Encoding(const S: RawByteString): TEncodeType;
+var
+  FirstExtChar, i: integer;
+begin
+  FirstExtChar := 0;
+  for i := 1 to Length(S) do
+    if Ord(S[i])>=$80 then
+    begin
+      FirstExtChar := i;
+      Break;
+    end;
+
+  if FirstExtChar=0 then
+    Result := etUSASCII
+  else
+  if IsBufferUtf8(@S[FirstExtChar], Length(S)-FirstExtChar+1, false)=u8sYes then
+    Result := etUTF8
+  else
+    Result := etANSI;
+end;
+
+function IsUTF8String(const S: RawByteString): boolean;
+begin
+  Result := DetectUTF8Encoding(S) = etUTF8;
+end;
+
+
 end.
 end.
 
 

+ 23 - 52
rtl/objpas/classes/stringl.inc

@@ -547,6 +547,11 @@ var
   end;
   end;
 
 
   Function CheckQuoted : Boolean;
   Function CheckQuoted : Boolean;
+  { Paraphrased from Delphi XE2 help:
+    Strings must be separated by Delimiter characters or spaces.
+    They may be enclosed in QuoteChars.
+    QuoteChars in the string must be repeated to distinguish them from the QuoteChars enclosing the string.
+  }
 
 
   begin
   begin
     Result:=(AValue[i]=aQuoteChar) and (aQuoteChar<>#0);
     Result:=(AValue[i]=aQuoteChar) and (aQuoteChar<>#0);
@@ -567,60 +572,29 @@ var
     i:=j+1;
     i:=j+1;
   end;
   end;
 
 
-begin
- BeginUpdate;
-
- i:=1;
- j:=1;
- aNotFirst:=false;
+  Procedure MaybeSkipSpaces; inline;
 
 
- { Paraphrased from Delphi XE2 help:
- Strings must be separated by Delimiter characters or spaces.
- They may be enclosed in QuoteChars.
- QuoteChars in the string must be repeated to distinguish them from the QuoteChars enclosing the string.
- }
- try
-  if DoClear then
-    Clear;
-  len:=length(AValue);
-  If aStrictDelimiter then
-    begin
-    while i<=len do
-      begin
-      // skip delimiter
-      if aNotFirst and (i<=len) and (AValue[i]=aDelimiter) then
+  begin
+    if Not aStrictDelimiter then
+      while (i<=len) and (Ord(AValue[i])<=Ord(' ')) do
         inc(i);
         inc(i);
-      // read next string
-      if i>len then
-        begin
-        if aNotFirst then Add('');
-        end
-      else
-        begin
-        If not CheckQuoted then
-          begin
-          // next string is not quoted; read until delimiter
-          j:=i;
-          while (j<=len) and
-                (AValue[j]<>aDelimiter) do inc(j);
-          Add( Copy(AValue,i,j-i));
-          i:=j;
-          end;
-        end;
-      aNotFirst:=true;
-      end;
-    end
-  else 
-    begin
+  end;
+
+begin
+  BeginUpdate;
+  i:=1;
+  j:=1;
+  aNotFirst:=false;
+  try
+    if DoClear then
+      Clear;
+    len:=length(AValue);
     while i<=len do
     while i<=len do
       begin
       begin
       // skip delimiter
       // skip delimiter
       if aNotFirst and (i<=len) and (AValue[i]=aDelimiter) then
       if aNotFirst and (i<=len) and (AValue[i]=aDelimiter) then
         inc(i);
         inc(i);
-
-      // skip spaces
-      while (i<=len) and (Ord(AValue[i])<=Ord(' ')) do inc(i);
-    
+      MaybeSkipSpaces;
       // read next string
       // read next string
       if i>len then
       if i>len then
         begin
         begin
@@ -634,19 +608,16 @@ begin
           // next string is not quoted; read until control character/space/delimiter
           // next string is not quoted; read until control character/space/delimiter
           j:=i;
           j:=i;
           while (j<=len) and
           while (j<=len) and
-                (Ord(AValue[j])>Ord(' ')) and
+                (aStrictDelimiter or (Ord(AValue[j])>Ord(' '))) and
                 (AValue[j]<>aDelimiter) do
                 (AValue[j]<>aDelimiter) do
             inc(j);
             inc(j);
           Add( Copy(AValue,i,j-i));
           Add( Copy(AValue,i,j-i));
           i:=j;
           i:=j;
           end;
           end;
         end;
         end;
-      // skip spaces
-      while (i<=len) and (Ord(AValue[i])<=Ord(' ')) do
-        inc(i);
+      MaybeSkipSpaces;
       aNotFirst:=true;
       aNotFirst:=true;
       end; // While I<=Len
       end; // While I<=Len
-    end; // If StrictDelimiter
  finally
  finally
    EndUpdate;
    EndUpdate;
  end;
  end;

+ 2 - 1
rtl/objpas/sysconst.pp

@@ -68,7 +68,8 @@ const
   SInvalidBoolean        = '"%s" is not a valid boolean.';
   SInvalidBoolean        = '"%s" is not a valid boolean.';
   SInvalidCast           = 'Invalid type cast';
   SInvalidCast           = 'Invalid type cast';
   SinvalidCurrency       = 'Invalid currency: "%s"';
   SinvalidCurrency       = 'Invalid currency: "%s"';
-  SInvalidDateTime       = '%f is not a valid date/time value.';
+  SInvalidDateTime       = '"%s" is not a valid date/time value.';
+  SInvalidDateTimeFloat  = '%f is not a valid date/time value.';
   SInvalidDrive          = 'Invalid drive specified';
   SInvalidDrive          = 'Invalid drive specified';
   SInvalidFileHandle     = 'Invalid file handle';
   SInvalidFileHandle     = 'Invalid file handle';
   SInvalidFloat          = '"%s" is an invalid float';
   SInvalidFloat          = '"%s" is an invalid float';

+ 2 - 1
rtl/objpas/sysutils/stre.inc

@@ -48,7 +48,8 @@ Const
    SInvalidArgIndex = 'Invalid argument index in format "%s"';
    SInvalidArgIndex = 'Invalid argument index in format "%s"';
    SInvalidBoolean = '"%s" is not a valid boolean.';
    SInvalidBoolean = '"%s" is not a valid boolean.';
    SInvalidCast = 'Invalid type cast';
    SInvalidCast = 'Invalid type cast';
-   SInvalidDateTime = '%f is not a valid date/time value.';
+   SInvalidDateTime = '"%s" is not a valid date/time value.';
+   SInvalidDateTimeFloat = '%f is not a valid date/time value.';
    SInvalidDrive = 'Invalid drive specified';
    SInvalidDrive = 'Invalid drive specified';
    SInvalidFileHandle = 'Invalid file handle';
    SInvalidFileHandle = 'Invalid file handle';
    SInvalidFloat = '"%s" is an invalid float';
    SInvalidFloat = '"%s" is an invalid float';

+ 1 - 1
rtl/objpas/sysutils/syssb.inc

@@ -532,7 +532,7 @@ begin
   CheckNegative(RemLength,'RemLength');
   CheckNegative(RemLength,'RemLength');
   CheckRange(StartIndex,0,Length);
   CheckRange(StartIndex,0,Length);
   MoveIndex:=StartIndex+RemLength;
   MoveIndex:=StartIndex+RemLength;
-  CheckRange(MoveIndex,0,Length-1);
+  CheckRange(MoveIndex,0,Length);
   if (Length-Moveindex)>0 then
   if (Length-Moveindex)>0 then
     Move(FData[MoveIndex],FData[StartIndex],(Length-MoveIndex)*SizeOf(SBChar));
     Move(FData[MoveIndex],FData[StartIndex],(Length-MoveIndex)*SizeOf(SBChar));
   Length:=Length-RemLength;
   Length:=Length-RemLength;

+ 1 - 1
rtl/objpas/sysutils/sysstr.inc

@@ -1913,7 +1913,7 @@ end;
 Function FloatToDateTime (Const Value : Extended) : TDateTime;
 Function FloatToDateTime (Const Value : Extended) : TDateTime;
 begin
 begin
   If (Value<MinDateTime) or (Value>MaxDateTime) then
   If (Value<MinDateTime) or (Value>MaxDateTime) then
-    Raise EConvertError.CreateFmt (SInvalidDateTime,[Value]);
+    Raise EConvertError.CreateFmt (SInvalidDateTimeFloat,[Value]);
   Result:=Value;
   Result:=Value;
 end;
 end;
 
 

+ 8 - 8
rtl/objpas/sysutils/sysutils.inc

@@ -39,7 +39,7 @@
 
 
   { variant error codes }
   { variant error codes }
   {$i varerror.inc}
   {$i varerror.inc}
-  
+
   { Type helpers}
   { Type helpers}
   {$i syshelp.inc}
   {$i syshelp.inc}
 
 
@@ -144,7 +144,7 @@ end;
   {$i sysuni.inc}
   {$i sysuni.inc}
   {$i sysencoding.inc}
   {$i sysencoding.inc}
 {$endif FPC_HAS_UNICODESTRING}
 {$endif FPC_HAS_UNICODESTRING}
-  
+
   { threading stuff }
   { threading stuff }
   {$i sysuthrd.inc}
   {$i sysuthrd.inc}
 
 
@@ -161,7 +161,7 @@ end;
       end;
       end;
 
 
     procedure FreeMemAndNil(var p);
     procedure FreeMemAndNil(var p);
-    
+
     var
     var
       temp:Pointer;
       temp:Pointer;
     begin
     begin
@@ -169,7 +169,7 @@ end;
       Pointer(P):=nil;
       Pointer(P):=nil;
       FreeMem(temp);
       FreeMem(temp);
     end;
     end;
-    
+
   { Interfaces support }
   { Interfaces support }
   {$i sysuintf.inc}
   {$i sysuintf.inc}
 
 
@@ -300,7 +300,7 @@ Procedure CatchUnhandledException (Obj : TObject; Addr: CodePointer; FrameCount:
 Var
 Var
   i : longint;
   i : longint;
   hstdout : ^text;
   hstdout : ^text;
-  
+
 begin
 begin
   if WriteErrorsToStdErr then
   if WriteErrorsToStdErr then
     hstdout:=@stderr
     hstdout:=@stderr
@@ -802,7 +802,7 @@ begin
 end;
 end;
 
 
 function ExecuteProcess(Const Path: UnicodeString; Const ComLine: Array of UnicodeString;Flags:TExecuteFlags=[]):integer;
 function ExecuteProcess(Const Path: UnicodeString; Const ComLine: Array of UnicodeString;Flags:TExecuteFlags=[]):integer;
-var 
+var
   ComLineA : array of RawByteString;
   ComLineA : array of RawByteString;
   I        : Integer;
   I        : Integer;
 begin
 begin
@@ -818,9 +818,9 @@ end;
 {$IFNDEF VER3_0}
 {$IFNDEF VER3_0}
 generic function IfThen<T>(val:boolean;const iftrue:T; const iffalse:T) :T; inline; overload;
 generic function IfThen<T>(val:boolean;const iftrue:T; const iffalse:T) :T; inline; overload;
 begin
 begin
-  if val then 
+  if val then
     Result := ifTrue
     Result := ifTrue
   else
   else
-    Result:=ifFalse;  
+    Result:=ifFalse;
 end;
 end;
 {$ENDIF}
 {$ENDIF}

+ 1 - 0
utils/fpcres/fpcres.pas

@@ -271,6 +271,7 @@ begin
     mti386 : Result.MachineType:=cmti386;
     mti386 : Result.MachineType:=cmti386;
     mtarm : Result.MachineType:=cmtarm;
     mtarm : Result.MachineType:=cmtarm;
     mtx86_64 : Result.MachineType:=cmtx8664;
     mtx86_64 : Result.MachineType:=cmtx8664;
+    mtaarch64 : Result.MachineType:=cmtaarch64;
   end;
   end;
 end;
 end;
 
 

+ 2 - 2
utils/fpcres/target.pas

@@ -83,7 +83,7 @@ var
     (name : 'ia64';         formats : [ofElf]),                   //mtia64
     (name : 'ia64';         formats : [ofElf]),                   //mtia64
     (name : 'mips';         formats : [ofElf]; alias : 'mipseb'), //mtmips
     (name : 'mips';         formats : [ofElf]; alias : 'mipseb'), //mtmips
     (name : 'mipsel';       formats : [ofElf]),                   //mtmipsel
     (name : 'mipsel';       formats : [ofElf]),                   //mtmipsel
-    (name : 'aarch64';      formats : [ofElf, ofMachO]),          //mtaarch64
+    (name : 'aarch64';      formats : [ofElf, ofCoff, ofMachO]),  //mtaarch64
     (name : 'powerpc64le';  formats : [ofElf]),                   //mtppc64le
     (name : 'powerpc64le';  formats : [ofElf]),                   //mtppc64le
     (name : 'bigendian';    formats : [ofExt]),                   //mtBigEndian
     (name : 'bigendian';    formats : [ofExt]),                   //mtBigEndian
     (name : 'littleendian'; formats : [ofExt])                    //mtLittleEndian
     (name : 'littleendian'; formats : [ofExt])                    //mtLittleEndian
@@ -104,7 +104,7 @@ var
                                                      mtia64,mtmips,mtmipsel,
                                                      mtia64,mtmips,mtmipsel,
                                                      mtppc64le,mtaarch64]),
                                                      mtppc64le,mtaarch64]),
     (name : 'coff';     ext : '.o';      machines : [mti386,mtx86_64,mtarm,
     (name : 'coff';     ext : '.o';      machines : [mti386,mtx86_64,mtarm,
-                                                     mtppc,mtppc64]),
+                                                     mtaarch64,mtppc,mtppc64]),
     (name : 'xcoff';    ext : '.o';      machines : [mtppc{,mtppc64}]),
     (name : 'xcoff';    ext : '.o';      machines : [mtppc{,mtppc64}]),
     (name : 'mach-o';   ext : '.or';     machines : [mti386,mtx86_64,mtppc,
     (name : 'mach-o';   ext : '.or';     machines : [mti386,mtx86_64,mtppc,
                                                      mtppc64,mtarm,mtaarch64]),
                                                      mtppc64,mtarm,mtaarch64]),