Skip to content

Commit 0034011

Browse files
authored
Merge branch 'doublecmd:master' into master
2 parents 60256ef + c32db48 commit 0034011

100 files changed

Lines changed: 5056 additions & 2219 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/scripts/create_release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ build_doublecmd
106106
export CPU_TARGET=x86_64
107107
export TARGET=x86_64-apple-darwin
108108
# Set minimal Mac OS X target version
109-
export MACOSX_DEPLOYMENT_TARGET=10.11
109+
export MACOSX_DEPLOYMENT_TARGET=11.0
110110

111111
build_unrar
112112
build_doublecmd

.github/scripts/create_snapshot.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,6 @@ build_doublecmd
107107
# Set processor architecture
108108
export CPU_TARGET=x86_64
109109
# Set minimal Mac OS X target version
110-
export MACOSX_DEPLOYMENT_TARGET=10.11
110+
export MACOSX_DEPLOYMENT_TARGET=11.0
111111

112112
build_doublecmd

.github/workflows/release.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,23 @@ concurrency:
1111

1212
jobs:
1313
build-mac:
14-
runs-on: macos-13
14+
runs-on: macos-14
1515
steps:
1616
- name: Install Free Pascal
1717
uses: doublecmd/lazarus-install@mac
1818
with:
1919
lazarus-version: "stable"
2020

2121
- name: Get Lazarus source
22-
uses: actions/checkout@v5
22+
uses: actions/checkout@v6
2323
with:
2424
repository: 'fpc/Lazarus'
2525
ref: 'fixes_4'
2626

2727
- name: Build and install Lazarus
28-
run: make all install
28+
run: |
29+
make all
30+
sudo make install
2931
3032
- name: Create Lazarus config
3133
run: |
@@ -34,12 +36,12 @@ jobs:
3436
sudo sed -i -e "s|_PPCARCH_|fpc|g; s|/Developer/lazarus|/usr/local/share/lazarus|g" /etc/lazarus/environmentoptions.xml
3537
3638
- name: Checkout source
37-
uses: actions/checkout@v5
39+
uses: actions/checkout@v6
3840
with:
3941
fetch-depth: 0
4042

4143
- name: Download unrar source code
42-
run: wget https://www.rarlab.com/rar/unrarsrc-7.0.9.tar.gz -O /tmp/unrarsrc.tar.gz
44+
run: wget https://www.rarlab.com/rar/unrarsrc-7.2.3.tar.gz -O /tmp/unrarsrc.tar.gz
4345

4446
- name: Extract unrar source code
4547
run: cd /tmp && tar xzf unrarsrc.tar.gz

.github/workflows/snapshots.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
lazarus-version: "stable"
2626

2727
- name: Get Lazarus source
28-
uses: actions/checkout@v5
28+
uses: actions/checkout@v6
2929
with:
3030
repository: 'fpc/Lazarus'
3131

@@ -41,7 +41,7 @@ jobs:
4141
sudo sed -i -e "s|_PPCARCH_|fpc|g; s|/Developer/lazarus|/usr/local/share/lazarus|g" /etc/lazarus/environmentoptions.xml
4242
4343
- name: Checkout source
44-
uses: actions/checkout@v5
44+
uses: actions/checkout@v6
4545
with:
4646
fetch-depth: 0
4747

@@ -69,7 +69,7 @@ jobs:
6969
lazarus-version: "stable"
7070

7171
- name: Checkout source
72-
uses: actions/checkout@v5
72+
uses: actions/checkout@v6
7373
with:
7474
fetch-depth: 0
7575

components/doublecmd/dcdatetimeutils.pas

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222

2323
unit DCDateTimeUtils;
2424

25-
{$mode objfpc}{$H+}
25+
{$mode objfpc}
26+
{$H+}{$R-}{$Q-}
2627

2728
interface
2829

