diff --git a/components/fpdebug/fpdbgdwarfdataclasses.pas b/components/fpdebug/fpdbgdwarfdataclasses.pas index 84dcdbee40..80cb6a3af7 100644 --- a/components/fpdebug/fpdbgdwarfdataclasses.pas +++ b/components/fpdebug/fpdbgdwarfdataclasses.pas @@ -931,8 +931,8 @@ end; function NameInfoForSearch(const AName: String): TNameSearchInfo; begin - Result.NameLower := QuickUtf8LowerCase(AName); - Result.NameUpper := QuickUtf8UpperCase(AName); + Result.NameLower := UTF8LowerCaseFast(AName); + Result.NameUpper := UTF8UpperCaseFast(AName); Result.NameHash := objpas.Hash(Result.NameUpper) and $7fff or $8000; end; @@ -2866,7 +2866,7 @@ begin if not HasValidScope then exit; - h := objpas.Hash(QuickUtf8UpperCase(CompUnit.UnitName)) and $7fff or $8000; + h := objpas.Hash(UTF8UpperCaseFast(CompUnit.UnitName)) and $7fff or $8000; AKNownHashes^[h and KnownNameHashesBitMask] := True; NextTopLevel := 0; @@ -2889,7 +2889,7 @@ begin NextTopLevel := FScope.GetNextIndex; Continue; end; - h := objpas.Hash(QuickUtf8UpperCase(EntryName)) and $7fff or $8000; + h := objpas.Hash(UTF8UpperCaseFast(EntryName)) and $7fff or $8000; FScope.Current^.NameHash := h; if (FScope.Index >= NextTopLevel) or InEnum then AKNownHashes^[h and KnownNameHashesBitMask] := True; @@ -2932,8 +2932,8 @@ begin GoChild; if not HasValidScope then exit; - s1 := QuickUtf8UpperCase(AName); - s2 := UTF8LowerCase(AName); + s1 := UTF8UpperCaseFast(AName); + s2 := UTF8LowerCase(AName); // Should this be UTF8LowerCaseFast(AName) ? while HasValidScope do begin PrepareAbbrev; if (FAbbrev = nil) or not (dafHasName in FAbbrev^.flags) then begin @@ -2945,7 +2945,7 @@ begin Continue; end; - if CompareUtf8BothCase(@s1[1], @s2[1], EntryName) then begin + if CompareUtf8BothCase(@s1[1], @s2[1], EntryName) then begin // TODO: check DW_AT_start_scope; DebugLn(FPDBG_DWARF_SEARCH, ['GoNamedChild found ', dbgs(FScope, FCompUnit), ' Result=', DbgSName(Self), ' FOR ', AName]); Result := True; diff --git a/components/fpdebug/fpdbgutil.pp b/components/fpdebug/fpdbgutil.pp index 7ce1266f58..a190590f2b 100644 --- a/components/fpdebug/fpdbgutil.pp +++ b/components/fpdebug/fpdbgutil.pp @@ -201,10 +201,6 @@ var function CompareUtf8BothCase(AnUpper, AnLower, AnUnknown: PChar): Boolean; -// Optimistic upper/lower case. Attempt Ansi only, but if none ansi is found, do utf8 -function QuickUtf8UpperCase(const AText: String): String; -function QuickUtf8LowerCase(const AText: String): String; - function AlignPtr(Src: Pointer; Alignment: Byte): Pointer; function ValueFromMem(const AValue; ASize: Byte; AFlags: THexValueFormatFlags): Int64; function HexValue(const AValue; ASize: Byte; AFlags: THexValueFormatFlags): String; @@ -375,58 +371,6 @@ begin Result := AnUpper^ = AnUnknown^; // both #0 end; -function QuickUtf8UpperCase(const AText: String): String; -var - src, dst: PChar; - c: Integer; - t: Char; -begin - SetLength(Result, Length(AText)); - if Result = '' then - exit; - - src := @AText[1]; - dst := @Result[1]; - c := Length(Result); - while c > 0 do begin - t := src^; - if (ord(t) and 128) <> 0 then - exit(UTF8UpperCase(AText)); - if (t in ['a'..'z']) then - t := chr(ord(t) - 32); - dst^ := t; - dec(c); - inc(src); - inc(dst); - end; -end; - -function QuickUtf8LowerCase(const AText: String): String; -var - src, dst: PChar; - c: Integer; - t: Char; -begin - SetLength(Result, Length(AText)); - if Result = '' then - exit; - - src := @AText[1]; - dst := @Result[1]; - c := Length(Result); - while c > 0 do begin - t := src^; - if (ord(t) and 128) <> 0 then - exit(UTF8UpperCase(AText)); - if (t in ['A'..'Z']) then - t := chr(ord(t) + 32); - dst^ := t; - dec(c); - inc(src); - inc(dst); - end; -end; - function AlignPtr(Src: Pointer; Alignment: Byte): Pointer; begin Result := Pointer(((PtrUInt(Src) + Alignment - 1) and not PtrUInt(Alignment - 1))); diff --git a/components/lazutils/lazutf8.pas b/components/lazutils/lazutf8.pas index 4613af72ed..4c02913b3e 100644 --- a/components/lazutils/lazutf8.pas +++ b/components/lazutils/lazutf8.pas @@ -126,6 +126,10 @@ function UTF8LowerCase(const AInStr: string; const ALanguage: string=''): string function UTF8LowerString(const s: string): string; inline; function UTF8UpperCase(const AInStr: string; const ALanguage: string=''): string; function UTF8UpperString(const s: string): string; inline; +// Optimistic upper/lower case. Attempt ASCII only, but if non-ASCII is found, do UTF8 +function UTF8UpperCaseFast(const AText: String): String; +function UTF8LowerCaseFast(const AText: String): String; + function UTF8SwapCase(const AInStr: string; const ALanguage: string=''): string; // Capitalize the first letters of every word function UTF8ProperCase(const AInStr: string; const WordDelims: TSysCharSet): string; @@ -2872,6 +2876,55 @@ begin Result:=UTF8UpperCase(s); end; +function UTF8UpperCaseFast(const AText: String): String; +var + src, dst: PChar; + c: Integer; + t: Char; +begin + SetLength(Result, Length(AText)); + if Result = '' then + exit; + src := @AText[1]; + dst := @Result[1]; + c := Length(Result); + while c > 0 do begin + t := src^; + if (ord(t) and 128) <> 0 then + exit(UTF8UpperCase(AText)); + if (t in ['a'..'z']) then + t := chr(ord(t) - 32); + dst^ := t; + dec(c); + inc(src); + inc(dst); + end; +end; + +function UTF8LowerCaseFast(const AText: String): String; +var + src, dst: PChar; + c: Integer; + t: Char; +begin + SetLength(Result, Length(AText)); + if Result = '' then + exit; + src := @AText[1]; + dst := @Result[1]; + c := Length(Result); + while c > 0 do begin + t := src^; + if (ord(t) and 128) <> 0 then + exit(UTF8UpperCase(AText)); + if (t in ['A'..'Z']) then + t := chr(ord(t) + 32); + dst^ := t; + dec(c); + inc(src); + inc(dst); + end; +end; function FindInvalidUTF8Codepoint(p: PChar; Count: PtrInt; StopOnNonUTF8: Boolean): PtrInt; // return -1 if ok