codetools: FilenameIsMatching: fixed bracket at end of mask, FindPathInSearchPath: using CompareFilenames

git-svn-id: trunk@24964 -
This commit is contained in:
mattias 2010-04-26 12:22:02 +00:00
parent 04e8257632
commit b885edf472
2 changed files with 138 additions and 34 deletions

View File

@ -546,6 +546,18 @@ const
DefineTemplateFlagNames: array[TDefineTemplateFlag] of shortstring = (
'AutoGenerated'
);
type
TShortFilenameTreeItem = class
public
ShortFilename: string; // = ExtractFilename(Filename)
Filename: string;
end;
TShortFilenameTree = class
public
end;
function DefineActionNameToAction(const s: string): TDefineAction;
function DefineTemplateFlagsToString(Flags: TDefineTemplateFlags): string;
@ -560,11 +572,13 @@ function GetDefaultCompilerFilename: string;
function CreateDefinesInDirectories(const SourcePaths, FlagName: string
): TDefineTemplate;
function GatherFiles(Directory, ExcludeDirMask, IncludeFileMask: string
): TStringList;
procedure ReadMakefileFPC(const Filename: string; List: TStrings);
procedure ParseMakefileFPC(const Filename, SrcOS: string;
var Dirs, SubDirs: string);
implementation
@ -580,6 +594,54 @@ type
// some useful functions
function GatherFiles(Directory, ExcludeDirMask, IncludeFileMask: string): TStringList;
{ ExcludeDirMask: check FilenameIsMatching vs the short file name of a directory
IncludeFileMask: check FilenameIsMatching vs the short file name of a file
}
procedure Search(CurDir: string);
var
FileInfo: TSearchRec;
ShortFilename: String;
Filename: String;
begin
DebugLn(['Search CurDir=',CurDir]);
if FindFirstUTF8(CurDir+FileMask,faAnyFile,FileInfo)=0 then begin
repeat
ShortFilename:=FileInfo.Name;
if (ShortFilename='') or (ShortFilename='.') or (ShortFilename='..') then
continue;
debugln(['Search ShortFilename=',ShortFilename,' IsDir=',(FileInfo.Attr and faDirectory)>0]);
Filename:=CurDir+ShortFilename;
if (FileInfo.Attr and faDirectory)>0 then begin
// directory
if (ExcludeDirMask='')
or (FilenameIsMatching(ExcludeDirMask,ShortFilename,true))
then begin
Search(Filename+PathDelim);
end else begin
DebugLn(['Search DIR MISMATCH ',Filename]);
end;
end else begin
// file
if (IncludeFileMask='')
or FilenameIsMatching(IncludeFileMask,ShortFilename,true) then begin
DebugLn(['Search ADD ',Filename]);
GatherFiles.Add(Filename);
end else begin
DebugLn(['Search MISMATCH ',Filename]);
end;
end;
until FindNextUTF8(FileInfo)<>0;
end;
FindCloseUTF8(FileInfo);
end;
begin
Result:=TStringList.Create;
Search(CleanAndExpandDirectory(Directory));
end;
procedure ReadMakefileFPC(const Filename: string; List: TStrings);
var
MakefileFPC: TStringList;

View File