@@ -327,8 +328,20 @@ function WinFileTimeToFileTimeEx(FileTime: TWinFileTime): DCBasicTypes.TFileTime
327328
end;
328329
{$ELSEIF DEFINED(UNIX)}
329330
begin
330-
Result.Sec:= Int64((FileTime - UnixWinEpoch) div 10000000);
331-
Result.NanoSec:= Int64((FileTime - UnixWinEpoch) mod 10000000) * 100;
331+
if (FileTime >= UnixWinEpoch) then
332+
begin
333+
Result.Sec:= Int64((FileTime - UnixWinEpoch) div 10000000);
334+
Result.NanoSec:= Int64((FileTime - UnixWinEpoch) mod 10000000) * 100;
335+
end
336+
else begin
337+
Result.Sec:= (Int64(FileTime) - Int64(UnixWinEpoch)) div 10000000;
338+
if (Result.Sec = 0) then
339+
Result.NanoSec:= 0
340+
else begin
341+
Result.NanoSec:= (Int64(UnixWinEpoch - FileTime) mod 10000000) * 100;
342+
if (Result.NanoSec > 0) then Result.NanoSec:= 1000000000 - Result.NanoSec;
343+
end;
344+
end;
332345
end;
333346
{$ENDIF}
334347

@@ -583,31 +596,10 @@ function UnixFileTimeToDateTime(UnixTime: TUnixFileTime) : TDateTime;
583596
function DateTimeToUnixFileTime(DateTime : TDateTime): TUnixFileTime;
584597
{$IF DEFINED(UNIX)}
585598
var
586-
AUnixTime: TTime;
587-
ATime: TTimeStruct;
588-
Year, Month, Day: Word;
589-
Hour, Minute, Second, MilliSecond: Word;
599+
AUnixTime: TFileTimeEx;
590600
begin
591-
DecodeDate(DateTime, Year, Month, Day);
592-
DecodeTime(DateTime, Hour, Minute, Second, MilliSecond);
593-
594-
ATime.tm_isdst:= -1;
595-
596-
ATime.tm_year:= Year - 1900;
597-
ATime.tm_mon:= Month - 1;
598-
ATime.tm_mday:= Day;
599-
600-
ATime.tm_hour:= Hour;
601-
ATime.tm_min:= Minute;
602-
ATime.tm_sec:= Second;
603-
604-
AUnixTime:= fpMkTime(@ATime);
605-
606-
if (AUnixTime = -1) then
607-
Result:= 0
608-
else begin
609-
Result:= TUnixFileTime(AUnixTime);
610-
end;
601+
AUnixTime:= DateTimeToUnixFileTimeEx(DateTime);
602+
Result:= TUnixFileTime(AUnixTime.Sec);
611603
end;
612604
{$ELSE}
613605
var
@@ -626,9 +618,6 @@ function DateTimeToUnixFileTimeEx(DateTime : TDateTime): DCBasicTypes.TFileTimeE
626618
Year, Month, Day: Word;
627619
Hour, Minute, Second, MilliSecond: Word;
628620
begin
629-
if DateTime < UnixEpoch then
630-
raise EDateOutOfRange.Create(DateTime);
631-
632621
DecodeDate(DateTime, Year, Month, Day);
633622
DecodeTime(DateTime, Hour, Minute, Second, MilliSecond);
634623

@@ -647,6 +636,7 @@ function DateTimeToUnixFileTimeEx(DateTime : TDateTime): DCBasicTypes.TFileTimeE
647636
if (AUnixTime = -1) then
648637
Result:= TFileTimeExNull
649638
else begin
639+
if (AUnixTime < 0) then MilliSecond:= 0;
650640
Result:= TFileTimeEx.Create(AUnixTime, MilliSecond * 1000 * 1000);
651641
end;
652642
end;

components/doublecmd/dcosutils.pas

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ interface
4949
fmOpenSync = $10000;
5050
fmOpenDirect = $20000;
5151
fmOpenNoATime = $40000;
52+
fmOpenSpecial = $80000;
5253

5354
{$IF DEFINED(UNIX)}
5455
ERROR_NOT_SAME_DEVICE = ESysEXDEV;
@@ -182,6 +183,8 @@ function MapFile(const sFileName : String; out FileMapRec : TFileMapRec) : Boole
182183
}
183184
procedure UnMapFile(var FileMapRec : TFileMapRec);
184185

186+
function NormalizeFileName(const Source: String): String;
187+
185188
{en
186189
Convert from console to UTF8 encoding.
187190
}
@@ -335,6 +338,9 @@ implementation
335338
{$ENDIF}
336339
{$IF DEFINED(UNIX)}
337340
Unix, dl,
341+
{$ENDIF}
342+
{$IF DEFINED(DARWIN)}
343+
LazFileUtils,
338344
{$ENDIF}
339345
DCStrUtils, LazUTF8;
340346

@@ -845,6 +851,17 @@ procedure UnMapFile(var FileMapRec : TFileMapRec);
845851
end;
846852
{$ENDIF}
847853

854+
function NormalizeFileName(const Source: String): String; inline;
855+
{$IF DEFINED(DARWIN)}
856+
begin
857+
Result:= GetDarwinNormalizedFileName(Source);
858+
end;
859+
{$ELSE}
860+
begin
861+
Result:= Source;
862+
end;
863+
{$ENDIF}
864+
848865
function ConsoleToUTF8(const Source: String): RawByteString;
849866
{$IFDEF MSWINDOWS}
850867
begin
@@ -874,6 +891,8 @@ function mbFileOpen(const FileName: String; Mode: LongWord): System.THandle;
874891
end;
875892
end;
876893
{$ELSE}
894+
var
895+
Info: BaseUnix.Stat;
877896
begin
878897
repeat
879898
Result:= fpOpen(UTF8ToSys(FileName), AccessModes[Mode and 3] or
@@ -882,6 +901,18 @@ function mbFileOpen(const FileName: String; Mode: LongWord): System.THandle;
882901
if Result <> feInvalidHandle then
883902
begin
884903
FileCloseOnExec(Result);
904+
if (Mode and fmOpenSpecial = 0) then
905+
begin
906+
if fpFStat(Result, Info) = 0 then
907+
begin
908+
if FPS_ISFIFO(Info.st_mode) then
909+
begin
910+
FileClose(Result);
911+
errno:= ESysEINVAL;
912+
Exit(feInvalidHandle);
913+
end;
914+
end;
915+
end;
885916
{$IF DEFINED(DARWIN)}
886917
if (Mode and (fmOpenSync or fmOpenDirect) <> 0) then
887918
begin
@@ -1605,8 +1636,16 @@ function mbFileSystemEntryExists(const Path: String): Boolean;
16051636
Result := mbFileGetAttr(Path) <> faInvalidAttributes;
16061637
end;
16071638

1608-
function mbCompareFileNames(const FileName1, FileName2: String): Boolean; inline;
1609-
{$IF DEFINED(WINDOWS) OR DEFINED(DARWIN)}
1639+
function mbCompareFileNames(const FileName1, FileName2: String): Boolean;
1640+
{$IF DEFINED(DARWIN)}
1641+
begin
1642+
if (Length(FileName1) = 0) or (Length(FileName2) = 0) then
1643+
Result:= (FileName1 = FileName2)
1644+
else begin
1645+
Result:= CompareFilenamesIgnoreCase(FileName1, FileName2) = 0;
1646+
end;
1647+
end;
1648+
{$ELSEIF DEFINED(MSWINDOWS)}
16101649
begin
16111650
Result:= (UnicodeCompareText(CeUtf8ToUtf16(FileName1), CeUtf8ToUtf16(FileName2)) = 0);
16121651
end;

components/doublecmd/dcstringhashlistutf8.pas

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@ TStringHashListUtf8 = class(TObject)
4242
private
4343
FList: PStringHashItemList;
4444
FCount: Integer;
45+
fNormalize: Boolean;
4546
fCaseSensitive: Boolean;
4647
function BinarySearch(HashValue: Cardinal): Integer;
4748
function CompareString(const Low, Key: String): Boolean;
4849
function CompareValue(const Value1, Value2: Cardinal): Integer;
4950
procedure FindHashBoundaries(HashValue: Cardinal; StartFrom: Integer; out First, Last: Integer);
5051
function GetData(const S: String): Pointer;
52+
procedure SetNormalize(AValue: Boolean);
5153
procedure SetCaseSensitive(const Value: Boolean);
5254
procedure Delete(Index: Integer);
5355
procedure SetData(const S: String; const AValue: Pointer);
@@ -66,6 +68,7 @@ TStringHashListUtf8 = class(TObject)
6668
function Remove(const S: String): Integer;
6769
function Remove(const S: String; Data: Pointer): Integer;
6870
procedure FindBoundaries(StartFrom: Integer; out First, Last: Integer);
71+
property Normalize: Boolean read fNormalize write SetNormalize;
6972
property CaseSensitive: Boolean read fCaseSensitive write SetCaseSensitive;
7073
property Count: Integer read FCount;
7174
property Data[const S: String]: Pointer read GetData write SetData; default;
@@ -75,7 +78,7 @@ TStringHashListUtf8 = class(TObject)
7578
implementation
7679

7780
uses
78-
LazUTF8;
81+
LazUTF8, DCOSUtils;
7982

8083
{ TStringHashListUtf8 }
8184

@@ -97,6 +100,10 @@ function TStringHashListUtf8.Add(const S: String; ItemData: Pointer): Integer;
97100
else begin
98101
Text:= UTF8LowerCase(S);
99102
end;
103+
if fNormalize then
104+
begin
105+
Text:= NormalizeFileName(Text);
106+
end;
100107
New(Item);
101108
Val:= HashOf(Text);
102109
Item^.HashValue := Val;
@@ -180,13 +187,20 @@ function TStringHashListUtf8.CompareString(const Low, Key: String): Boolean;
180187
begin
181188
P:= Pointer(Low);
182189
Len:= Length(Low);
190+
if not fNormalize then
191+
begin
192+
LKey:= Key;
193+
end
194+
else begin
195+
LKey:= NormalizeFileName(Key);
196+
end;
183197
if fCaseSensitive then
184198
begin
185-
Result:= (Len = Length(Key));
186-
if Result then Result:= (CompareByte(P^, Pointer(Key)^, Len) = 0);
199+
Result:= (Len = Length(LKey));
200+
if Result then Result:= (CompareByte(P^, Pointer(LKey)^, Len) = 0);
187201
end
188202
else begin
189-
LKey:= UTF8LowerCase(Key);
203+
LKey:= UTF8LowerCase(LKey);
190204
Result:= (Len = Length(LKey));
191205
if Result then Result:= (CompareByte(P^, Pointer(LKey)^, Len) = 0);
192206
end;
@@ -232,6 +246,18 @@ procedure TStringHashListUtf8.SetData(const S: String; const AValue: Pointer);
232246
Add(S,AValue);
233247
end;
234248

249+
procedure TStringHashListUtf8.SetNormalize(AValue: Boolean);
250+
begin
251+
if fNormalize <> AValue then
252+
begin
253+
if Count > 0 then
254+
begin
255+
raise EListError.Create(lrsListMustBeEmpty);
256+
end;
257+
fNormalize := AValue;
258+
end;
259+
end;
260+
235261
destructor TStringHashListUtf8.Destroy;
236262
begin
237263
Clear;
@@ -249,6 +275,10 @@ function TStringHashListUtf8.Find(const S: String): Integer;
249275
else begin
250276
Text:= UTF8LowerCase(S);
251277
end;
278+
if fNormalize then
279+
begin
280+
Text:= NormalizeFileName(Text);
281+
end;
252282
Value:= HashOf(Text);
253283
Result:= BinarySearch(Value);
254284
if (Result <> -1) and not CompareString(Text, FList[Result]^.Key) then
@@ -275,6 +305,10 @@ function TStringHashListUtf8.Find(const S: String; Data: Pointer): Integer;
275305
else begin
276306
Text:= UTF8LowerCase(S);
277307
end;
308+
if fNormalize then
309+
begin
310+
Text:= NormalizeFileName(Text);
311+
end;
278312
Value:= HashOf(Text);
279313
Result:= BinarySearch(Value);
280314
if (Result <> -1) and
@@ -335,7 +369,8 @@ procedure TStringHashListUtf8.Insert(Index: Integer; Item: PStringHashItem);
335369

336370
constructor TStringHashListUtf8.Create(CaseSensitivity: boolean);
337371
begin
338-
fCaseSensitive:=CaseSensitivity;
372+
fNormalize:= True;
373+
fCaseSensitive:= CaseSensitivity;
339374
inherited Create;
340375
end;
341376

0 commit comments

Comments
 (0)