mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-23 07:39:59 +02:00
IDE: Synchronize custom compiler options and all compiler options. Partially working.
git-svn-id: trunk@42176 -
This commit is contained in:
parent
5d273402b3
commit
30837a8e7d
@ -70,7 +70,6 @@ object frmAllCompilerOptions: TfrmAllCompilerOptions
|
||||
CancelButton.Name = 'CancelButton'
|
||||
CancelButton.DefaultCaption = True
|
||||
TabOrder = 2
|
||||
OnClick = ButtonPanel1Click
|
||||
ShowButtons = [pbOK, pbCancel, pbHelp]
|
||||
end
|
||||
object cbShowModified: TCheckBox
|
||||
|
@ -21,11 +21,10 @@ type
|
||||
edOptionsFilter: TEdit;
|
||||
sbAllOptions: TScrollBox;
|
||||
procedure btnResetOptionsFilterClick(Sender: TObject);
|
||||
procedure ButtonPanel1Click(Sender: TObject);
|
||||
procedure edOptionsFilterChange(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
private
|
||||
fCustomOptions: TMemo;
|
||||
FCustomOptions: TStrings;
|
||||
FIdleConnected: Boolean;
|
||||
FOptionsReader: TCompilerOptReader;
|
||||
FGeneratedControls: TComponentList;
|
||||
@ -33,11 +32,14 @@ type
|
||||
procedure SetIdleConnected(AValue: Boolean);
|
||||
procedure OnIdle(Sender: TObject; var Done: Boolean);
|
||||
procedure RenderAndFilterOptions;
|
||||
private
|
||||
property IdleConnected: Boolean read FIdleConnected write SetIdleConnected;
|
||||
public
|
||||
constructor CreateWithMemo(aCustomOptions: TMemo);
|
||||
constructor Create(TheOwner: TComponent);
|
||||
destructor Destroy; override;
|
||||
public
|
||||
property IdleConnected: Boolean read FIdleConnected write SetIdleConnected;
|
||||
property CustomOptions: TStrings read FCustomOptions write FCustomOptions;
|
||||
property OptionsReader: TCompilerOptReader read FOptionsReader;
|
||||
end;
|
||||
|
||||
var
|
||||
@ -49,10 +51,9 @@ implementation
|
||||
|
||||
{ TfrmAllCompilerOptions }
|
||||
|
||||
constructor TfrmAllCompilerOptions.CreateWithMemo(aCustomOptions: TMemo);
|
||||
constructor TfrmAllCompilerOptions.Create(TheOwner: TComponent);
|
||||
begin
|
||||
inherited Create(Nil);
|
||||
fCustomOptions := aCustomOptions;
|
||||
inherited Create(TheOwner);
|
||||
FOptionsReader := TCompilerOptReader.Create;
|
||||
FGeneratedControls := TComponentList.Create;
|
||||
end;
|
||||
@ -80,13 +81,6 @@ begin
|
||||
//lblStatus.Caption := '';
|
||||
end;
|
||||
|
||||
procedure TfrmAllCompilerOptions.ButtonPanel1Click(Sender: TObject);
|
||||
begin
|
||||
// All Options
|
||||
//FOptionsReader.CopyNonDefaultOptions(CompOptions.AllOptions);
|
||||
|
||||
end;
|
||||
|
||||
procedure TfrmAllCompilerOptions.edOptionsFilterChange(Sender: TObject);
|
||||
begin
|
||||
btnResetOptionsFilter.Enabled := edOptionsFilter.Text<>'';
|
||||
@ -119,6 +113,7 @@ begin
|
||||
FOptionsReader.CompilerExecutable := EnvironmentOptions.CompilerFilename;
|
||||
if FOptionsReader.ReadAndParseOptions <> mrOK then
|
||||
ShowMessage(FOptionsReader.ErrorMsg);
|
||||
FOptionsReader.FromCustomOptions(FCustomOptions);
|
||||
RenderAndFilterOptions;
|
||||
edOptionsFilter.Enabled := True;
|
||||
finally
|
||||
@ -138,23 +133,14 @@ var
|
||||
yLoc: Integer;
|
||||
Container: TCustomControl;
|
||||
|
||||
function MakeHeaderLabel: TControl;
|
||||
begin
|
||||
Result := TLabel.Create(Nil); // Container
|
||||
Result.Parent := Container;
|
||||
Result.Top := yLoc;
|
||||
Result.Left := Opt.Indentation*4;
|
||||
Result.Caption := Opt.Option+#9#9+Opt.Description;
|
||||
FGeneratedControls.Add(Result);
|
||||
end;
|
||||
|
||||
function MakeOptionCntrl(aCntrlClass: TControlClass; aTopOffs: integer=0): TControl;
|
||||
function MakeOptionCntrl(aCntrlClass: TControlClass; aCaption: string;
|
||||
aTopOffs: integer=0): TControl;
|
||||
begin
|
||||
Result := aCntrlClass.Create(Nil);
|
||||
Result.Parent := Container;
|
||||
Result.Top := yLoc+aTopOffs;
|
||||
Result.Left := Opt.Indentation*4;
|
||||
Result.Caption := Opt.Option;
|
||||
Result.Caption := aCaption;
|
||||
FGeneratedControls.Add(Result);
|
||||
end;
|
||||
|
||||
@ -206,13 +192,15 @@ var
|
||||
begin
|
||||
for i := 0 to aParentGroup.CompilerOpts.Count-1 do begin
|
||||
Opt := TCompilerOpt(aParentGroup.CompilerOpts[i]);
|
||||
if not Opt.Visible then Continue; // Maybe filtered out
|
||||
if Opt.Ignored or not Opt.Visible then Continue; // Maybe filtered out
|
||||
case Opt.EditKind of
|
||||
oeNone: begin // Label
|
||||
Cntrl := MakeHeaderLabel;
|
||||
oeGroup, oeSet: begin // Label for group or set
|
||||
Cntrl := MakeOptionCntrl(TLabel, Opt.Option+Opt.Suffix+#9#9+Opt.Description);
|
||||
end;
|
||||
oeBoolean: begin // CheckBox
|
||||
Cntrl := MakeOptionCntrl(TCheckBox);
|
||||
Cntrl := MakeOptionCntrl(TCheckBox, Opt.Option);
|
||||
Assert((Opt.Value='') or (Opt.Value='True'), 'Wrong value in Boolean option '+Opt.Option);
|
||||
TCheckBox(Cntrl).Checked := Opt.Value<>'';
|
||||
if Length(Opt.Option) > 10 then
|
||||
NewLeft := LeftDescrBoolean + (Length(Opt.Option)-10)*8
|
||||
else
|
||||
@ -220,29 +208,34 @@ var
|
||||
MakeDescrLabel(Cntrl, NewLeft);
|
||||
end;
|
||||
oeSetElem: begin // Sub-item for set, CheckBox
|
||||
Cntrl := MakeOptionCntrl(TCheckBox);
|
||||
Cntrl := MakeOptionCntrl(TCheckBox, Opt.Option+Opt.Description);
|
||||
Assert((Opt.Value='') or (Opt.Value='True'), 'Wrong value in Boolean option '+Opt.Option);
|
||||
TCheckBox(Cntrl).Checked := Opt.Value<>'';
|
||||
end;
|
||||
oeNumber, oeText, oeSetNumber: begin // Edit
|
||||
Lbl := MakeOptionCntrl(TLabel, 3);
|
||||
Lbl := MakeOptionCntrl(TLabel, Opt.Option+Opt.Suffix, 3);
|
||||
Cntrl := MakeEditCntrl(Lbl, TEdit);
|
||||
TEdit(Cntrl).Text := Opt.Value;
|
||||
MakeDescrLabel(Cntrl, LeftDescrEdit);
|
||||
end;
|
||||
oeList: begin // ComboBox
|
||||
Lbl := MakeOptionCntrl(TLabel, 3);
|
||||
Lbl := MakeOptionCntrl(TLabel, Opt.Option+Opt.Suffix, 3);
|
||||
Cntrl := MakeEditCntrl(Lbl, TComboBox);
|
||||
cb := TComboBox(Cntrl);
|
||||
cb.Style := csDropDownList;
|
||||
// ToDo: Move this logic to parser data so values can be validated better.
|
||||
case Opt.Option of
|
||||
'-Ca<x>': AddChoices(cb, 'ABI targets:');
|
||||
'-Cf<x>': AddChoices(cb, 'FPU instruction sets:');
|
||||
'-Cp<x>': AddChoices(cb, 'CPU instruction sets:');
|
||||
'-Oo[NO]<x>': AddChoices(cb, 'Optimizations:');
|
||||
'-Op<x>': AddChoices(cb, 'CPU instruction sets:');
|
||||
'-OW<x>': AddChoices(cb, 'Whole Program Optimizations:');
|
||||
'-Ow<x>': AddChoices(cb, 'Whole Program Optimizations:');
|
||||
'-Ca': AddChoices(cb, 'ABI targets:');
|
||||
'-Cf': AddChoices(cb, 'FPU instruction sets:');
|
||||
'-Cp': AddChoices(cb, 'CPU instruction sets:');
|
||||
'-Oo[NO]': AddChoices(cb, 'Optimizations:');
|
||||
'-Op': AddChoices(cb, 'CPU instruction sets:');
|
||||
'-OW': AddChoices(cb, 'Whole Program Optimizations:');
|
||||
'-Ow': AddChoices(cb, 'Whole Program Optimizations:');
|
||||
else
|
||||
raise Exception.Create('AddChoices: Unknown option ' + Opt.Option);
|
||||
end;
|
||||
cb.Text := Opt.Value;
|
||||
MakeDescrLabel(Cntrl, LeftDescrEdit);
|
||||
end
|
||||
else
|
||||
|
292
ide/compiler.pp
292
ide/compiler.pp
@ -97,7 +97,8 @@ type
|
||||
// Following classes are for compiler options parsed from "fpc -h" and "fpc -i".
|
||||
|
||||
TCompilerOptEditKind = (
|
||||
oeNone, // Only show the option header
|
||||
oeGroup, // A header for a group
|
||||
oeSet, // A header for a set
|
||||
oeBoolean, // Typically use CheckBox
|
||||
oeSetElem, // One char element of a set, use CheckBox
|
||||
oeSetNumber, // Number element of a set, use Edit
|
||||
@ -113,23 +114,28 @@ type
|
||||
TCompilerOpt = class
|
||||
private
|
||||
fOption: string; // Option without the leading '-'
|
||||
fSuffix: string; // <x> or similar suffix of option.
|
||||
fValue: string; // Data entered by user, 'True' for Boolean.
|
||||
fEditKind: TCompilerOptEditKind;
|
||||
fDescription: string;
|
||||
fIndentation: integer; // Indentation level in "fpc -h" output.
|
||||
fOwnerGroup: TCompilerOptGroup;
|
||||
fVisible: Boolean; // Used for filtering.
|
||||
procedure ParseOption(aDescr: string; aIndent: integer);
|
||||
fIgnored: Boolean; // Pretend this option does not exist.
|
||||
protected
|
||||
function GuessEditKind: TCompilerOptEditKind; virtual;
|
||||
procedure ParseOption(aDescr: string; aIndent: integer); virtual;
|
||||
public
|
||||
constructor Create(aOwnerGroup: TCompilerOptGroup);
|
||||
destructor Destroy; override;
|
||||
public
|
||||
property Option: string read fOption;
|
||||
property Suffix: string read fSuffix;
|
||||
property Value: string read fValue write fValue;
|
||||
property EditKind: TCompilerOptEditKind read fEditKind;
|
||||
property Description: string read fDescription;
|
||||
property Indentation: integer read fIndentation;
|
||||
property Visible: Boolean read fVisible write fVisible;
|
||||
property Ignored: Boolean read fIgnored write fIgnored;
|
||||
end;
|
||||
|
||||
TCompilerOptList = TObjectList;
|
||||
@ -142,10 +148,12 @@ type
|
||||
// List of options belonging to this group.
|
||||
fCompilerOpts: TCompilerOptList;
|
||||
protected
|
||||
function GuessEditKind: TCompilerOptEditKind; override;
|
||||
procedure ParseOption(aDescr: string; aIndent: integer); override;
|
||||
public
|
||||
constructor Create(aOwnerGroup: TCompilerOptGroup);
|
||||
destructor Destroy; override;
|
||||
function FindOption(aOptStr: string): TCompilerOpt;
|
||||
function SelectOption(aOptAndValue: string): Boolean;
|
||||
public
|
||||
property CompilerOpts: TCompilerOptList read fCompilerOpts;
|
||||
end;
|
||||
@ -155,12 +163,15 @@ type
|
||||
// A set of options. A combination of chars or numbers following the option char.
|
||||
TCompilerOptSet = class(TCompilerOptGroup)
|
||||
private
|
||||
fHasNumber: Boolean;
|
||||
protected
|
||||
procedure AddOptions(aDescr: string; aIndent: integer);
|
||||
function GuessEditKind: TCompilerOptEditKind; override;
|
||||
procedure ParseOption(aDescr: string; aIndent: integer); override;
|
||||
public
|
||||
constructor Create(aOwnerGroup: TCompilerOptGroup);
|
||||
destructor Destroy; override;
|
||||
function CollectSelectedOptions: string;
|
||||
procedure SelectOptions(aOptStr: string);
|
||||
end;
|
||||
|
||||
{ TCompilerOptReader }
|
||||
@ -183,7 +194,8 @@ type
|
||||
destructor Destroy; override;
|
||||
function ReadAndParseOptions: TModalResult;
|
||||
function FilterOptions(aFilter: string): Boolean;
|
||||
function CopyNonDefaultOptions(aStrings: TStrings): integer;
|
||||
function FromCustomOptions(aStrings: TStrings): TModalResult;
|
||||
function ToCustomOptions(aStrings: TStrings): TModalResult;
|
||||
public
|
||||
property SupportedCategories: TStringList read fSupportedCategories;
|
||||
property RootOptGroup: TCompilerOptGroup read fRootOptGroup;
|
||||
@ -378,9 +390,27 @@ begin
|
||||
Inc(Result);
|
||||
end;
|
||||
|
||||
function IgnoredOption(aOpt: string): Boolean;
|
||||
begin
|
||||
Result := aOpt = '-F'; // Ignore all file names and paths
|
||||
end;
|
||||
|
||||
|
||||
{ TCompilerOpt }
|
||||
|
||||
constructor TCompilerOpt.Create(aOwnerGroup: TCompilerOptGroup);
|
||||
begin
|
||||
inherited Create;
|
||||
fOwnerGroup := aOwnerGroup;
|
||||
if Assigned(aOwnerGroup) then
|
||||
aOwnerGroup.fCompilerOpts.Add(Self);
|
||||
end;
|
||||
|
||||
destructor TCompilerOpt.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TCompilerOpt.ParseOption(aDescr: string; aIndent: integer);
|
||||
var
|
||||
i, Start: Integer;
|
||||
@ -397,38 +427,23 @@ begin
|
||||
while (i < Length(aDescr)) and (aDescr[i] = ' ') do
|
||||
Inc(i);
|
||||
fDescription := Copy(aDescr, i, Length(aDescr));
|
||||
fEditKind := GuessEditKind;
|
||||
end;
|
||||
|
||||
function TCompilerOpt.GuessEditKind: TCompilerOptEditKind;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
// Guess whether this option can be edited and what is the EditKind
|
||||
Result := oeBoolean; // Default kind
|
||||
if Pos('fpc -i', fDescription) > 0 then
|
||||
Result := oeList // Values will be got later.
|
||||
else begin
|
||||
i := Length(fOption);
|
||||
if (i > 2) and (fOption[i-2] = '<') and (fOption[i] = '>') then
|
||||
case fOption[i-1] of
|
||||
'x': Result:=oeText; // <x>
|
||||
'n': Result:=oeNumber; // <n>
|
||||
end;
|
||||
fEditKind := oeBoolean; // Default kind
|
||||
i := Length(fOption);
|
||||
if (i > 3) and (fOption[i-2] = '<') and (fOption[i] = '>') then
|
||||
begin
|
||||
case fOption[i-1] of
|
||||
'x': fEditKind:=oeText; // <x>
|
||||
'n': fEditKind:=oeNumber; // <n>
|
||||
end;
|
||||
// Move <x> in the end to Suffix. We need the pure option later.
|
||||
fSuffix := Copy(fOption, i-2, i);
|
||||
fOption := Copy(fOption, 1, i-3);
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TCompilerOpt.Create(aOwnerGroup: TCompilerOptGroup);
|
||||
begin
|
||||
inherited Create;
|
||||
fOwnerGroup := aOwnerGroup;
|
||||
if Assigned(aOwnerGroup) then
|
||||
aOwnerGroup.fCompilerOpts.Add(Self);
|
||||
end;
|
||||
|
||||
destructor TCompilerOpt.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
if Pos('fpc -i', fDescription) > 0 then
|
||||
fEditKind := oeList; // Values will be got later.
|
||||
if fOwnerGroup.fIgnored or IgnoredOption(fOption) then
|
||||
fIgnored := True;
|
||||
end;
|
||||
|
||||
{ TCompilerOptGroup }
|
||||
@ -445,11 +460,74 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TCompilerOptGroup.GuessEditKind: TCompilerOptEditKind;
|
||||
function TCompilerOptGroup.FindOption(aOptStr: string): TCompilerOpt;
|
||||
|
||||
function FindOptionSub(aRoot: TCompilerOpt): TCompilerOpt;
|
||||
var
|
||||
Children: TCompilerOptList;
|
||||
i: Integer;
|
||||
begin
|
||||
Result := Nil;
|
||||
if aRoot is TCompilerOptGroup then
|
||||
begin
|
||||
Children := TCompilerOptGroup(aRoot).CompilerOpts;
|
||||
if aRoot is TCompilerOptSet then
|
||||
begin // TCompilerOptSet
|
||||
if AnsiStartsStr(aRoot.Option, aOptStr) then
|
||||
begin
|
||||
with TCompilerOptSet(aRoot) do
|
||||
SelectOptions(Copy(aOptStr, Length(aRoot.Option)+1, Length(aOptStr)));
|
||||
Result := aRoot;
|
||||
end;
|
||||
end
|
||||
else begin // TCompilerOptGroup
|
||||
for i := 0 to Children.Count-1 do // Recursive call for children.
|
||||
begin
|
||||
Result := FindOptionSub(TCompilerOpt(Children[i]));
|
||||
if Assigned(Result) then Break;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else begin // TCompilerOpt
|
||||
if aRoot.Option = aOptStr then
|
||||
Result := aRoot;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=inherited GuessEditKind;
|
||||
if Result = oeBoolean then
|
||||
Result := oeNone;
|
||||
Result := FindOptionSub(Self);
|
||||
end;
|
||||
|
||||
function TCompilerOptGroup.SelectOption(aOptAndValue: string): Boolean;
|
||||
var
|
||||
Opt: TCompilerOpt;
|
||||
OptStr, Param: string;
|
||||
OptLen: integer;
|
||||
begin
|
||||
Opt := FindOption(aOptAndValue);
|
||||
if Assigned(Opt) then
|
||||
Opt.Value := 'True'
|
||||
else begin
|
||||
// Option was not found, try separating the parameter.
|
||||
// ToDo: figure out the length in a more clever way.
|
||||
if AnsiStartsStr('-d', aOptAndValue)
|
||||
or AnsiStartsStr('-u', aOptAndValue) then
|
||||
OptLen := 2
|
||||
else
|
||||
OptLen := 3;
|
||||
OptStr := Copy(aOptAndValue, 1, OptLen);
|
||||
Param := Copy(aOptAndValue, OptLen+1, Length(aOptAndValue));
|
||||
Opt := FindOption(OptStr);
|
||||
if Assigned(Opt) then
|
||||
Opt.Value := Param;
|
||||
end;
|
||||
Result := Assigned(Opt);
|
||||
end;
|
||||
|
||||
procedure TCompilerOptGroup.ParseOption(aDescr: string; aIndent: integer);
|
||||
begin
|
||||
inherited ParseOption(aDescr, aIndent);
|
||||
fEditKind := oeGroup;
|
||||
end;
|
||||
|
||||
{ TCompilerOptSet }
|
||||
@ -464,6 +542,47 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TCompilerOptSet.CollectSelectedOptions: string;
|
||||
// Collect subitems of a set to one option.
|
||||
var
|
||||
Opt: TCompilerOpt;
|
||||
i: Integer;
|
||||
s: string;
|
||||
begin
|
||||
Result := '';
|
||||
s := '';
|
||||
for i := 0 to fCompilerOpts.Count-1 do
|
||||
begin
|
||||
Opt := TCompilerOpt(fCompilerOpts[i]);
|
||||
if Opt.Value <> '' then
|
||||
s := s + Opt.Option;
|
||||
end;
|
||||
if s <> '' then
|
||||
Result := Option + s;
|
||||
end;
|
||||
|
||||
procedure TCompilerOptSet.SelectOptions(aOptStr: string);
|
||||
// Select options in this set based on the given characters.
|
||||
var
|
||||
i, j: Integer;
|
||||
OptChar: string;
|
||||
Opt: TCompilerOpt;
|
||||
begin
|
||||
for i := 1 to Length(aOptStr) do
|
||||
begin
|
||||
OptChar := aOptStr[i];
|
||||
for j := 0 to fCompilerOpts.Count-1 do
|
||||
begin
|
||||
Opt := TCompilerOpt(fCompilerOpts[j]);
|
||||
if Opt.Option = OptChar then
|
||||
begin
|
||||
Opt.Value := 'True';
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCompilerOptSet.AddOptions(aDescr: string; aIndent: integer);
|
||||
// Set can have one letter options and <n> for numbers
|
||||
|
||||
@ -476,6 +595,7 @@ procedure TCompilerOptSet.AddOptions(aDescr: string; aIndent: integer);
|
||||
OptSet.fOption := 'Number';
|
||||
OptSet.fDescription := aDescr;
|
||||
OptSet.fEditKind := oeSetNumber;
|
||||
fHasNumber := True;
|
||||
end;
|
||||
|
||||
procedure NewSetElem(aDescr: string);
|
||||
@ -484,7 +604,8 @@ procedure TCompilerOptSet.AddOptions(aDescr: string; aIndent: integer);
|
||||
begin
|
||||
OptSet := TCompilerOpt.Create(Self); // Add it under a group
|
||||
OptSet.fIndentation := aIndent;
|
||||
OptSet.fOption := aDescr;
|
||||
OptSet.fOption := aDescr[1];
|
||||
OptSet.fDescription := Copy(aDescr, 2, Length(aDescr));
|
||||
OptSet.fEditKind := oeSetElem;
|
||||
end;
|
||||
|
||||
@ -497,7 +618,8 @@ begin
|
||||
NewSetNumber(Opt1)
|
||||
else begin
|
||||
i := PosEx(':', Opt1, 4);
|
||||
if (i > 0) and (Opt1[i-1]=' ') and (Opt1[i-2]<>' ') and (Opt1[i-3]=' ') then begin
|
||||
if (i > 0) and (Opt1[i-1]=' ') and (Opt1[i-2]<>' ') and (Opt1[i-3]=' ') then
|
||||
begin
|
||||
// Found another option on the same line, like ' a :'
|
||||
Opt2 := Copy(Opt1, i-2, Length(Opt1));
|
||||
if Opt1[3] = ':' then
|
||||
@ -512,9 +634,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCompilerOptSet.GuessEditKind: TCompilerOptEditKind;
|
||||
procedure TCompilerOptSet.ParseOption(aDescr: string; aIndent: integer);
|
||||
begin
|
||||
Result := oeNone;
|
||||
inherited ParseOption(aDescr, aIndent);
|
||||
fEditKind := oeSet;
|
||||
end;
|
||||
|
||||
|
||||
@ -554,7 +677,8 @@ var
|
||||
ReadBytes: integer;
|
||||
begin
|
||||
Result := false;
|
||||
while proc.Output.NumBytesAvailable>0 do begin
|
||||
while proc.Output.NumBytesAvailable>0 do
|
||||
begin
|
||||
ReadBytes := proc.Output.Read(Buffer{%H-}, BufSize);
|
||||
OutStream.Write(Buffer, ReadBytes);
|
||||
Result := true;
|
||||
@ -581,13 +705,13 @@ begin
|
||||
proc.ShowWindow := swoShowNormal;
|
||||
//proc.CurrentDirectory := WorkingDir;
|
||||
proc.Execute;
|
||||
while proc.Running do begin
|
||||
while proc.Running do
|
||||
if not ReadOutput then
|
||||
Sleep(100);
|
||||
end;
|
||||
ReadOutput;
|
||||
Result := proc.ExitStatus;
|
||||
if Result<>0 then begin
|
||||
if Result<>0 then
|
||||
begin
|
||||
fErrorMsg := Format('fpc %s failed: Result %d' + LineEnding + '%s',
|
||||
[aParam, Result, GetOutput]);
|
||||
Result := mrCancel;
|
||||
@ -613,10 +737,12 @@ var
|
||||
begin
|
||||
Result := mrOK;
|
||||
Category := Nil;
|
||||
for i := 0 to aLines.Count-1 do begin
|
||||
for i := 0 to aLines.Count-1 do
|
||||
begin
|
||||
Line := aLines[i];
|
||||
TrimmedLine := Trim(Line);
|
||||
if Assigned(Category) then begin
|
||||
if Assigned(Category) then
|
||||
begin
|
||||
if TrimmedLine = '' then
|
||||
Category := Nil // End of category.
|
||||
else begin
|
||||
@ -625,7 +751,8 @@ begin
|
||||
Category.Add(Trim(Line));
|
||||
end;
|
||||
end
|
||||
else if AnsiStartsStr(Supported, Line) then begin
|
||||
else if AnsiStartsStr(Supported, Line) then
|
||||
begin
|
||||
Category := TStringList.Create;
|
||||
Category.Add(''); // First an empty string. Allows removing selection.
|
||||
s := Copy(Line, Length(Supported)+1, Length(Line));
|
||||
@ -641,13 +768,13 @@ const
|
||||
var
|
||||
i, Start: Integer;
|
||||
begin
|
||||
if AnsiStartsStr(VersBegin, s) then begin
|
||||
if AnsiStartsStr(VersBegin, s) then
|
||||
begin
|
||||
Start := Length(VersBegin);
|
||||
i := PosEx(' ', s, Start+1);
|
||||
if i > 0 then begin
|
||||
if i > 0 then
|
||||
fCompilerVersion := Copy(s, Start, i-Start);
|
||||
// ToDo: the rest 2 fields are date and target CPU.
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -662,12 +789,13 @@ var
|
||||
begin
|
||||
Result := mrOK;
|
||||
LastGroup := fRootOptGroup;
|
||||
for i := 0 to aLines.Count-1 do begin
|
||||
for i := 0 to aLines.Count-1 do
|
||||
begin
|
||||
ThisLine := StringReplace(aLines[i],'-Agas-darwinAssemble','-Agas-darwin Assemble',[]);
|
||||
ThisInd := CalcIndentation(ThisLine);
|
||||
if ThisInd = 0 then begin
|
||||
// Top header lines for compiler version etc.
|
||||
ReadVersion(ThisLine);
|
||||
if ThisInd = 0 then
|
||||
begin
|
||||
ReadVersion(ThisLine); // Top header lines for compiler version etc.
|
||||
Continue;
|
||||
end;
|
||||
if (Trim(ThisLine) = '') or (ThisInd > 30)
|
||||
@ -682,7 +810,8 @@ begin
|
||||
NextLine := '';
|
||||
NextInd := -1;
|
||||
end;
|
||||
if NextInd > ThisInd then begin
|
||||
if NextInd > ThisInd then
|
||||
begin
|
||||
if (LastGroup is TCompilerOptSet)
|
||||
and ((Pos(' v : ', NextLine) > 0) or (NextInd > 30)) then
|
||||
// A hack to deal with split lined in the help output.
|
||||
@ -695,7 +824,8 @@ begin
|
||||
LastGroup.ParseOption(ThisLine, ThisInd);
|
||||
end;
|
||||
end;
|
||||
if NextInd <= ThisInd then begin
|
||||
if NextInd <= ThisInd then
|
||||
begin
|
||||
// This is an option
|
||||
if (LastGroup is TCompilerOptSet) then // Add it to a set (may add many)
|
||||
TCompilerOptSet(LastGroup).AddOptions(ThisLine, ThisInd)
|
||||
@ -762,10 +892,28 @@ begin
|
||||
Result := FilterOptionsSub(fRootOptGroup);
|
||||
end;
|
||||
|
||||
function TCompilerOptReader.CopyNonDefaultOptions(aStrings: TStrings): integer;
|
||||
function TCompilerOptReader.FromCustomOptions(aStrings: TStrings): TModalResult;
|
||||
var
|
||||
i, CommentPos: Integer;
|
||||
s: String;
|
||||
Opt: TCompilerOpt;
|
||||
begin
|
||||
Result := mrOK;
|
||||
for i := 0 to aStrings.Count-1 do
|
||||
begin
|
||||
s := Trim(aStrings[i]);
|
||||
if s = '' then Continue;
|
||||
CommentPos := Pos('//', s);
|
||||
if CommentPos > 0 then // Remove the possible comment.
|
||||
s := TrimRight(Copy(s, 1, CommentPos));
|
||||
fRootOptGroup.SelectOption(s);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCompilerOptReader.ToCustomOptions(aStrings: TStrings): TModalResult;
|
||||
// Copy options to a list if they have a non-default value (True for boolean).
|
||||
|
||||
function CopyOptionsSub(aRoot: TCompilerOpt): integer;
|
||||
function CopyOptions(aRoot: TCompilerOpt): integer;
|
||||
var
|
||||
Children: TCompilerOptList;
|
||||
i, Res: Integer;
|
||||
@ -776,24 +924,30 @@ function TCompilerOptReader.CopyNonDefaultOptions(aStrings: TStrings): integer;
|
||||
Children := TCompilerOptGroup(aRoot).CompilerOpts;
|
||||
if aRoot is TCompilerOptSet then
|
||||
begin // TCompilerOptSet
|
||||
s := '';
|
||||
for i := 0 to Children.Count-1 do // Collect subitems of a set to one option.
|
||||
s := s + TCompilerOpt(Children[i]).Option;
|
||||
aStrings.Add(s);
|
||||
s := TCompilerOptSet(aRoot).CollectSelectedOptions;
|
||||
if s <> '' then
|
||||
aStrings.Add(s);
|
||||
end
|
||||
else begin // TCompilerOptGroup
|
||||
for i := 0 to Children.Count-1 do // Recursive call for children.
|
||||
Res := CopyOptionsSub(TCompilerOpt(Children[i]));
|
||||
Res := CopyOptions(TCompilerOpt(Children[i]));
|
||||
end;
|
||||
end
|
||||
else begin // TCompilerOpt
|
||||
aStrings.Add(aRoot.Option);
|
||||
if aRoot.Value <> '' then
|
||||
begin
|
||||
if aRoot.Value = 'True' then
|
||||
aStrings.Add(aRoot.Option)
|
||||
else
|
||||
aStrings.Add(aRoot.Option + aRoot.Value);
|
||||
end;
|
||||
end;
|
||||
Result := Res;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result := CopyOptionsSub(fRootOptGroup);
|
||||
aStrings.Clear;
|
||||
Result := CopyOptions(fRootOptGroup);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -112,10 +112,14 @@ procedure TCompilerOtherOptionsFrame.btnAllOptionsClick(Sender: TObject);
|
||||
var
|
||||
AllOpts: TfrmAllCompilerOptions;
|
||||
begin
|
||||
AllOpts := TfrmAllCompilerOptions.CreateWithMemo(memoCustomOptions);
|
||||
AllOpts := TfrmAllCompilerOptions.Create(Nil);
|
||||
try
|
||||
AllOpts.CustomOptions := memoCustomOptions.Lines;
|
||||
if AllOpts.ShowModal = mrOK then
|
||||
;
|
||||
begin
|
||||
AllOpts.OptionsReader.ToCustomOptions(memoCustomOptions.Lines);
|
||||
memoCustomOptions.Invalidate;
|
||||
end;
|
||||
finally
|
||||
AllOpts.Free;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user