
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4412 8e941d3f-bd1b-0410-a28a-d453659cc2b4
281 lines
7.9 KiB
ObjectPascal
281 lines
7.9 KiB
ObjectPascal
{
|
|
*****************************************************************************
|
|
* *
|
|
* This file is part of the iPhone Laz Extension *
|
|
* *
|
|
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
|
* for details about the copyright. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
* *
|
|
*****************************************************************************
|
|
}
|
|
unit LazFilesUtils;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$ifdef Unix}BaseUnix,{$endif}
|
|
Classes, SysUtils, FileUtil, LazFileUtils, Masks,
|
|
LazIDEIntf, ProjectIntf, process;
|
|
|
|
function ResolveProjectPath(const path: string; project: TLazProject = nil): string;
|
|
|
|
function BreakPathsStringToOption(const Paths, Switch: String;
|
|
const Quotes: string = '"'; project: TLazProject = nil; AResolvePath: Boolean = false): String;
|
|
|
|
function RelativeToFullPath(const BasePath, Relative: string): String;
|
|
function NeedQuotes(const path: string): Boolean;
|
|
|
|
function CopySymLinks(const SrcDir, DstDir, FilterMask: string): Boolean;
|
|
|
|
procedure EnumFilesAtDir(const PathUtf8 : AnsiString; Dst: TStrings);
|
|
procedure EnumFilesAtDir(const PathUtf8, AMask : AnsiString; Dst: TStrings);
|
|
procedure ExecCmdLineNoWait(const CmdLineUtf8: AnsiString);
|
|
function ExecCmdLineStdOut(const CmdLineUtf8: AnsiString; var StdOut: string; var ErrCode: LongWord): Boolean;
|
|
|
|
implementation
|
|
|
|
{$ifdef Unix}
|
|
function CopySymLinks(const SrcDir, DstDir, FilterMask: string): Boolean;
|
|
var
|
|
allfiles : TStringList;
|
|
i : Integer;
|
|
pth : string;
|
|
MaskList : TMaskList;
|
|
curdir : string;
|
|
linkdir : string;
|
|
linkname : string;
|
|
begin
|
|
Result:=DirectoryExistsUTF8(SrcDir) and ForceDirectoriesUTF8(DstDir);
|
|
if not Result then Exit;
|
|
|
|
//todo: don't use FindAllFiles(), use sub dir search
|
|
|
|
allfiles:=FindAllFiles(SrcDir, AllFilesMask, False);
|
|
Result:=Assigned(allfiles);
|
|
if not Result then Exit;
|
|
|
|
MaskList := TMaskList.Create(FilterMask);
|
|
|
|
curdir:=IncludeTrailingPathDelimiter(SrcDir);
|
|
linkdir:=IncludeTrailingPathDelimiter(DstDir);
|
|
for i:=0 to allfiles.Count-1 do begin
|
|
pth:=allfiles[i];
|
|
if (FilterMask='') or (not MaskList.Matches(pth)) then begin
|
|
linkname:=linkdir+Copy(pth, length(curdir), length(pth));
|
|
fpSymlink(PAnsiChar(pth), PAnsiChar(linkname));
|
|
end;
|
|
end;
|
|
allfiles.Free;
|
|
end;
|
|
{$else}
|
|
function CopySymLinks(const SrcDir, DstDir, FilterMask: string): Boolean;
|
|
begin
|
|
Result:=false;
|
|
end;
|
|
{$endif}
|
|
|
|
|
|
function GetNextDir(const Path: string; var index: integer; var Name: string): Boolean;
|
|
var
|
|
i : Integer;
|
|
begin
|
|
Result:=index<=length(Path);
|
|
if not Result then Exit;
|
|
|
|
if Path[index]=PathDelim then inc(index);
|
|
Result:=index<=length(Path);
|
|
if not Result then Exit;
|
|
|
|
for i:=index to length(Path) do
|
|
if Path[i]=PathDelim then begin
|
|
Name:=Copy(Path, index, i - index);
|
|
index:=i+1;
|
|
Exit;
|
|
end;
|
|
Name:=Copy(Path, index, length(Path) - index+1);
|
|
index:=length(Path)+1;
|
|
end;
|
|
|
|
function RelativeToFullPath(const BasePath, Relative: string): String;
|
|
var
|
|
i : integer;
|
|
nm : string;
|
|
begin
|
|
Result:=ExcludeTrailingPathDelimiter(BasePath);
|
|
i:=1;
|
|
while GetNextDir(Relative, i, nm) do
|
|
if nm = '..' then
|
|
Result:=ExtractFileDir(Result)
|
|
else if nm <> '.' then
|
|
Result:=IncludeTrailingPathDelimiter(Result)+nm;
|
|
end;
|
|
|
|
function NeedQuotes(const path: string): Boolean;
|
|
var
|
|
i : integer;
|
|
const
|
|
SpaceChars = [#32,#9];
|
|
begin
|
|
for i:=1 to length(path) do
|
|
if path[i] in SpaceChars then begin
|
|
Result:=true;
|
|
Exit;
|
|
end;
|
|
Result:=false;
|
|
end;
|
|
|
|
function QuoteStrIfNeeded(const path: string; const quotes: String): String;
|
|
begin
|
|
if NeedQuotes(path) then
|
|
Result:=quotes+path+quotes
|
|
else
|
|
Result:=path;
|
|
end;
|
|
|
|
function ResolveProjectPath(const path: string; project: TLazProject): string;
|
|
var
|
|
base : string;
|
|
begin
|
|
if project=nil then project:=LazarusIDE.ActiveProject;
|
|
|
|
if FilenameIsAbsolute(Path) then
|
|
Result:=Path
|
|
else begin
|
|
base:='';
|
|
base:=ExtractFilePath(project.ProjectInfoFile);
|
|
Result:=RelativeToFullPath(base, Path);
|
|
end;
|
|
end;
|
|
|
|
function BreakPathsStringToOption(const Paths, Switch, Quotes: String; project: TLazProject; AResolvePath: Boolean): String;
|
|
var
|
|
i, j : Integer;
|
|
fixed : String;
|
|
begin
|
|
Result:='';
|
|
if not Assigned(project) then
|
|
project:=LazarusIDE.ActiveProject;
|
|
|
|
if not Assigned(project) then Exit;
|
|
|
|
j:=1;
|
|
for i:=1 to length(paths)-1 do
|
|
if Paths[i]=';' then begin
|
|
fixed:=Trim(Copy(paths,j, i-j) );
|
|
if fixed<>'' then begin
|
|
if AResolvePath then fixed:=ResolveProjectPath(fixed, project);
|
|
Result:=Result+' ' + Switch + QuoteStrIfNeeded(fixed, quotes);
|
|
end;
|
|
j:=i+1;
|
|
end;
|
|
|
|
fixed:=Trim(Copy(paths,j, length(paths)-j+1) );
|
|
if fixed<>'' then begin
|
|
if AResolvePath then fixed:=ResolveProjectPath(fixed, project);
|
|
Result:=Result+' ' + Switch + QuoteStrIfNeeded(fixed, quotes);
|
|
end;
|
|
end;
|
|
|
|
procedure EnumFilesAtDir(const PathUtf8, AMask : AnsiString; Dst: TStrings);
|
|
var
|
|
mask : TMask;
|
|
sr : TSearchRec;
|
|
path : AnsiString;
|
|
begin
|
|
if (AMask='') or (trim(AMask)='*') then mask:=nil else mask:=TMask.Create(AMask);
|
|
try
|
|
path:=IncludeTrailingPathDelimiter(PathUtf8);
|
|
if FindFirstUTF8(path+AllFilesMask, faAnyFile, sr) = 0 then begin
|
|
repeat
|
|
if (sr.Name<>'.') and (sr.Name<>'..') then
|
|
if not Assigned(mask) or mask.Matches(sr.Name) then
|
|
Dst.Add(path+sr.Name);
|
|
until FindNextUTF8(sr)<>0;
|
|
FindCloseUTF8(sr);
|
|
end;
|
|
finally
|
|
mask.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure EnumFilesAtDir(const PathUtf8 : AnsiString; Dst: TStrings);
|
|
begin
|
|
EnumFilesAtDir(PathUTF8, AllFilesMask, Dst);
|
|
end;
|
|
|
|
procedure ExecCmdLineNoWait(const CmdLineUtf8: AnsiString);
|
|
var
|
|
proc : TProcess;
|
|
begin
|
|
proc:=TProcess.Create(nil);
|
|
try
|
|
proc.CommandLine:=CmdLineUtf8;
|
|
proc.Options := [poUsePipes,poNoConsole,poStderrToOutPut];
|
|
proc.Execute;
|
|
finally
|
|
proc.Free;
|
|
end;
|
|
end;
|
|
|
|
function ExecCmdLineStdOut(const CmdLineUtf8: AnsiString; var StdOut: string; var ErrCode: LongWord): Boolean;
|
|
var
|
|
//OurCommand : String;
|
|
//OutputLines : TStringList;
|
|
MemStream : TStringStream;
|
|
OurProcess : TProcess;
|
|
//NumBytes : LongInt;
|
|
begin
|
|
// A temp Memorystream is used to buffer the output
|
|
MemStream := TStringStream.Create('');
|
|
|
|
OurProcess := TProcess.Create(nil);
|
|
try
|
|
OurProcess.CommandLine := CmdLineUtf8;
|
|
//OurProcess.Executable := CmdLineUtf8;
|
|
//OurProcess.Parameters.Add(OurCommand);
|
|
|
|
// We cannot use poWaitOnExit here since we don't
|
|
// know the size of the output. On Linux the size of the
|
|
// output pipe is 2 kB; if the output data is more, we
|
|
// need to read the data. This isn't possible since we are
|
|
// waiting. So we get a deadlock here if we use poWaitOnExit.
|
|
OurProcess.Options := [poUsePipes];
|
|
OurProcess.Execute;
|
|
while True do
|
|
begin
|
|
// make sure we have room
|
|
//MemStream.SetSize(BytesRead + READ_BYTES);
|
|
|
|
// try reading it
|
|
if OurProcess.Output.NumBytesAvailable > 0 then
|
|
MemStream.CopyFrom(OurProcess.Output, OurProcess.Output.NumBytesAvailable)
|
|
else begin
|
|
if not OurProcess.Active then
|
|
Break; // Program has finished execution.
|
|
end;
|
|
|
|
end;
|
|
//MemStream.SetSize(BytesRead);
|
|
|
|
//OutputLines := TStringList.Create;
|
|
//OutputLines.LoadFromStream(MemStream);
|
|
//OutputLines.Free;
|
|
|
|
StdOut:=MemStream.DataString;
|
|
Result:=true;
|
|
finally
|
|
OurProcess.Free;
|
|
MemStream.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
end.
|
|
|