@ -129,6 +129,7 @@ function SearchPascalFileInDir(const ShortFilename, BaseDirectory: string;
function SearchPascalFileInPath(const ShortFilename, BasePath, SearchPath,
Delimiter: string; SearchCase: TCTSearchFileCase): string;
// search paths
function CreateAbsoluteSearchPath(const SearchPath, BaseDirectory: string): string;
function CreateRelativeSearchPath(const SearchPath, BaseDirectory: string): string;
function MinimizeSearchPath(const SearchPath: string): string;
@ -1791,13 +1792,32 @@ var
EndPos: LongInt;
NextStartPos: LongInt;
CmpPos: LongInt;
UseQuickCompare: Boolean;
PathStr: String;
CurFilename: String;
begin
Result:=nil;
if SearchPath=nil then exit;
if APath=nil then exit;
if (APath=nil) or (APathLen=0) then exit;
// ignore trailing PathDelim at end
while (APathLen>1) and (APath[APathLen-1]=PathDelim) do dec(APathLen);
{$IFDEF CaseInsensitiveFilenames}
UseQuickCompare:=false;
{$ELSE}
{$IFDEF NotLiteralFilenames}
CmpPos:=0;
while (CmpPos<APathLen) and (ord(APath[CmpPos]<128)) do inc(CmpPos);
UseQuickCompare:=CmpPos=APathLen;
{$ELSE}
UseQuickCompare:=true;
{$ENDIF}
{$ENDIF}
if not UseQuickCompare then begin
SetLength(PathStr,APathLen);
System.Move(APath^,PathStr[1],APathLen);
end;
StartPos:=0;
while StartPos<SearchPathLen do begin
// find current path bounds
@ -1809,14 +1829,25 @@ begin
while (EndPos>StartPos+1) and (SearchPath[EndPos-1]=PathDelim) do
dec(EndPos);
// compare current path
if EndPos-StartPos=APathLen then begin
CmpPos:=0;
while CmpPos<APathLen do begin
if APath[CmpPos]<>SearchPath[StartPos+CmpPos] then
break;
inc(CmpPos);
if UseQuickCompare then begin
if EndPos-StartPos=APathLen then begin
CmpPos:=0;
while CmpPos<APathLen do begin
if APath[CmpPos]<>SearchPath[StartPos+CmpPos] then
break;
inc(CmpPos);
end;
if CmpPos=APathLen then begin
Result:=@SearchPath[StartPos];
exit;
end;
end;
if CmpPos=APathLen then begin
end else if EndPos>StartPos then begin
// use CompareFilenames
CurFilename:='';
SetLength(CurFilename,EndPos-StartPos);
System.Move(SearchPath[StartPos],CurFilename[1],EndPos-StartPos);
if CompareFilenames(PathStr,CurFilename)=0 then begin
Result:=@SearchPath[StartPos];
exit;
end;
@ -2026,8 +2057,33 @@ var
DirStartFile, DirEndFile,
AsteriskPos,
BracketMaskPos, BracketFilePos: integer;
function TryNextOr: boolean;
begin
Result:=false;
if BracketMaskPos<1 then exit;
repeat
inc(DirStartMask);
if DirStartMask>=DirEndMask then exit; // error, missing }
if Mask[DirStartMask]=SpecialChar then begin
// special char -> next char is normal char
inc(DirStartMask);
end else if Mask[DirStartMask]='}' then begin
// bracket found (= end of Or operator)
// -> filename does not match
exit;
end else if Mask[DirStartMask]=',' then begin
// next Or found
// -> reset filename position and compare
inc(DirStartMask);
DirStartFile:=BracketFilePos;
exit(true);
end;
until false;
end;
begin
//debugln('[FilenameIsMatching] Mask="',Mask,'" Filename="',Filename,'" MatchExactly=',MatchExactly);
//debugln(['[FilenameIsMatching] Mask="',Mask,'" Filename="',Filename,'" MatchExactly=',MatchExactly]);
Result:=false;
if (Filename='') then exit;
if (Mask='') then begin
@ -2043,19 +2099,21 @@ begin
// find ends of directories
DirEndMask:=FindDirectoryEnd(Mask,DirStartMask);
DirEndFile:=FindDirectoryEnd(Filename,DirStartFile);
// debugln(' Compare "',copy(Mask,DirStartMask,DirEndMask-DirStartMask),'"',
// ' "',copy(Filename,DirStartFile,DirEndFile-DirStartFile),'"');
//debugln(' Compare "',copy(Mask,DirStartMask,DirEndMask-DirStartMask),'"',
//' "',copy(Filename,DirStartFile,DirEndFile-DirStartFile),'"');
// compare directories
AsteriskPos:=0;
BracketMaskPos:=0;
while (DirStartMask<DirEndMask) and (DirStartFile<DirEndFile) do begin
//debugln('FilenameIsMatching ',DirStartMask,' ',Mask[DirStartMask],' - ',DirStartFile,' ',Filename[DirStartFile]);
while (DirStartMask<DirEndMask) do begin
//debugln(['FilenameIsMatching ',DirStartMask,' ',Mask[DirStartMask],' - ',DirStartFile,' ',Pchar(Filename)[DirStartFile-1]]);
case Mask[DirStartMask] of
'?':
begin
if DirStartFile<DirEndFile then begin
inc(DirStartMask);
inc(DirStartFile);
continue;
end else begin
if not TryNextOr then exit;
end;
'*':
begin
@ -2105,31 +2163,15 @@ begin
if (DirStartMask>=DirEndMask) then exit;
end;
// compare char
if CharsEqual(Mask[DirStartMask],Filename[DirStartFile]) then begin
if (DirStartFile<DirEndFile)
and CharsEqual(Mask[DirStartMask],Filename[DirStartFile]) then begin
inc(DirStartMask);
inc(DirStartFile);
end else begin
// chars different
if BracketMaskPos>0 then begin
// try next Or
repeat
inc(DirStartMask);
if DirStartMask>=DirEndMask then exit; // error, missing }
if Mask[DirStartMask]=SpecialChar then begin
// special char -> next char is normal char
inc(DirStartMask);
end else if Mask[DirStartMask]='}' then begin
// bracket found (= end of Or operator)
// -> filename does not match
exit;
end else if Mask[DirStartMask]=',' then begin
// next Or found
// -> reset filename position and compare
inc(DirStartMask);
DirStartFile:=BracketFilePos;
break;
end;
until false;
if not TryNextOr then exit;
end else if AsteriskPos>0 then begin
// * operator always fits
inc(DirStartFile);