mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 18:09:15 +02:00
* pas2jni: Detect the default units path.
git-svn-id: trunk@32084 -
This commit is contained in:
parent
ab4c8623ec
commit
9193954d1c
@ -36,9 +36,13 @@ type
|
|||||||
TPPUParser = class
|
TPPUParser = class
|
||||||
private
|
private
|
||||||
FOnCheckItem: TOnCheckItem;
|
FOnCheckItem: TOnCheckItem;
|
||||||
|
FDefaultSearchPathAdded: boolean;
|
||||||
function FindUnit(const AName: string): string;
|
function FindUnit(const AName: string): string;
|
||||||
function ReadUnit(const AName: string): string;
|
function ReadUnit(const AName: string): string;
|
||||||
function InternalParse(const AUnitName: string): TUnitDef;
|
function InternalParse(const AUnitName: string): TUnitDef;
|
||||||
|
procedure AddSearchPath(const ASearchPath: string);
|
||||||
|
function ReadProcessOutput(const AExeName, AParams: string; var AOutput, AError: string): integer;
|
||||||
|
procedure AddDefaultSearchPath(const ACPU, AOS: string);
|
||||||
public
|
public
|
||||||
SearchPath: TStringList;
|
SearchPath: TStringList;
|
||||||
Units: TDef;
|
Units: TDef;
|
||||||
@ -112,31 +116,9 @@ end;
|
|||||||
{ TPPUParser }
|
{ TPPUParser }
|
||||||
|
|
||||||
constructor TPPUParser.Create(const ASearchPath: string);
|
constructor TPPUParser.Create(const ASearchPath: string);
|
||||||
var
|
|
||||||
i, j: integer;
|
|
||||||
s, d: string;
|
|
||||||
sr: TSearchRec;
|
|
||||||
begin
|
begin
|
||||||
SearchPath:=TStringList.Create;
|
SearchPath:=TStringList.Create;
|
||||||
SearchPath.Delimiter:=';';
|
AddSearchPath(ASearchPath);
|
||||||
SearchPath.DelimitedText:=ASearchPath;
|
|
||||||
i:=0;
|
|
||||||
while i < SearchPath.Count do begin
|
|
||||||
s:=SearchPath[i];
|
|
||||||
if (Pos('*', s) > 0) or (Pos('?', s) > 0) then begin
|
|
||||||
d:=ExtractFilePath(s);
|
|
||||||
j:=FindFirst(s, faDirectory, sr);
|
|
||||||
while j = 0 do begin
|
|
||||||
if (sr.Name <> '.') and (sr.Name <> '..') then
|
|
||||||
SearchPath.Add(d + sr.Name);
|
|
||||||
j:=FindNext(sr);
|
|
||||||
end;
|
|
||||||
FindClose(sr);
|
|
||||||
SearchPath.Delete(i);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Inc(i);
|
|
||||||
end;
|
|
||||||
Units:=TDef.Create(nil, dtNone);
|
Units:=TDef.Create(nil, dtNone);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -171,68 +153,31 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TPPUParser.ReadUnit(const AName: string): string;
|
function TPPUParser.ReadUnit(const AName: string): string;
|
||||||
|
|
||||||
procedure _ReadOutput(o: TInputPipeStream; var s: string);
|
|
||||||
var
|
|
||||||
i, j: integer;
|
|
||||||
begin
|
|
||||||
with o do
|
|
||||||
while NumBytesAvailable > 0 do begin
|
|
||||||
i:=NumBytesAvailable;
|
|
||||||
j:=Length(s);
|
|
||||||
SetLength(s, j + i);
|
|
||||||
ReadBuffer(s[j + 1], i);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
p: TProcess;
|
|
||||||
s, un, err: ansistring;
|
s, un, err: ansistring;
|
||||||
ec: integer;
|
ec: integer;
|
||||||
begin
|
begin
|
||||||
un:=FindUnit(AName);
|
un:=FindUnit(AName);
|
||||||
p:=TProcess.Create(nil);
|
if ppudumpprog = '' then begin
|
||||||
try
|
ppudumpprog:='ppudump';
|
||||||
if ppudumpprog = '' then begin
|
// Check for ppudump in the same folder as pas2jni
|
||||||
ppudumpprog:='ppudump';
|
s:=ExtractFilePath(ParamStr(0));
|
||||||
// Check for ppudump in the same folder as pas2jni
|
if s <> '' then begin
|
||||||
s:=ExtractFilePath(ParamStr(0));
|
s:=s + ppudumpprog + ExtractFileExt(ParamStr(0));
|
||||||
if s <> '' then begin
|
if FileExists(s) then
|
||||||
s:=s + ppudumpprog + ExtractFileExt(ParamStr(0));
|
ppudumpprog:=s;
|
||||||
if FileExists(s) then
|
|
||||||
ppudumpprog:=s;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
p.Executable:=ppudumpprog;
|
end;
|
||||||
p.Parameters.Add('-Fj');
|
ec:=ReadProcessOutput(ppudumpprog, '-Fj' + LineEnding + un, s, err);
|
||||||
p.Parameters.Add(un);
|
if Copy(s, 1, 1) <> '[' then begin
|
||||||
p.Options:=[poUsePipes, poNoConsole];
|
ec:=-1;
|
||||||
p.ShowWindow:=swoHIDE;
|
err:='Output of ppudump is not in JSON format.' + LineEnding + 'Probably old version of ppudump has been used.';
|
||||||
p.StartupOptions:=[suoUseShowWindow];
|
end;
|
||||||
try
|
if ec <> 0 then begin
|
||||||
p.Execute;
|
if err = '' then
|
||||||
except
|
if Length(s) < 300 then
|
||||||
raise Exception.CreateFmt('Unable to run "%s".'+LineEnding+'%s', [p.Executable, Exception(ExceptObject).Message]);
|
err:=s;
|
||||||
end;
|
raise Exception.CreateFmt('Error reading contents of unit "%s" using "%s".'+LineEnding+'Error code: %d'+LineEnding+'%s', [un, ppudumpprog, ec, err]);
|
||||||
s:='';
|
|
||||||
err:='';
|
|
||||||
repeat
|
|
||||||
_ReadOutput(p.Output, s);
|
|
||||||
_ReadOutput(p.Stderr, err);
|
|
||||||
until not p.Running and (p.Output.NumBytesAvailable = 0) and (p.Stderr.NumBytesAvailable = 0);
|
|
||||||
ec:=p.ExitStatus;
|
|
||||||
if Copy(s, 1, 1) <> '[' then begin
|
|
||||||
ec:=-1;
|
|
||||||
err:='Output of ppudump is not in JSON format.' + LineEnding + 'Probably old version of ppudump has been used.';
|
|
||||||
end;
|
|
||||||
if ec <> 0 then begin
|
|
||||||
if err = '' then
|
|
||||||
if Length(s) < 300 then
|
|
||||||
err:=s;
|
|
||||||
raise Exception.CreateFmt('Error reading contents of unit "%s" using "%s".'+LineEnding+'Error code: %d'+LineEnding+'%s', [un, ppudumpprog, ec, err]);
|
|
||||||
end;
|
|
||||||
finally
|
|
||||||
p.Free;
|
|
||||||
end;
|
end;
|
||||||
Result:=s;
|
Result:=s;
|
||||||
{$ifopt D+}
|
{$ifopt D+}
|
||||||
@ -602,8 +547,16 @@ begin
|
|||||||
Result.PPUVer:=junit.Integers['Version'];
|
Result.PPUVer:=junit.Integers['Version'];
|
||||||
Result.CPU:=junit.Strings['TargetCPU'];
|
Result.CPU:=junit.Strings['TargetCPU'];
|
||||||
Result.OS:=junit.Strings['TargetOS'];
|
Result.OS:=junit.Strings['TargetOS'];
|
||||||
|
j:=Length(Result.CPU);
|
||||||
|
if AnsiLowerCase(Copy(Result.OS, Length(Result.OS) - j, j + 1)) = AnsiLowerCase('-' + Result.CPU) then
|
||||||
|
Result.OS:=Copy(Result.OS, 1, Length(Result.OS) - j - 1);
|
||||||
Result.IntfCRC:=junit.Strings['InterfaceCRC'];
|
Result.IntfCRC:=junit.Strings['InterfaceCRC'];
|
||||||
|
|
||||||
|
if not FDefaultSearchPathAdded then begin
|
||||||
|
FDefaultSearchPathAdded:=True;
|
||||||
|
AddDefaultSearchPath(AnsiLowerCase(Result.CPU), AnsiLowerCase(Result.OS));
|
||||||
|
end;
|
||||||
|
|
||||||
if junit.Find('Units') <> nil then
|
if junit.Find('Units') <> nil then
|
||||||
with junit.Arrays['Units'] do begin
|
with junit.Arrays['Units'] do begin
|
||||||
SetLength(deref, Count);
|
SetLength(deref, Count);
|
||||||
@ -641,5 +594,121 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TPPUParser.AddSearchPath(const ASearchPath: string);
|
||||||
|
var
|
||||||
|
i, j: integer;
|
||||||
|
s, d: string;
|
||||||
|
sr: TSearchRec;
|
||||||
|
sl: TStringList;
|
||||||
|
begin
|
||||||
|
sl:=TStringList.Create;
|
||||||
|
try
|
||||||
|
sl.Delimiter:=';';
|
||||||
|
sl.DelimitedText:=ASearchPath;
|
||||||
|
i:=0;
|
||||||
|
while i < sl.Count do begin
|
||||||
|
s:=sl[i];
|
||||||
|
if (Pos('*', s) > 0) or (Pos('?', s) > 0) then begin
|
||||||
|
d:=ExtractFilePath(s);
|
||||||
|
j:=FindFirst(s, faDirectory, sr);
|
||||||
|
while j = 0 do begin
|
||||||
|
if (sr.Name <> '.') and (sr.Name <> '..') then
|
||||||
|
sl.Add(d + sr.Name);
|
||||||
|
j:=FindNext(sr);
|
||||||
|
end;
|
||||||
|
FindClose(sr);
|
||||||
|
sl.Delete(i);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Inc(i);
|
||||||
|
end;
|
||||||
|
SearchPath.AddStrings(sl);
|
||||||
|
finally
|
||||||
|
sl.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPPUParser.ReadProcessOutput(const AExeName, AParams: string; var AOutput, AError: string): integer;
|
||||||
|
|
||||||
|
procedure _ReadOutput(o: TInputPipeStream; var s: string);
|
||||||
|
var
|
||||||
|
i, j: integer;
|
||||||
|
begin
|
||||||
|
with o do
|
||||||
|
while NumBytesAvailable > 0 do begin
|
||||||
|
i:=NumBytesAvailable;
|
||||||
|
j:=Length(s);
|
||||||
|
SetLength(s, j + i);
|
||||||
|
ReadBuffer(s[j + 1], i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
p: TProcess;
|
||||||
|
begin
|
||||||
|
AOutput:='';
|
||||||
|
AError:='';
|
||||||
|
p:=TProcess.Create(nil);
|
||||||
|
try
|
||||||
|
p.Executable:=AExeName;
|
||||||
|
p.Parameters.Text:=AParams;
|
||||||
|
p.Options:=[poUsePipes, poNoConsole];
|
||||||
|
p.ShowWindow:=swoHIDE;
|
||||||
|
p.StartupOptions:=[suoUseShowWindow];
|
||||||
|
try
|
||||||
|
p.Execute;
|
||||||
|
except
|
||||||
|
raise Exception.CreateFmt('Unable to run "%s".'+LineEnding+'%s', [p.Executable, Exception(ExceptObject).Message]);
|
||||||
|
end;
|
||||||
|
repeat
|
||||||
|
_ReadOutput(p.Output, AOutput);
|
||||||
|
_ReadOutput(p.Stderr, AError);
|
||||||
|
until not p.Running and (p.Output.NumBytesAvailable = 0) and (p.Stderr.NumBytesAvailable = 0);
|
||||||
|
Result:=p.ExitStatus;
|
||||||
|
finally
|
||||||
|
p.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TPPUParser.AddDefaultSearchPath(const ACPU, AOS: string);
|
||||||
|
var
|
||||||
|
fpc, s, e: string;
|
||||||
|
sl: TStringList;
|
||||||
|
i, j: integer;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
fpc:=ExtractFilePath(ppudumpprog) + 'fpc' + ExtractFileExt(ppudumpprog);
|
||||||
|
if not FileExists(fpc) then
|
||||||
|
exit;
|
||||||
|
// Find the compiler binary
|
||||||
|
if ReadProcessOutput(fpc, '-P' + ACPU + LineEnding + '-T' + AOS + LineEnding + '-PB', s, e) <> 0 then
|
||||||
|
exit;
|
||||||
|
fpc:=Trim(s);
|
||||||
|
// Get units path from the compiler output
|
||||||
|
ReadProcessOutput(fpc, '-P' + ACPU + LineEnding + '-T' + AOS + LineEnding + '-vt' + LineEnding + '.', s, e);
|
||||||
|
sl:=TStringList.Create;
|
||||||
|
try
|
||||||
|
sl.Text:=s;
|
||||||
|
s:='';
|
||||||
|
for i:=0 to sl.Count - 1 do begin
|
||||||
|
s:=sl[i];
|
||||||
|
j:=Pos(':', s);
|
||||||
|
if j > 0 then begin
|
||||||
|
s:=Trim(Copy(s, j + 1, MaxInt));
|
||||||
|
s:=ExcludeTrailingPathDelimiter(s);
|
||||||
|
if (Copy(s, Length(s) - 3, 4) = DirectorySeparator + 'rtl') and DirectoryExists(s) then begin
|
||||||
|
AddSearchPath(ExtractFilePath(s) + '*');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
sl.Free;
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
// Ignore exceptions
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user