mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
FIX: Use normalized strings when compare file names under macOS (fixes #1981)
This commit is contained in:
parent
aa4b99f3a1
commit
f27b7f8526
2 changed files with 61 additions and 6 deletions
|
|
@ -182,6 +182,8 @@ function MapFile(const sFileName : String; out FileMapRec : TFileMapRec) : Boole
|
|||
}
|
||||
procedure UnMapFile(var FileMapRec : TFileMapRec);
|
||||
|
||||
function NormalizeFileName(const Source: String): String;
|
||||
|
||||
{en
|
||||
Convert from console to UTF8 encoding.
|
||||
}
|
||||
|
|
@ -335,6 +337,9 @@ uses
|
|||
{$ENDIF}
|
||||
{$IF DEFINED(UNIX)}
|
||||
Unix, dl,
|
||||
{$ENDIF}
|
||||
{$IF DEFINED(DARWIN)}
|
||||
LazFileUtils,
|
||||
{$ENDIF}
|
||||
DCStrUtils, LazUTF8;
|
||||
|
||||
|
|
@ -845,6 +850,17 @@ begin
|
|||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function NormalizeFileName(const Source: String): String; inline;
|
||||
{$IF DEFINED(DARWIN)}
|
||||
begin
|
||||
Result:= GetDarwinNormalizedFileName(Source);
|
||||
end;
|
||||
{$ELSE}
|
||||
begin
|
||||
Result:= Source;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function ConsoleToUTF8(const Source: String): RawByteString;
|
||||
{$IFDEF MSWINDOWS}
|
||||
begin
|
||||
|
|
@ -1606,7 +1622,11 @@ begin
|
|||
end;
|
||||
|
||||
function mbCompareFileNames(const FileName1, FileName2: String): Boolean; inline;
|
||||
{$IF DEFINED(WINDOWS) OR DEFINED(DARWIN)}
|
||||
{$IF DEFINED(DARWIN)}
|
||||
begin
|
||||
Result:= CompareFilenamesIgnoreCase(FileName1, FileName2) = 0;
|
||||
end;
|
||||
{$ELSEIF DEFINED(MSWINDOWS)}
|
||||
begin
|
||||
Result:= (UnicodeCompareText(CeUtf8ToUtf16(FileName1), CeUtf8ToUtf16(FileName2)) = 0);
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -42,12 +42,14 @@ type
|
|||
private
|
||||
FList: PStringHashItemList;
|
||||
FCount: Integer;
|
||||
fNormalize: Boolean;
|
||||
fCaseSensitive: Boolean;
|
||||
function BinarySearch(HashValue: Cardinal): Integer;
|
||||
function CompareString(const Low, Key: String): Boolean;
|
||||
function CompareValue(const Value1, Value2: Cardinal): Integer;
|
||||
procedure FindHashBoundaries(HashValue: Cardinal; StartFrom: Integer; out First, Last: Integer);
|
||||
function GetData(const S: String): Pointer;
|
||||
procedure SetNormalize(AValue: Boolean);
|
||||
procedure SetCaseSensitive(const Value: Boolean);
|
||||
procedure Delete(Index: Integer);
|
||||
procedure SetData(const S: String; const AValue: Pointer);
|
||||
|
|
@ -66,6 +68,7 @@ type
|
|||
function Remove(const S: String): Integer;
|
||||
function Remove(const S: String; Data: Pointer): Integer;
|
||||
procedure FindBoundaries(StartFrom: Integer; out First, Last: Integer);
|
||||
property Normalize: Boolean read fNormalize write SetNormalize;
|
||||
property CaseSensitive: Boolean read fCaseSensitive write SetCaseSensitive;
|
||||
property Count: Integer read FCount;
|
||||
property Data[const S: String]: Pointer read GetData write SetData; default;
|
||||
|
|
@ -75,7 +78,7 @@ type
|
|||
implementation
|
||||
|
||||
uses
|
||||
LazUTF8;
|
||||
LazUTF8, DCOSUtils;
|
||||
|
||||
{ TStringHashListUtf8 }
|
||||
|
||||
|
|
@ -97,6 +100,10 @@ begin
|
|||
else begin
|
||||
Text:= UTF8LowerCase(S);
|
||||
end;
|
||||
if fNormalize then
|
||||
begin
|
||||
Text:= NormalizeFileName(Text);
|
||||
end;
|
||||
New(Item);
|
||||
Val:= HashOf(Text);
|
||||
Item^.HashValue := Val;
|
||||
|
|
@ -180,13 +187,20 @@ var
|
|||
begin
|
||||
P:= Pointer(Low);
|
||||
Len:= Length(Low);
|
||||
if fCaseSensitive then
|
||||
if not fNormalize then
|
||||
begin
|
||||
Result:= (Len = Length(Key));
|
||||
if Result then Result:= (CompareByte(P^, Pointer(Key)^, Len) = 0);
|
||||
LKey:= Key;
|
||||
end
|
||||
else begin
|
||||
LKey:= UTF8LowerCase(Key);
|
||||
LKey:= NormalizeFileName(Key);
|
||||
end;
|
||||
if fCaseSensitive then
|
||||
begin
|
||||
Result:= (Len = Length(LKey));
|
||||
if Result then Result:= (CompareByte(P^, Pointer(LKey)^, Len) = 0);
|
||||
end
|
||||
else begin
|
||||
LKey:= UTF8LowerCase(LKey);
|
||||
Result:= (Len = Length(LKey));
|
||||
if Result then Result:= (CompareByte(P^, Pointer(LKey)^, Len) = 0);
|
||||
end;
|
||||
|
|
@ -232,6 +246,18 @@ begin
|
|||
Add(S,AValue);
|
||||
end;
|
||||
|
||||
procedure TStringHashListUtf8.SetNormalize(AValue: Boolean);
|
||||
begin
|
||||
if fNormalize <> AValue then
|
||||
begin
|
||||
if Count > 0 then
|
||||
begin
|
||||
raise EListError.Create(lrsListMustBeEmpty);
|
||||
end;
|
||||
fNormalize := AValue;
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TStringHashListUtf8.Destroy;
|
||||
begin
|
||||
Clear;
|
||||
|
|
@ -249,6 +275,10 @@ begin
|
|||
else begin
|
||||
Text:= UTF8LowerCase(S);
|
||||
end;
|
||||
if fNormalize then
|
||||
begin
|
||||
Text:= NormalizeFileName(Text);
|
||||
end;
|
||||
Value:= HashOf(Text);
|
||||
Result:= BinarySearch(Value);
|
||||
if (Result <> -1) and not CompareString(Text, FList[Result]^.Key) then
|
||||
|
|
@ -275,6 +305,10 @@ begin
|
|||
else begin
|
||||
Text:= UTF8LowerCase(S);
|
||||
end;
|
||||
if fNormalize then
|
||||
begin
|
||||
Text:= NormalizeFileName(Text);
|
||||
end;
|
||||
Value:= HashOf(Text);
|
||||
Result:= BinarySearch(Value);
|
||||
if (Result <> -1) and
|
||||
|
|
@ -335,7 +369,8 @@ end;
|
|||
|
||||
constructor TStringHashListUtf8.Create(CaseSensitivity: boolean);
|
||||
begin
|
||||
fCaseSensitive:=CaseSensitivity;
|
||||
fNormalize:= True;
|
||||
fCaseSensitive:= CaseSensitivity;
|
||||
inherited Create;
|
||||
end;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue