mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-09 23:08:05 +02:00
fixed comparing filenames under darwin
git-svn-id: trunk@16373 -
This commit is contained in:
parent
301ebd9881
commit
60daf2ddd1
@ -40,6 +40,9 @@ uses
|
||||
{$ifdef MSWindows}
|
||||
{$define CaseInsensitiveFilenames}
|
||||
{$endif}
|
||||
{$IF defined(CaseInsensitiveFilenames) or defined(darwin)}
|
||||
{$DEFINE NotLiteralFilenames}
|
||||
{$ENDIF}
|
||||
|
||||
type
|
||||
TCTDirCacheString = (
|
||||
|
@ -42,7 +42,17 @@ type
|
||||
TFPCMemStreamSeekType = integer;
|
||||
PCharZ = Pointer;
|
||||
|
||||
{$ifdef Windows}
|
||||
{$define CaseInsensitiveFilenames}
|
||||
{$endif}
|
||||
{$IF defined(CaseInsensitiveFilenames) or defined(darwin)}
|
||||
{$DEFINE NotLiteralFilenames}
|
||||
{$ENDIF}
|
||||
|
||||
const
|
||||
FilenamesCaseSensitive = {$IFDEF CaseInsensitiveFilenames}false{$ELSE}true{$ENDIF};// lower and upper letters are treated the same
|
||||
FilenamesLiteral = {$IFDEF NotLiteralFilenames}false{$ELSE}true{$ENDIF};// file names can be compared using = string operator
|
||||
|
||||
SpecialChar = '#'; // used to use PathDelim, e.g. #\
|
||||
{$IFDEF MSWindows}
|
||||
FileMask = '*.*';
|
||||
@ -51,9 +61,6 @@ const
|
||||
FileMask = '*';
|
||||
ExeExt = '';
|
||||
{$ENDIF}
|
||||
{$ifdef MSWindows}
|
||||
{$define CaseInsensitiveFilenames}
|
||||
{$endif}
|
||||
|
||||
type
|
||||
TCTSearchFileCase = (
|
||||
@ -63,6 +70,7 @@ type
|
||||
);
|
||||
|
||||
function CompareFilenames(const Filename1, Filename2: string): integer;
|
||||
function CompareFilenamesIgnoreCase(const Filename1, Filename2: string): integer;
|
||||
function CompareFileExt(const Filename, Ext: string;
|
||||
CaseSensitive: boolean): integer;
|
||||
function DirPathExists(DirectoryName: string): boolean;
|
||||
@ -97,6 +105,9 @@ function FilenameIsMatching(const Mask, Filename: string;
|
||||
MatchExactly: boolean): boolean;
|
||||
function GetFilenameOnDisk(const AFilename: string): string;
|
||||
function FindDiskFilename(const Filename: string): string;
|
||||
{$IFDEF darwin}
|
||||
function GetDarwinSystemFilename(Filename: string): string;
|
||||
{$ENDIF}
|
||||
|
||||
function CompareAnsiStringFilenames(Data1, data2: Pointer): integer;
|
||||
function CompareFilenameOnly(Filename: PChar; FilenameLen: integer;
|
||||
@ -343,6 +354,9 @@ uses
|
||||
{$IFDEF MSWindows}
|
||||
Windows;
|
||||
{$ELSE}
|
||||
{$IFDEF darwin}
|
||||
MacOSAll,
|
||||
{$ENDIF}
|
||||
Unix, BaseUnix;
|
||||
{$ENDIF}
|
||||
|
||||
@ -647,7 +661,7 @@ begin
|
||||
if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='')
|
||||
then
|
||||
continue;
|
||||
if CompareText(FileInfo.Name,CurFile)=0 then begin
|
||||
if CompareFilenamesIgnoreCase(FileInfo.Name,CurFile)=0 then begin
|
||||
//writeln('FindDiskFilename ',FileInfo.Name,' ',CurFile);
|
||||
if FileInfo.Name=CurFile then begin
|
||||
// file found, has already the correct name
|
||||
@ -678,6 +692,24 @@ begin
|
||||
until StartPos>length(Result);
|
||||
end;
|
||||
|
||||
{$IFDEF darwin}
|
||||
function GetDarwinSystemFilename(Filename: string): string;
|
||||
var
|
||||
s: CFStringRef;
|
||||
l: CFIndex;
|
||||
begin
|
||||
if Filename='' then exit('');
|
||||
s:=CFStringCreateWithCString(nil,Pointer(Filename),kCFStringEncodingUTF8);
|
||||
l:=CFStringGetMaximumSizeOfFileSystemRepresentation(s);
|
||||
SetLength(Result,l);
|
||||
if Result<>'' then begin
|
||||
CFStringGetFileSystemRepresentation(s,@Result[1],length(Result));
|
||||
SetLength(Result,StrLen(PChar(Result)));
|
||||
end;
|
||||
CFRelease(s);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function CompareAnsiStringFilenames(Data1, data2: Pointer): integer;
|
||||
var
|
||||
s1: String;
|
||||
@ -731,12 +763,47 @@ begin
|
||||
end;
|
||||
|
||||
function CompareFilenames(const Filename1, Filename2: string): integer;
|
||||
{$IFDEF darwin}
|
||||
var
|
||||
F1: CFStringRef;
|
||||
F2: CFStringRef;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
Result:=CompareText(Filename1, Filename2);
|
||||
{$IFDEF darwin}
|
||||
if Filename1=Filename2 then exit(0);
|
||||
if (Filename1='') or (Filename2='') then
|
||||
exit(length(Filename2)-length(Filename1));
|
||||
F1:=CFStringCreateWithCString(nil,Pointer(Filename1),kCFStringEncodingUTF8);
|
||||
F2:=CFStringCreateWithCString(nil,Pointer(Filename2),kCFStringEncodingUTF8);
|
||||
Result:=CFStringCompare(F1,F2,kCFCompareNonliteral);
|
||||
CFRelease(F1);
|
||||
CFRelease(F2);
|
||||
{$ELSE}
|
||||
//debugln(['CompareFilenames F1="',length(Filename1),'" F2="',length(Filename2),'"']);
|
||||
Result:=CompareStr(Filename1, Filename2);
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
Result:=AnsiCompareText(Filename1, Filename2);
|
||||
{$ELSE}
|
||||
Result:=CompareStr(Filename1, Filename2);
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function CompareFilenamesIgnoreCase(const Filename1, Filename2: string
|
||||
): integer;
|
||||
{$IFDEF darwin}
|
||||
var
|
||||
F1: CFStringRef;
|
||||
F2: CFStringRef;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IFDEF darwin}
|
||||
if Filename1=Filename2 then exit(0);
|
||||
F1:=CFStringCreateWithCString(nil,Pointer(Filename1),kCFStringEncodingUTF8);
|
||||
F2:=CFStringCreateWithCString(nil,Pointer(Filename2),kCFStringEncodingUTF8);
|
||||
Result:=CFStringCompare(F1,F2,kCFCompareNonliteral+kCFCompareCaseInsensitive);
|
||||
CFRelease(F1);
|
||||
CFRelease(F2);
|
||||
{$ELSE}
|
||||
Result:=AnsiCompareText(Filename1, Filename2);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
@ -827,8 +894,12 @@ end;
|
||||
function GetFilenameOnDisk(const AFilename: string): string;
|
||||
begin
|
||||
Result:=AFilename;
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
Result:=FindDiskFilename(Result);
|
||||
{$IFDEF darwin}
|
||||
Result:=GetDarwinSystemFilename(Result);
|
||||
{$ELSE}
|
||||
{$IF defined(CaseInsensitiveFilenames) or (NotLiteralFilenames)}
|
||||
Result:=FindDiskFilename(Result);
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
@ -1123,6 +1194,10 @@ var
|
||||
ResultPos: Integer;
|
||||
i: Integer;
|
||||
FileNameRestLen: Integer;
|
||||
CmpBaseDirectory: String;
|
||||
CmpFilename: String;
|
||||
p: Integer;
|
||||
DirCount: Integer;
|
||||
begin
|
||||
Result:=Filename;
|
||||
if (BaseDirectory='') or (Filename='') then exit;
|
||||
@ -1134,55 +1209,69 @@ begin
|
||||
then
|
||||
exit;
|
||||
{$ENDIF}
|
||||
CmpBaseDirectory:=BaseDirectory;
|
||||
CmpFilename:=Filename;
|
||||
{$IFDEF darwin}
|
||||
CmpBaseDirectory:=GetDarwinSystemFilename(CmpBaseDirectory);
|
||||
CmpFilename:=GetDarwinSystemFilename(CmpFilename);
|
||||
{$ENDIF}
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
CmpBaseDirectory:=AnsiUpperCaseFileName(CmpBaseDirectory);
|
||||
CmpFilename:=AnsiUpperCaseFileName(CmpFilename);
|
||||
{$ENDIF}
|
||||
|
||||
FileNameLength:=length(Filename);
|
||||
BaseDirLen:=length(BaseDirectory);
|
||||
FileNameLength:=length(CmpFilename);
|
||||
if CmpFilename[FileNameLength]=PathDelim then
|
||||
dec(FileNameLength);
|
||||
BaseDirLen:=length(CmpBaseDirectory);
|
||||
if CmpBaseDirectory[BaseDirLen]=PathDelim then
|
||||
dec(BaseDirLen);
|
||||
if BaseDirLen=0 then exit;
|
||||
|
||||
// skip matching directories
|
||||
MinLen:=FileNameLength;
|
||||
if MinLen>BaseDirLen then MinLen:=BaseDirLen;
|
||||
SamePos:=1;
|
||||
while (SamePos<=MinLen) do begin
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
if AnsiStrLIComp(@FileName[SamePos],@BaseDirectory[SamePos],1)=0
|
||||
{$ELSE}
|
||||
if FileName[SamePos]=BaseDirectory[SamePos]
|
||||
{$ENDIF}
|
||||
then
|
||||
inc(SamePos)
|
||||
else
|
||||
break;
|
||||
p:=1;
|
||||
DirCount:=0;
|
||||
while (p<=MinLen) and (CmpFileName[p]=CmpBaseDirectory[p]) do
|
||||
begin
|
||||
if CmpFilename[p]=PathDelim then
|
||||
inc(DirCount);
|
||||
inc(p);
|
||||
end;
|
||||
if (SamePos>MinLen)
|
||||
and (((SamePos<=BaseDirLen) and (BaseDirectory[SamePos]=PathDelim))
|
||||
or ((SamePos<=FileNameLength) and (Filename[SamePos]=PathDelim))
|
||||
or (BaseDirLen=FileNameLength))
|
||||
then begin
|
||||
// Filename lies in BaseDirectory
|
||||
// or Filename is parent directory of BaseDirectory
|
||||
// or Filename is BaseDirectory
|
||||
end else begin
|
||||
// difference found -> step back to path delimiter
|
||||
repeat
|
||||
dec(SamePos);
|
||||
if (SamePos<1) then exit;
|
||||
until (FileName[SamePos]=PathDelim);
|
||||
end;
|
||||
if (SamePos=1) and (Filename[1]=PathDelim) then exit;
|
||||
if ((p>BaseDirLen) or (CmpBaseDirectory[p]=PathDelim))
|
||||
and ((p>FileNameLength) or (CmpFilename[p]=PathDelim)) then
|
||||
inc(DirCount);
|
||||
if DirCount=0 then exit;
|
||||
|
||||
// calculate needed up directories
|
||||
UpDirCount:=0;
|
||||
BaseDirPos:=SamePos+1;
|
||||
BaseDirLen:=length(BaseDirectory);
|
||||
UpDirCount:=-DirCount;
|
||||
BaseDirPos:=1;
|
||||
while (BaseDirPos<=BaseDirLen) do begin
|
||||
if (BaseDirectory[BaseDirPos]=PathDelim) then
|
||||
inc(UpDirCount);
|
||||
inc(BaseDirPos);
|
||||
end;
|
||||
if (SamePos<BaseDirLen) and (BaseDirectory[BaseDirLen]<>PathDelim) then
|
||||
if (BaseDirLen>0) and (BaseDirectory[BaseDirLen]<>PathDelim) then
|
||||
inc(UpDirCount);
|
||||
|
||||
// create relative filename
|
||||
FileNameRestLen:=FileNameLength-SamePos;
|
||||
SamePos:=1;
|
||||
p:=0;
|
||||
FileNameLength:=length(Filename);
|
||||
while (SamePos<=FileNameLength) do begin
|
||||
if (Filename[SamePos]=PathDelim) then begin
|
||||
inc(p);
|
||||
if p>=DirCount then begin
|
||||
inc(SamePos);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
inc(SamePos);
|
||||
end;
|
||||
FileNameRestLen:=FileNameLength-SamePos+1;
|
||||
//writeln('DirCount=',DirCount,' UpDirCount=',UpDirCount,' FileNameRestLen=',FileNameRestLen,' SamePos=',SamePos);
|
||||
SetLength(Result,3*UpDirCount+FileNameRestLen);
|
||||
ResultPos:=1;
|
||||
for i:=1 to UpDirCount do begin
|
||||
@ -1192,11 +1281,7 @@ begin
|
||||
inc(ResultPos,3);
|
||||
end;
|
||||
if FileNameRestLen>0 then
|
||||
Move(Filename[SamePos+1],Result[ResultPos],FileNameRestLen);
|
||||
|
||||
// use '.' for an Filename=BaseDirectory
|
||||
if UsePointDirectory and (Result='') and (Filename<>'') then
|
||||
Result:='.';
|
||||
System.Move(Filename[SamePos],Result[ResultPos],FileNameRestLen);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -1449,7 +1534,7 @@ begin
|
||||
Result:=FileInfo.Name;
|
||||
|
||||
ctsfcAllCase:
|
||||
if CompareText(ShortFilename,FileInfo.Name)=0 then begin
|
||||
if CompareFilenamesIgnoreCase(ShortFilename,FileInfo.Name)=0 then begin
|
||||
Result:=FileInfo.Name;
|
||||
if ShortFilename=FileInfo.Name then break;
|
||||
end;
|
||||
@ -1730,7 +1815,7 @@ begin
|
||||
if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='')
|
||||
then
|
||||
continue;
|
||||
if CompareText(FileInfo.Name,ShortFile)=0 then begin
|
||||
if CompareFilenamesIgnoreCase(FileInfo.Name,ShortFile)=0 then begin
|
||||
if FileInfo.Name=ShortFile then begin
|
||||
// file found, with correct name
|
||||
Result:=FileInfo.Name;
|
||||
|
@ -287,6 +287,7 @@ begin
|
||||
and (not CreateScanners(Tool.Scanners)) then
|
||||
exit;
|
||||
|
||||
debugln(['TOutputFilter.Execute ',dbgsname(fProcess)]);
|
||||
if fProcess is TAsyncProcess then begin
|
||||
TheAsyncProcess:=TAsyncProcess(fProcess);
|
||||
TheAsyncProcess.OnReadData:=@OnAsyncReadData;
|
||||
|
@ -32,12 +32,18 @@ uses
|
||||
{$ifdef Windows}
|
||||
{$define CaseInsensitiveFilenames}
|
||||
{$endif}
|
||||
{$IF defined(CaseInsensitiveFilenames) or defined(darwin)}
|
||||
{$DEFINE NotLiteralFilenames}
|
||||
{$ENDIF}
|
||||
|
||||
const
|
||||
UTF8FileHeader = #$ef#$bb#$bf;
|
||||
FilenamesCaseSensitive = {$IFDEF CaseInsensitiveFilenames}false{$ELSE}true{$ENDIF};// lower and upper letters are treated the same
|
||||
FilenamesLiteral = {$IFDEF NotLiteralFilenames}false{$ELSE}true{$ENDIF};// file names can be compared using = string operator
|
||||
|
||||
// file attributes and states
|
||||
function CompareFilenames(const Filename1, Filename2: string): integer;
|
||||
function CompareFilenamesIgnoreCase(const Filename1, Filename2: string): integer;
|
||||
function CompareFilenames(const Filename1, Filename2: string;
|
||||
ResolveLinks: boolean): integer;
|
||||
function CompareFilenames(Filename1: PChar; Len1: integer;
|
||||
@ -106,6 +112,9 @@ function SearchAllFilesInPath(const Filename, BasePath, SearchPath,
|
||||
function FindDiskFilename(const Filename: string): string;
|
||||
function FindDiskFileCaseInsensitive(const Filename: string): string;
|
||||
function FindDefaultExecutablePath(const Executable: string): string;
|
||||
{$IFDEF darwin}
|
||||
function GetDarwinSystemFilename(Filename: string): string;
|
||||
{$ENDIF}
|
||||
|
||||
type
|
||||
|
||||
@ -213,6 +222,9 @@ uses
|
||||
{$IFDEF windows}
|
||||
Windows;
|
||||
{$ELSE}
|
||||
{$IFDEF darwin}
|
||||
MacOSAll,
|
||||
{$ENDIF}
|
||||
Unix, BaseUnix;
|
||||
{$ENDIF}
|
||||
|
||||
|
@ -90,6 +90,25 @@ begin
|
||||
Result:=s;
|
||||
end;
|
||||
|
||||
{$IFDEF darwin}
|
||||
function GetDarwinSystemFilename(Filename: string): string;
|
||||
var
|
||||
s: CFStringRef;
|
||||
l: CFIndex;
|
||||
begin
|
||||
if Filename='' then exit('');
|
||||
s:=CFStringCreateWithCString(nil,Pointer(Filename),kCFStringEncodingUTF8);
|
||||
l:=CFStringGetMaximumSizeOfFileSystemRepresentation(s);
|
||||
SetLength(Result,l);
|
||||
if Result<>'' then begin
|
||||
CFStringGetFileSystemRepresentation(s,@Result[1],length(Result));
|
||||
SetLength(Result,StrLen(PChar(Result)));
|
||||
end;
|
||||
CFRelease(s);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
function FileExistsUTF8(const Filename: string): boolean;
|
||||
begin
|
||||
Result:=SysUtils.FileExists(UTF8ToSys(Filename));
|
||||
@ -245,11 +264,47 @@ end;
|
||||
function CompareFilenames(const Filename1, Filename2: string): integer;
|
||||
------------------------------------------------------------------------------}
|
||||
function CompareFilenames(const Filename1, Filename2: string): integer;
|
||||
{$IFDEF darwin}
|
||||
var
|
||||
F1: CFStringRef;
|
||||
F2: CFStringRef;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
Result:=AnsiCompareText(Filename1, Filename2);
|
||||
{$IFDEF darwin}
|
||||
if Filename1=Filename2 then exit(0);
|
||||
if (Filename1='') or (Filename2='') then
|
||||
exit(length(Filename2)-length(Filename1));
|
||||
F1:=CFStringCreateWithCString(nil,Pointer(Filename1),kCFStringEncodingUTF8);
|
||||
F2:=CFStringCreateWithCString(nil,Pointer(Filename2),kCFStringEncodingUTF8);
|
||||
Result:=CFStringCompare(F1,F2,kCFCompareNonliteral);
|
||||
CFRelease(F1);
|
||||
CFRelease(F2);
|
||||
{$ELSE}
|
||||
Result:=CompareStr(Filename1, Filename2);
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
Result:=AnsiCompareText(Filename1, Filename2);
|
||||
{$ELSE}
|
||||
Result:=CompareStr(Filename1, Filename2);
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function CompareFilenamesIgnoreCase(const Filename1, Filename2: string
|
||||
): integer;
|
||||
{$IFDEF darwin}
|
||||
var
|
||||
F1: CFStringRef;
|
||||
F2: CFStringRef;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IFDEF darwin}
|
||||
if Filename1=Filename2 then exit(0);
|
||||
F1:=CFStringCreateWithCString(nil,Pointer(Filename1),kCFStringEncodingUTF8);
|
||||
F2:=CFStringCreateWithCString(nil,Pointer(Filename2),kCFStringEncodingUTF8);
|
||||
Result:=CFStringCompare(F1,F2,kCFCompareNonliteral+kCFCompareCaseInsensitive);
|
||||
CFRelease(F1);
|
||||
CFRelease(F2);
|
||||
{$ELSE}
|
||||
Result:=AnsiCompareText(Filename1, Filename2);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
@ -279,7 +334,7 @@ function CompareFilenames(Filename1: PChar; Len1: integer;
|
||||
var
|
||||
File1: string;
|
||||
File2: string;
|
||||
{$IFNDEF CaseInsensitiveFilenames}
|
||||
{$IFNDEF NotLiteralFilenames}
|
||||
i: Integer;
|
||||
{$ENDIF}
|
||||
begin
|
||||
@ -289,16 +344,16 @@ begin
|
||||
end;
|
||||
if ResolveLinks then begin
|
||||
SetLength(File1,Len1);
|
||||
Move(Filename1^,File1[1],Len1);
|
||||
System.Move(Filename1^,File1[1],Len1);
|
||||
SetLength(File2,Len2);
|
||||
Move(Filename2^,File2[1],Len2);
|
||||
System.Move(Filename2^,File2[1],Len2);
|
||||
Result:=CompareFilenames(File1,File2,true);
|
||||
end else begin
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
{$IFDEF NotLiteralFilenames}
|
||||
SetLength(File1,Len1);
|
||||
Move(Filename1^,File1[1],Len1);
|
||||
System.Move(Filename1^,File1[1],Len1);
|
||||
SetLength(File2,Len2);
|
||||
Move(Filename2^,File2[1],Len2);
|
||||
System.Move(Filename2^,File2[1],Len2);
|
||||
Result:=CompareFilenames(File1,File2);
|
||||
{$ELSE}
|
||||
Result:=0;
|
||||
@ -403,7 +458,7 @@ function TrimFilename(const AFilename: string): string;
|
||||
if (i<l) and (TheFilename[i+1]='.')
|
||||
and ((i+1=l) or ((i+2<=l) and (TheFilename[i+2]=PathDelim))) then exit;
|
||||
end;
|
||||
|
||||
|
||||
end;
|
||||
inc(i);
|
||||
end;
|
||||
@ -766,14 +821,25 @@ begin
|
||||
end;
|
||||
|
||||
function FileSize(const Filename: string): int64;
|
||||
{$IFDEF Unix}
|
||||
var
|
||||
st : baseunix.stat;
|
||||
{$ELSE}
|
||||
var
|
||||
FileInfo: TSearchRec;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IFDEF Unix}
|
||||
if not fpstat(pointer(Filename),st)>=0 then
|
||||
exit(-1);
|
||||
Result:=st.st_size;
|
||||
{$ELSE}
|
||||
if FindFirstUTF8(Filename,faAnyFile,FileInfo)=0 then begin
|
||||
Result:=FileInfo.Size;
|
||||
end else
|
||||
Result:=-1;
|
||||
FindCloseUTF8(FileInfo);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -1166,6 +1232,10 @@ var
|
||||
ResultPos: Integer;
|
||||
i: Integer;
|
||||
FileNameRestLen: Integer;
|
||||
CmpBaseDirectory: String;
|
||||
CmpFilename: String;
|
||||
p: Integer;
|
||||
DirCount: Integer;
|
||||
begin
|
||||
Result:=Filename;
|
||||
if (BaseDirectory='') or (Filename='') then exit;
|
||||
@ -1177,55 +1247,69 @@ begin
|
||||
then
|
||||
exit;
|
||||
{$ENDIF}
|
||||
CmpBaseDirectory:=BaseDirectory;
|
||||
CmpFilename:=Filename;
|
||||
{$IFDEF darwin}
|
||||
CmpBaseDirectory:=GetDarwinSystemFilename(CmpBaseDirectory);
|
||||
CmpFilename:=GetDarwinSystemFilename(CmpFilename);
|
||||
{$ENDIF}
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
CmpBaseDirectory:=AnsiUpperCaseFileName(CmpBaseDirectory);
|
||||
CmpFilename:=AnsiUpperCaseFileName(CmpFilename);
|
||||
{$ENDIF}
|
||||
|
||||
FileNameLength:=length(Filename);
|
||||
BaseDirLen:=length(BaseDirectory);
|
||||
FileNameLength:=length(CmpFilename);
|
||||
if CmpFilename[FileNameLength]=PathDelim then
|
||||
dec(FileNameLength);
|
||||
BaseDirLen:=length(CmpBaseDirectory);
|
||||
if CmpBaseDirectory[BaseDirLen]=PathDelim then
|
||||
dec(BaseDirLen);
|
||||
if BaseDirLen=0 then exit;
|
||||
|
||||
// skip matching directories
|
||||
MinLen:=FileNameLength;
|
||||
if MinLen>BaseDirLen then MinLen:=BaseDirLen;
|
||||
SamePos:=1;
|
||||
while (SamePos<=MinLen) do begin
|
||||
{$IFDEF CaseInsensitiveFilenames}
|
||||
if AnsiStrLIComp(@FileName[SamePos],@BaseDirectory[SamePos],1)=0
|
||||
{$ELSE}
|
||||
if FileName[SamePos]=BaseDirectory[SamePos]
|
||||
{$ENDIF}
|
||||
then
|
||||
inc(SamePos)
|
||||
else
|
||||
break;
|
||||
p:=1;
|
||||
DirCount:=0;
|
||||
while (p<=MinLen) and (CmpFileName[p]=CmpBaseDirectory[p]) do
|
||||
begin
|
||||
if CmpFilename[p]=PathDelim then
|
||||
inc(DirCount);
|
||||
inc(p);
|
||||
end;
|
||||
if (SamePos>MinLen)
|
||||
and (((SamePos<=BaseDirLen) and (BaseDirectory[SamePos]=PathDelim))
|
||||
or ((SamePos<=FileNameLength) and (Filename[SamePos]=PathDelim))
|
||||
or (BaseDirLen=FileNameLength))
|
||||
then begin
|
||||
// Filename lies in BaseDirectory
|
||||
// or Filename is parent directory of BaseDirectory
|
||||
// or Filename is BaseDirectory
|
||||
end else begin
|
||||
// difference found -> step back to path delimiter
|
||||
repeat
|
||||
dec(SamePos);
|
||||
if (SamePos<1) then exit;
|
||||
until (FileName[SamePos]=PathDelim);
|
||||
end;
|
||||
if (SamePos=1) and (Filename[1]=PathDelim) then exit;
|
||||
if ((p>BaseDirLen) or (CmpBaseDirectory[p]=PathDelim))
|
||||
and ((p>FileNameLength) or (CmpFilename[p]=PathDelim)) then
|
||||
inc(DirCount);
|
||||
if DirCount=0 then exit;
|
||||
|
||||
// calculate needed up directories
|
||||
UpDirCount:=0;
|
||||
BaseDirPos:=SamePos+1;
|
||||
BaseDirLen:=length(BaseDirectory);
|
||||
UpDirCount:=-DirCount;
|
||||
BaseDirPos:=1;
|
||||
while (BaseDirPos<=BaseDirLen) do begin
|
||||
if (BaseDirectory[BaseDirPos]=PathDelim) then
|
||||
inc(UpDirCount);
|
||||
inc(BaseDirPos);
|
||||
end;
|
||||
if (SamePos<BaseDirLen) and (BaseDirectory[BaseDirLen]<>PathDelim) then
|
||||
if (BaseDirLen>0) and (BaseDirectory[BaseDirLen]<>PathDelim) then
|
||||
inc(UpDirCount);
|
||||
|
||||
// create relative filename
|
||||
FileNameRestLen:=FileNameLength-SamePos;
|
||||
SamePos:=1;
|
||||
p:=0;
|
||||
FileNameLength:=length(Filename);
|
||||
while (SamePos<=FileNameLength) do begin
|
||||
if (Filename[SamePos]=PathDelim) then begin
|
||||
inc(p);
|
||||
if p>=DirCount then begin
|
||||
inc(SamePos);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
inc(SamePos);
|
||||
end;
|
||||
FileNameRestLen:=FileNameLength-SamePos+1;
|
||||
//writeln('DirCount=',DirCount,' UpDirCount=',UpDirCount,' FileNameRestLen=',FileNameRestLen,' SamePos=',SamePos);
|
||||
SetLength(Result,3*UpDirCount+FileNameRestLen);
|
||||
ResultPos:=1;
|
||||
for i:=1 to UpDirCount do begin
|
||||
@ -1235,7 +1319,7 @@ begin
|
||||
inc(ResultPos,3);
|
||||
end;
|
||||
if FileNameRestLen>0 then
|
||||
Move(Filename[SamePos+1],Result[ResultPos],FileNameRestLen);
|
||||
System.Move(Filename[SamePos],Result[ResultPos],FileNameRestLen);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -1478,7 +1562,7 @@ begin
|
||||
if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='')
|
||||
then
|
||||
continue;
|
||||
if CompareText(FileInfo.Name,CurFile)=0 then begin
|
||||
if CompareFilenamesIgnoreCase(FileInfo.Name,CurFile)=0 then begin
|
||||
//debugln('FindDiskFilename ',FileInfo.Name,' ',CurFile);
|
||||
if FileInfo.Name=CurFile then begin
|
||||
// file found, has already the correct name
|
||||
@ -1522,7 +1606,7 @@ begin
|
||||
if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='')
|
||||
then
|
||||
continue;
|
||||
if CompareText(FileInfo.Name,ShortFilename)=0 then begin
|
||||
if CompareFilenamesIgnoreCase(FileInfo.Name,ShortFilename)=0 then begin
|
||||
if FileInfo.Name=ShortFilename then begin
|
||||
// fits exactly
|
||||
Result:=Filename;
|
||||
|
Loading…
Reference in New Issue
Block a user