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