You've already forked lazarus-ccr
cmdlinecfg: the initial files commit
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2802 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
318
components/cmdlinecfg/trunk/cmdlinecfg.pas
Normal file
318
components/cmdlinecfg/trunk/cmdlinecfg.pas
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
unit cmdlinecfg;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, contnrs;
|
||||||
|
|
||||||
|
type
|
||||||
|
TCmdLineCfgValues = record
|
||||||
|
CmdLineValue : String; // the actual command that goes to the cmd line
|
||||||
|
DisplayName : String; // the default display name (in English)
|
||||||
|
Condition : String; // condition for the value of the option
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineCfgOption }
|
||||||
|
|
||||||
|
TCmdLineCfgOption = class(TObject)
|
||||||
|
private
|
||||||
|
procedure AssureSizeForIndex(AIndex: Integer);
|
||||||
|
public
|
||||||
|
Section : String; // the secion of the option
|
||||||
|
SubSection : String; // logical sub-section of the option
|
||||||
|
Name : String; // the "code" of the option, to be saved into project settings (to be backward compatible)
|
||||||
|
OptType : String; // option type - free form type option options
|
||||||
|
Key : String; // the key that needs to go
|
||||||
|
MasterKey : String; // the key values will be combined into a single Key, prefixed with the MasterKey
|
||||||
|
// example: two options -Ct -Co will be combined into -Cto, if both have -C as master key.
|
||||||
|
AliasToKey : string; // the key is deprecated and it's alias to a newer and better key
|
||||||
|
Display : String; // the default description of the option
|
||||||
|
Condition : String; // the condition for the option (in general)
|
||||||
|
Values : array of TCmdLineCfgValues; // cmd line value used with the key
|
||||||
|
ValCount : Integer; // the total number of values
|
||||||
|
isMultiple : Boolean;
|
||||||
|
constructor Create;
|
||||||
|
procedure SetValue(const AValue: string; Index: Integer = 0);
|
||||||
|
procedure SetValDisplay(const DispName: string; Index: Integer = 0);
|
||||||
|
procedure SetCondition(const Condition: string; Index: Integer = 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineCfg }
|
||||||
|
|
||||||
|
TCmdLineCfg = class(TObject)
|
||||||
|
private
|
||||||
|
fHash : TFPHashObjectList;
|
||||||
|
isValid : Boolean;
|
||||||
|
public
|
||||||
|
Options : TList;
|
||||||
|
Executable : String; // the executable code. Doesn't have to be the actual command-line executable name
|
||||||
|
Version : String; // human-readable version name
|
||||||
|
FromVersion : String; // the previous version of configuration
|
||||||
|
TestKey : String; // the command that should return the TestValue
|
||||||
|
TestValue : String; // expected test value to confirm the version.
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
function FindOption(const name: string): TCmdLineCfgOption;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineOptionValue }
|
||||||
|
|
||||||
|
TCmdLineOptionValue = class(TObject)
|
||||||
|
Option : TCmdLineCfgOption;
|
||||||
|
Value : String;
|
||||||
|
constructor Create(AOption: TCmdLineCfgOption=nil; const AValue: string = '');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CmdLineDebug(cfg: TCmdLineCfg);
|
||||||
|
procedure CmdLineDebugOption(opt: TCmdLineCfgOption);
|
||||||
|
function CmdLineMakeOptions(values: TList {of TCmdLineOptionValue}): string;
|
||||||
|
|
||||||
|
// returns the substring for thr command-line, by replacing %value% from the "Key" param
|
||||||
|
// is ValueType is switch, simply returns the key, if Value is not an empty string
|
||||||
|
// Example #1
|
||||||
|
// Key = -Ck%value%
|
||||||
|
// ValueType = int
|
||||||
|
// Value = 5000
|
||||||
|
// Result = -Ck5000
|
||||||
|
// Example #2
|
||||||
|
// Key = -Fu%value%
|
||||||
|
// ValueType = filename
|
||||||
|
// Value = /usr/bin/my files/test.pas
|
||||||
|
// Result = -Fu"/usr/bin/my files/test.pas"
|
||||||
|
function CmdLineCollectValue(const Key, ValueType, Value: string): string;
|
||||||
|
|
||||||
|
function CmdLineGenerateName(const Key,Name: String): String;
|
||||||
|
// Automatically sets the name based by CmdLineGenerateName
|
||||||
|
// Empty type is not allow, so defaults to "switch"
|
||||||
|
// Chagnes type from "switch" to either "string" ot "select"
|
||||||
|
// if the Key has a value (string), or there's a list of options given (select)
|
||||||
|
procedure CmdLineOptionNormalize(opt: TCmdLineCfgOption);
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure CmdLineOptionNormalize(opt: TCmdLineCfgOption);
|
||||||
|
var
|
||||||
|
tp: string;
|
||||||
|
begin
|
||||||
|
if not Assigned(opt) then Exit;
|
||||||
|
opt.Name:=CmdLineGenerateName(opt.Key, opt.Name);
|
||||||
|
if opt.OptType='' then opt.OptType:='switch';
|
||||||
|
tp:=AnsiLowerCase(opt.OptType);
|
||||||
|
if (pos('%value%', AnsiLowercase(opt.Key))>0) and (tp='switch')then begin
|
||||||
|
if opt.ValCount>1 then opt.OptType:='select'
|
||||||
|
else opt.OptType:='string';
|
||||||
|
end;;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CmdLineGenerateName(const Key,Name: String): String;
|
||||||
|
begin
|
||||||
|
Result:=Name;
|
||||||
|
if Name='' then Result:=StringReplace(Key, '%value%', '', [rfIgnoreCase,rfReplaceAll]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineOptionValue }
|
||||||
|
|
||||||
|
constructor TCmdLineOptionValue.Create(AOption: TCmdLineCfgOption;
|
||||||
|
const AValue: string);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
Option:=AOption;
|
||||||
|
Value:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TCmdLineCfgOption }
|
||||||
|
|
||||||
|
procedure TCmdLineCfgOption.AssureSizeForIndex(AIndex: Integer);
|
||||||
|
begin
|
||||||
|
while length(Values)<=AIndex do begin
|
||||||
|
if length(Values)=0 then SetLength(Values, 4)
|
||||||
|
else SetLength(Values, length(Values)*2);
|
||||||
|
end;
|
||||||
|
if ValCount<=AIndex then ValCount:=AIndex+1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TCmdLineCfgOption.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineCfgOption.SetValue(const AValue: string; Index: Integer);
|
||||||
|
begin
|
||||||
|
AssureSizeForIndex(Index);
|
||||||
|
Values[Index].CmdLineValue:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineCfgOption.SetValDisplay(const DispName: string; Index: Integer);
|
||||||
|
begin
|
||||||
|
AssureSizeForIndex(Index);
|
||||||
|
Values[Index].DisplayName:=DispName;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineCfgOption.SetCondition(const Condition: string; Index: Integer
|
||||||
|
);
|
||||||
|
begin
|
||||||
|
AssureSizeForIndex(Index);
|
||||||
|
Values[Index].Condition:=Condition;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineCfg }
|
||||||
|
|
||||||
|
constructor TCmdLineCfg.Create;
|
||||||
|
begin
|
||||||
|
Options:=TList.Create;
|
||||||
|
fHash:=TFPHashObjectList.Create(false);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TCmdLineCfg.Destroy;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
for i:=0 to Options.Count-1 do TCmdLineCfgOption(Options[i]).Free;
|
||||||
|
Options.Free;
|
||||||
|
fHash.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCmdLineCfg.FindOption(const name: string): TCmdLineCfgOption;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
l : string;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
begin
|
||||||
|
if not isValid then begin
|
||||||
|
for i:=0 to Options.Count-1 do begin
|
||||||
|
opt := TCmdLineCfgOPtion(Options[i]);
|
||||||
|
fHash.Add( opt.Name, opt);
|
||||||
|
end;
|
||||||
|
isValid:=true;
|
||||||
|
end;
|
||||||
|
Result:=TCmdLineCfgOption(fHash.Find(name));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CmdLineDebugOption(opt: TCmdLineCfgOption);
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
if (opt.Section<>'') or (opt.SubSection<>'') then
|
||||||
|
writeln(opt.Name, ' [', opt.Section,'/',opt.SubSection,']');
|
||||||
|
writeln('key: ', opt.key,' (',opt.Display,')');
|
||||||
|
writeln('type: ', opt.OptType);
|
||||||
|
if opt.isMultiple then writeln('multiple values allowed');
|
||||||
|
if opt.MasterKey<>'' then writeln('masterkey: ', opt.MasterKey);
|
||||||
|
for i:=0 to opt.ValCount-1 do begin
|
||||||
|
writeln(' value: ', opt.Values[i].CmdLineValue,' ', opt.Values[i].DisplayName );
|
||||||
|
if opt.Values[i].Condition<>'' then
|
||||||
|
writeln(' condition: ', opt.Values[i].Condition);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CmdLineDebug(cfg: TCmdLineCfg);
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
writeln('executable: ', cfg.Executable);
|
||||||
|
writeln('version: ', cfg.Version);
|
||||||
|
writeln('test key: ', cfg.TestKey);
|
||||||
|
writeln('test value: ', cfg.TestValue);
|
||||||
|
writeln('total options: ', cfg.Options.Count);
|
||||||
|
writeln;
|
||||||
|
for i:=0 to cfg.Options.Count-1 do begin
|
||||||
|
CmdLineDebugOption(TCmdLineCfgOption(cfg.Options[i]));
|
||||||
|
writeln;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CheckQuotes(const v: string): string;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
Result:=v;
|
||||||
|
for i:=1 to length(v) do
|
||||||
|
if (v[i] in [' ','<','>',#39]) then begin
|
||||||
|
//todo: how to handle quotes in parameter value?
|
||||||
|
Result:='"'+v+'"';
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CmdLineCollectValue(const Key, ValueType, Value: string): string;
|
||||||
|
var
|
||||||
|
l : string;
|
||||||
|
j : Integer;
|
||||||
|
vl : string;
|
||||||
|
const
|
||||||
|
ValueParam = '%value%';
|
||||||
|
begin
|
||||||
|
if Value='' then begin
|
||||||
|
Result:='';
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
l:=LowerCase(ValueType);
|
||||||
|
if l='switch' then begin
|
||||||
|
Result:=Key // no values expected
|
||||||
|
end else begin
|
||||||
|
vl:=CheckQuotes(Value);
|
||||||
|
Result:=Key;
|
||||||
|
j:=Pos(ValueParam, LowerCase(Result));
|
||||||
|
if j>0 then begin
|
||||||
|
//%value% is present in key declaration
|
||||||
|
Delete(Result, j, length(ValueParam));
|
||||||
|
// replacing any %% with %
|
||||||
|
Result:=StringReplace(Result, '%%', '%', [rfIgnoreCase, rfReplaceAll]);
|
||||||
|
Insert(vl, Result, j);
|
||||||
|
end else
|
||||||
|
//%value% is not present in key declaration, so just attach it to the key
|
||||||
|
Result:=Key+StringReplace(Key, '%%', '%', [rfIgnoreCase, rfReplaceAll])+vl;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CmdLineMakeOptions(values: TList {of TCmdLineOption}): string;
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
j : Integer;
|
||||||
|
masters : TStringList;
|
||||||
|
vl : TCmdLineOptionValue;
|
||||||
|
v : string;
|
||||||
|
mk : string;
|
||||||
|
begin
|
||||||
|
Result:='';
|
||||||
|
masters := TStringList.Create;
|
||||||
|
try
|
||||||
|
for i:=0 to values.Count-1 do begin
|
||||||
|
vl:=TCmdLineOptionValue(values[i]);
|
||||||
|
if vl.Option = nil then Continue;
|
||||||
|
|
||||||
|
v:=CmdLineCollectValue(vl.Option.Key, vl.Option.OptType, vl.Value);
|
||||||
|
if v='' then Continue;
|
||||||
|
|
||||||
|
mk:=vl.Option.MasterKey;
|
||||||
|
if mk<>'' then begin
|
||||||
|
j:=masters.IndexOfName(mk);
|
||||||
|
v:=Copy(v, length(mk)+1, length(v));
|
||||||
|
if j<0 then
|
||||||
|
masters.Values[mk]:=v
|
||||||
|
else
|
||||||
|
masters.ValueFromIndex[j]:=masters.ValueFromIndex[j]+v;
|
||||||
|
end else begin
|
||||||
|
if Result='' then Result:=v
|
||||||
|
else Result:=Result+' '+v;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
for i:=0 to masters.Count-1 do begin
|
||||||
|
v:=masters.Names[i]+masters.ValueFromIndex[i];
|
||||||
|
if Result='' then Result:=v
|
||||||
|
else Result:=Result+' '+v;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
masters.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
183
components/cmdlinecfg/trunk/cmdlinecfgjson.pas
Normal file
183
components/cmdlinecfg/trunk/cmdlinecfgjson.pas
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
unit cmdlinecfgjson;
|
||||||
|
|
||||||
|
{$mode delphi}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, cmdlinecfg, fpjson, jsonparser;
|
||||||
|
|
||||||
|
function CmdLineCfgJSONReadFile(stream: TStream; cfg: TCmdLineCfg): Boolean; overload;
|
||||||
|
function CmdLineCfgJSONReadFile(const FileName: String; cfg: TCmdLineCfg): Boolean; overload;
|
||||||
|
procedure CmdLineCfgJSONLoadFilesFromDir(const Dir: String; list: TList; const Mask : string = '*.copt');
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
// ugh... no better way to do it anyway. ... see TValueIterator below
|
||||||
|
type
|
||||||
|
{ TCfgIterator }
|
||||||
|
TCfgIterator = class(TObject)
|
||||||
|
class procedure Iterate(Const AName : TJSONStringType; Item: TJSONData; Data: TObject; var DoContinue: Boolean);
|
||||||
|
class procedure IterateOption(Const AName : TJSONStringType; Item: TJSONData; Data: TObject; var DoContinue: Boolean);
|
||||||
|
class procedure IterateValue(const AName: TJSONStringType; Item: TJSONdata; Data: TObject; var DoContinue: Boolean);
|
||||||
|
end;
|
||||||
|
|
||||||
|
type
|
||||||
|
TIterateValue = class(TObject)
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
idx : Integer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure TCfgIterator.IterateOption(Const AName : TJSONStringType; Item: TJSONData; Data: TObject; var DoContinue: Boolean);
|
||||||
|
var
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
nm : String;
|
||||||
|
ja : TJSONArray;
|
||||||
|
i : Integer;
|
||||||
|
iv : TIterateValue;
|
||||||
|
begin
|
||||||
|
opt:=TCmdLineCfgOption(Data);
|
||||||
|
nm:=lowerCase(AName);
|
||||||
|
if nm='section' then opt.Section:=Item.AsString
|
||||||
|
else if nm='subsection' then opt.SubSection:=Item.AsString
|
||||||
|
else if nm='type' then opt.OptType:=Item.AsString
|
||||||
|
else if nm='name' then opt.Name:=Item.AsString
|
||||||
|
else if nm='key' then opt.Key:=Item.AsString
|
||||||
|
else if nm='masterkey' then opt.MasterKey:=Item.AsString
|
||||||
|
else if nm='display' then opt.Display:=Item.AsString
|
||||||
|
else if (nm='condition') or (nm='cond') then opt.Condition:=Item.AsString
|
||||||
|
else if (nm='value') then opt.SetValue(Item.AsString)
|
||||||
|
else if (nm='alias') then opt.AliasToKey:=Item.AsString
|
||||||
|
else if (nm='multiple') then opt.isMultiple:=(Item.JSONType=jtBoolean) and (Item.AsBoolean)
|
||||||
|
else if (nm='options') then begin
|
||||||
|
ja:=TJSONArray(Item);
|
||||||
|
if ja.Count>0 then begin
|
||||||
|
iv:=TIterateValue.Create;
|
||||||
|
try
|
||||||
|
iv.opt:=opt;
|
||||||
|
for i:=0 to ja.Count-1 do begin
|
||||||
|
if ja.Items[i].JSONType = jtObject then begin
|
||||||
|
iv.idx:=opt.ValCount;
|
||||||
|
TJSONObject(ja.Items[i]).Iterate ( TCfgIterator.IterateValue, iv);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
iv.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure TCfgIterator.IterateValue(const AName: TJSONStringType;
|
||||||
|
Item: TJSONdata; Data: TObject; var DoContinue: Boolean);
|
||||||
|
var
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
idx : Integer;
|
||||||
|
nm : String;
|
||||||
|
begin
|
||||||
|
idx:=TIterateValue(Data).idx;
|
||||||
|
opt:=TIterateValue(Data).opt;
|
||||||
|
nm:=lowerCase(AName);
|
||||||
|
if nm='display' then opt.SetValDisplay(Item.AsString, idx)
|
||||||
|
else if nm='value' then opt.SetValue(Item.AsString, idx)
|
||||||
|
else if nm='condition' then opt.SetCondition(Item.AsString, idx);
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure TCfgIterator.Iterate(Const AName : TJSONStringType; Item: TJSONData; Data: TObject; var DoContinue: Boolean);
|
||||||
|
var
|
||||||
|
cfg : TCmdLineCfg;
|
||||||
|
nm : string;
|
||||||
|
ja : TJSONArray;
|
||||||
|
j : TJSONData;
|
||||||
|
i : Integer;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
|
||||||
|
begin
|
||||||
|
cfg:=TCmdLineCfg(data);
|
||||||
|
nm:=lowerCase(AName);
|
||||||
|
if nm='options' then begin
|
||||||
|
if Item.JSONType<>jtArray then Exit; // options must be an array of options
|
||||||
|
ja:=TJSONArray(Item);
|
||||||
|
for i:=0 to ja.Count-1 do begin
|
||||||
|
j:=ja.Items[i];
|
||||||
|
if j.JSONType<>jtObject then Continue;
|
||||||
|
|
||||||
|
opt:=TCmdLineCfgOption.Create;
|
||||||
|
TJSONObject(j).Iterate(TCfgIterator.IterateOption, opt);
|
||||||
|
if (opt.Key='') then begin
|
||||||
|
opt.Free
|
||||||
|
end else begin
|
||||||
|
CmdLineOptionNormalize(opt);
|
||||||
|
cfg.Options.Add(opt);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
if Item.JSONType<>jtString then Exit;
|
||||||
|
if nm='executable' then cfg.Executable:=Item.AsString
|
||||||
|
else if nm='version' then cfg.Version:=Item.AsString
|
||||||
|
else if nm='fromversion' then cfg.FromVersion:=Item.AsString
|
||||||
|
else if nm='testvalue' then cfg.TestValue:=Item.AsString
|
||||||
|
else if nm='testkey' then cfg.TestKey:=Item.AsString
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CmdLineCfgJSONReadFile(stream: TStream; cfg: TCmdLineCfg): Boolean;
|
||||||
|
var
|
||||||
|
p : TJSONParser;
|
||||||
|
d : TJSONData;
|
||||||
|
core : TJSONObject;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
d:=nil;
|
||||||
|
p:=TJSONParser.Create(stream);
|
||||||
|
try
|
||||||
|
d:=p.Parse;
|
||||||
|
if d.JSONType<>jtObject then Exit;
|
||||||
|
core:=TJSONObject(d);
|
||||||
|
core.Iterate(TCfgIterator.Iterate, cfg);
|
||||||
|
Result:=cfg.Executable<>'';
|
||||||
|
finally
|
||||||
|
d.Free;
|
||||||
|
p.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CmdLineCfgJSONReadFile(const FileName: String; cfg: TCmdLineCfg): Boolean;
|
||||||
|
var
|
||||||
|
fs : TFileStream;
|
||||||
|
begin
|
||||||
|
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
|
||||||
|
try
|
||||||
|
Result:=CmdLineCfgJSONReadFile(fs, cfg);
|
||||||
|
finally
|
||||||
|
fs.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CmdLineCfgJSONLoadFilesFromDir(const Dir: String; list: TList; const Mask: string);
|
||||||
|
var
|
||||||
|
rslt : TSearchRec;
|
||||||
|
res : Integer;
|
||||||
|
pth : string;
|
||||||
|
cfg : TCmdLineCfg;
|
||||||
|
begin
|
||||||
|
pth:=IncludeTrailingPathDelimiter(Dir);
|
||||||
|
res:=FindFirst( pth+Mask, faAnyFile, rslt);
|
||||||
|
try
|
||||||
|
while res = 0 do begin
|
||||||
|
if (rslt.Attr and faDirectory=0) and (rslt.Size>0) then begin
|
||||||
|
cfg := TCmdLineCfg.Create;
|
||||||
|
if not CmdLineCfgJSONReadFile(pth+rslt.Name, cfg) then cfg.Free
|
||||||
|
else list.Add(cfg);
|
||||||
|
end;
|
||||||
|
res:=FindNext(rslt);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FindClose(rslt);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
285
components/cmdlinecfg/trunk/cmdlinecfgparser.pas
Normal file
285
components/cmdlinecfg/trunk/cmdlinecfgparser.pas
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
unit cmdlinecfgparser;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$mode delphi}
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, cmdlinecfg, cmdlinecfgutils;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TCmdLineOptionParse }
|
||||||
|
|
||||||
|
TOptionParse = class(TObject)
|
||||||
|
key : string;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
isDelimited : Boolean; // the value comes with a white-space after the key
|
||||||
|
isParameter : Boolean;
|
||||||
|
constructor Create(aopt: TCmdLineCfgOption; const akey: string; AisDelim: Boolean; AisParam: Boolean);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineArgsParser }
|
||||||
|
|
||||||
|
TCmdLineArgsParser = class(TObject)
|
||||||
|
private
|
||||||
|
fKeyPrefix : TStrings;
|
||||||
|
fCfg : TCmdLineCfg;
|
||||||
|
fisValid : Boolean;
|
||||||
|
fMasters : TStringList;
|
||||||
|
MaxMasterLen : Integer;
|
||||||
|
MinMasterLen : Integer;
|
||||||
|
fOptions : TStringList;
|
||||||
|
MaxKeyLen : Integer;
|
||||||
|
MinKeyLen : Integer;
|
||||||
|
protected
|
||||||
|
procedure SetCfg(ACfg: TCmdLineCfg);
|
||||||
|
procedure PrepareConfig;
|
||||||
|
function FindMasterKey(const arg: string): string;
|
||||||
|
function FindParseOption(const arg: string): TOptionParse;
|
||||||
|
function CreateMasterKeyValues(const ArgValue, MasterKey: string; Vals: TList): Boolean;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
// if an argumant doesn't have a corresponding cmd line option;
|
||||||
|
// .Option field will be set to nil. The next "unkey" option will be set as a value;
|
||||||
|
// KeyPrefix - would be used to find values that are not part of arguments only;
|
||||||
|
// the method will create TCmdLineOptionValue objects and add them to values list
|
||||||
|
// it doesn't check for their existance, just adds them!
|
||||||
|
function Parse(Args: TStrings; Vals: TList {of TCmdLineOptionValue}): Boolean;
|
||||||
|
property CmdLineCfg: TCmdLineCfg read fCfg write SetCfg;
|
||||||
|
property KeyPrefix : TStrings read fKeyPrefix;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// note that KeyPrefix defaults to unix keys = "-". On Windows, many MS commandlines
|
||||||
|
// are using "/" as the key prefix
|
||||||
|
procedure CmdLineMatchArgsToOpts(CmdLineCfg: TCmdLineCfg; Args: TStrings; Vals: TList {of TCmdLineOptionValue}; const KeyPrefix: string = '-'); overload;
|
||||||
|
procedure CmdLineMatchArgsToOpts(CmdLineCfg: TCmdLineCfg; const CmdLine: string; Vals: TList {of TCmdLineOptionValue}; const KeyPrefix: string = '-'); overload;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure CmdLineMatchArgsToOpts(CmdLineCfg: TCmdLineCfg; Args: TStrings; Vals: TList;
|
||||||
|
const KeyPrefix: string);
|
||||||
|
var
|
||||||
|
parser : TCmdLineArgsParser;
|
||||||
|
begin
|
||||||
|
parser := TCmdLineArgsParser.Create;
|
||||||
|
try
|
||||||
|
parser.CmdLineCfg:=CmdLineCfg;
|
||||||
|
parser.KeyPrefix.Add(KeyPrefix);
|
||||||
|
parser.Parse(Args, Vals);
|
||||||
|
finally
|
||||||
|
parser.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CmdLineMatchArgsToOpts(CmdLineCfg: TCmdLineCfg; const CmdLine: string;
|
||||||
|
Vals: TList; const KeyPrefix: string);
|
||||||
|
var
|
||||||
|
args : TStringList;
|
||||||
|
begin
|
||||||
|
args:=TstringList.Create;
|
||||||
|
try
|
||||||
|
CmdLineParse(cmdLine, args);
|
||||||
|
CmdLineMatchArgsToOpts(cmdlinecfg, args, vals, KeyPrefix);
|
||||||
|
finally
|
||||||
|
args.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TOptionParse }
|
||||||
|
|
||||||
|
constructor TOptionParse.Create(aopt: TCmdLineCfgOption; const akey: string; AisDelim: Boolean; AisParam: Boolean);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
opt:=Aopt;
|
||||||
|
key:=akey;
|
||||||
|
isDelimited:=AisDelim;
|
||||||
|
isParameter:=AisParam;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineArgsParse }
|
||||||
|
|
||||||
|
procedure TCmdLineArgsParser.SetCfg(ACfg: TCmdLineCfg);
|
||||||
|
begin
|
||||||
|
if fCfg<>ACfg then begin
|
||||||
|
fisValid:=false;
|
||||||
|
fCfg:=ACfg;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure MaxMinOptionLen(options: TStrings; var minlen, maxlen: Integer);
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
j : Integer;
|
||||||
|
ln : Integer;
|
||||||
|
k : string;
|
||||||
|
begin
|
||||||
|
maxlen:=0;
|
||||||
|
minlen:=0;
|
||||||
|
if options.Count=0 then Exit;
|
||||||
|
|
||||||
|
for i:=0 to options.Count-1 do begin
|
||||||
|
ln:=length(options[i]);
|
||||||
|
if ln>maxlen then maxlen:=ln;
|
||||||
|
end;
|
||||||
|
|
||||||
|
j:=0;
|
||||||
|
repeat
|
||||||
|
inc(minlen);
|
||||||
|
k:=Copy(options[0],1,minlen);
|
||||||
|
for i:=0 to options.Count-1 do
|
||||||
|
if Pos(k, options[i])<>1 then begin
|
||||||
|
inc(j);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
until (j<>0) or (minlen>maxlen);
|
||||||
|
dec(minlen);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineArgsParser.PrepareConfig;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
ov : TCmdLineCfgOption;
|
||||||
|
k : string;
|
||||||
|
j : integer;
|
||||||
|
y : integer;
|
||||||
|
begin
|
||||||
|
if not Assigned(fCfg) then Exit;
|
||||||
|
fMasters.Clear;
|
||||||
|
fOptions.Clear;
|
||||||
|
fMasters.Duplicates:=dupIgnore;
|
||||||
|
for i:=0 to fCfg.Options.Count-1 do begin
|
||||||
|
ov:=TCmdLineCfgOption(fCfg.Options[i]);
|
||||||
|
if not Assigned(ov) then Continue;
|
||||||
|
k:=Trim(ov.Key);
|
||||||
|
if ov.MasterKey<>'' then fMasters.Add(ov.MasterKey);
|
||||||
|
// preparing keys for values with parameters, like -Cp%test% or -Cp %test%
|
||||||
|
j:=Pos('%', k);
|
||||||
|
y:=Pos(' ', k);
|
||||||
|
if (y>0) and ((y<j) or (j=0)) then k:=Copy(k, 1, y-1)
|
||||||
|
else if j>0 then k:=Copy(k, 1, j-1);
|
||||||
|
fOptions.AddObject(k, TOptionParse.Create(ov, k, y>0, j>0) );
|
||||||
|
end;
|
||||||
|
MaxMinOptionLen(fMasters, MinMasterLen, MaxMasterLen);
|
||||||
|
MaxMinOptionLen(fOptions, MinKeyLen, MaxKeyLen);
|
||||||
|
fOptions.Sort;
|
||||||
|
fisValid:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCmdLineArgsParser.FindMasterKey(const arg: string): string;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
t : string;
|
||||||
|
j : integer;
|
||||||
|
begin
|
||||||
|
for i:=MinMasterLen to MaxMasterLen do begin
|
||||||
|
t:=Copy(arg, 1, i);
|
||||||
|
j:=fMasters.IndexOf(t);
|
||||||
|
if j>=0 then begin
|
||||||
|
Result:=fMasters[j];
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:='';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCmdLineArgsParser.FindParseOption(const arg: string): TOptionParse;
|
||||||
|
var
|
||||||
|
k : string;
|
||||||
|
j : Integer;
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
for i:=MinKeyLen to MaxKeyLen do begin
|
||||||
|
k:=Copy(arg, 1, i);
|
||||||
|
j:=fOptions.IndexOf(k);
|
||||||
|
if j>=0 then begin
|
||||||
|
Result:=TOptionParse( fOptions.Objects[j] );
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCmdLineArgsParser.CreateMasterKeyValues(const ArgValue, MasterKey: string; Vals: TList): Boolean;
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
k : string;
|
||||||
|
j : Integer;
|
||||||
|
op : TOptionParse;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
for i:=length(MasterKey)+1 to length(ArgValue) do begin
|
||||||
|
k:=MasterKey + ArgValue[i];
|
||||||
|
j:=fOptions.IndexOf(k);
|
||||||
|
if j>=0 then begin
|
||||||
|
Result:=True;
|
||||||
|
op:=TOptionParse(fOptions.Objects[j]);
|
||||||
|
Vals.Add( TCmdLineOptionValue.Create ( op.opt, '1'))
|
||||||
|
end else begin
|
||||||
|
Vals.Add( TCmdLineOptionValue.Create ( nil, k));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TCmdLineArgsParser.Create;
|
||||||
|
begin
|
||||||
|
fKeyPrefix := TStringList.Create;
|
||||||
|
TStringList(fKeyPrefix).CaseSensitive:=true;
|
||||||
|
|
||||||
|
fMasters := TStringList.Create;
|
||||||
|
TStringList(fMasters).CaseSensitive:=true;
|
||||||
|
|
||||||
|
fOptions := TStringList.Create;
|
||||||
|
TStringList(fOptions).CaseSensitive:=true;
|
||||||
|
TStringList(fOptions).OwnsObjects:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TCmdLineArgsParser.Destroy;
|
||||||
|
begin
|
||||||
|
fMasters.Free;
|
||||||
|
fOptions.Clear;
|
||||||
|
fOptions.Free;
|
||||||
|
fKeyPrefix.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCmdLineArgsParser.Parse(Args: TStrings; Vals: TList): Boolean;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
v : string;
|
||||||
|
mk : string;
|
||||||
|
op : TOptionParse;
|
||||||
|
begin
|
||||||
|
Result:=Assigned(fCfg);
|
||||||
|
if not Result then Exit;
|
||||||
|
if not fisValid then PrepareConfig;
|
||||||
|
i:=0;
|
||||||
|
while i<Args.Count do begin
|
||||||
|
v:=Args[i];
|
||||||
|
mk:=FindMasterKey(v);
|
||||||
|
if mk<>'' then begin
|
||||||
|
// todo: test if there's any known value among keys!
|
||||||
|
CreateMasterKeyValues(v, mk, Vals);
|
||||||
|
end else begin
|
||||||
|
op:=FindParseOption(v);
|
||||||
|
if not Assigned(op) then
|
||||||
|
Vals.Add ( TCmdLineOptionValue.Create(nil, v))
|
||||||
|
else begin
|
||||||
|
if op.isParameter then begin
|
||||||
|
if op.isDelimited then begin
|
||||||
|
inc(i);
|
||||||
|
if i<Args.Count then v:=args[i] else v:='';
|
||||||
|
end else
|
||||||
|
v:=Copy(v, length(op.key)+1, length(v));
|
||||||
|
end else
|
||||||
|
v:='1'; // is switch, is enabled!
|
||||||
|
Vals.Add( TCmdLineOptionValue.Create(op.opt, v));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
end.
|
170
components/cmdlinecfg/trunk/cmdlinecfgui.pas
Normal file
170
components/cmdlinecfg/trunk/cmdlinecfgui.pas
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
unit cmdlinecfgui;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils,
|
||||||
|
cmdlinecfg;
|
||||||
|
|
||||||
|
type
|
||||||
|
{ TCmdLineLayoutInfo }
|
||||||
|
|
||||||
|
// Section names are assumed to be . separated.
|
||||||
|
// Anything after to . is expected to be a "sub section" of the section.
|
||||||
|
|
||||||
|
{ TLayoutSection }
|
||||||
|
|
||||||
|
TLayoutElementType = (letSwitch, letSection);
|
||||||
|
|
||||||
|
TLayoutSection = class(TObject)
|
||||||
|
//level : integer; // number of "dots" in the name
|
||||||
|
public
|
||||||
|
fName : string;
|
||||||
|
fElementType: TLayoutElementType;
|
||||||
|
public
|
||||||
|
Display : string;
|
||||||
|
GUIHint : string;
|
||||||
|
Elements : array of TLayoutSection;
|
||||||
|
ElemCount : integer;
|
||||||
|
function AddElement(const AName: string; AElementType: TLayoutElementType): TLayoutSection;
|
||||||
|
destructor Destroy; override;
|
||||||
|
property Name: string read fName;
|
||||||
|
property ElementType: TLayoutElementType read fElementType;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TCmdLineLayoutInfo = class(TObject)
|
||||||
|
private
|
||||||
|
fSections: TStringList;
|
||||||
|
fValidOrder: Boolean;
|
||||||
|
function DoGetSection(const SectName: String; Forced: Boolean = true): TLayoutSection;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
function AddSection(const Section: string): TLayoutSection;
|
||||||
|
function GetSection(const Section: string): TLayoutSection;
|
||||||
|
//function GetSwitches(const Section: string; Dst: TStrings): Boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineUIControl }
|
||||||
|
|
||||||
|
TCmdLineUIControl = class(TObject)
|
||||||
|
private
|
||||||
|
FValueChanged: TNotifyEvent;
|
||||||
|
protected
|
||||||
|
procedure ValueChanged; virtual;
|
||||||
|
public
|
||||||
|
procedure Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo); virtual; abstract;
|
||||||
|
procedure SetValues(list: TList {of TCmdLineOptionValue}); virtual; abstract;
|
||||||
|
procedure Serialize(list: TList {of TCmdLineOptionValue}); virtual; abstract;
|
||||||
|
property OnValueChanged: TNotifyEvent read FValueChanged write fValueChanged;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{ TLayoutSection }
|
||||||
|
|
||||||
|
function TLayoutSection.AddElement(const AName: string; AElementType: TLayoutElementType): TLayoutSection;
|
||||||
|
begin
|
||||||
|
if ElemCount = length(Elements) then begin
|
||||||
|
if ElemCount=0 then SetLength(Elements, 2)
|
||||||
|
else SetLength(Elements, ElemCount*2);
|
||||||
|
end;
|
||||||
|
Result:=TLayoutSection.Create;
|
||||||
|
Result.fName:=AName;
|
||||||
|
Result.fElementType:=AElementType;
|
||||||
|
Result.Display:=Aname;
|
||||||
|
Elements[ElemCount]:=Result;
|
||||||
|
inc(ElemCount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TLayoutSection.Destroy;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
for i:=0 to ElemCount-1 do Elements[i].Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineLayoutInfo }
|
||||||
|
|
||||||
|
function TCmdLineLayoutInfo.DoGetSection(const SectName: String; Forced: Boolean): TLayoutSection;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
i:=fSections.IndexOf(SectName);
|
||||||
|
if (i<0) and Forced then begin
|
||||||
|
Result:=TLayoutSection.Create;
|
||||||
|
fSections.AddObject(SectName, Result);
|
||||||
|
fValidOrder:=false; // a new section has been added, it might ruin the order
|
||||||
|
end else if (i<0) and not Forced then begin
|
||||||
|
Result:=nil;
|
||||||
|
end else
|
||||||
|
Result:=TLayoutSection(fSections.Objects[i]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TCmdLineLayoutInfo.Create;
|
||||||
|
begin
|
||||||
|
fSections:=TStringList.Create;
|
||||||
|
fSections.OwnsObjects:=true;
|
||||||
|
AddSection('');
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TCmdLineLayoutInfo.Destroy;
|
||||||
|
begin
|
||||||
|
fSections.Clear; // need to call clear explicitly, since FREE doesn't free objects (even if owned)
|
||||||
|
fSections.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{procedure TCmdLineLayoutInfo.AddSwitch(const Section: string;
|
||||||
|
const SwitchOrName: string);
|
||||||
|
begin
|
||||||
|
GetSection(Section).fswitches.Add(SwitchOrName);
|
||||||
|
end;}
|
||||||
|
|
||||||
|
function TCmdLineLayoutInfo.AddSection(const Section: string): TLayoutSection;
|
||||||
|
begin
|
||||||
|
Result:=DoGetSection(Section, true);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCmdLineLayoutInfo.GetSection(const Section: string): TLayoutSection;
|
||||||
|
begin
|
||||||
|
Result:=DoGetSection(Section, false);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{function TCmdLineLayoutInfo.GetSections(Dst: TStrings): Boolean;
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
if not fValidOrder then begin
|
||||||
|
SortSections;
|
||||||
|
fValidOrder:=true;
|
||||||
|
end;
|
||||||
|
Dst.BeginUpdate;
|
||||||
|
try
|
||||||
|
for i:=0 to fSections.Count-1 do
|
||||||
|
Dst.Add(fSections[i]);
|
||||||
|
finally
|
||||||
|
Dst.EndUpdate;
|
||||||
|
end;
|
||||||
|
Result:=True;
|
||||||
|
end;}
|
||||||
|
|
||||||
|
{function TCmdLineLayoutInfo.GetSwitches(const Section: string; Dst: TStrings): Boolean;
|
||||||
|
var
|
||||||
|
sct : TLayoutSection;
|
||||||
|
begin
|
||||||
|
sct:=GetSection(Section);
|
||||||
|
Result:=Assigned(Sct);
|
||||||
|
if not Result then Exit;
|
||||||
|
Dst.AddStrings(sct.fswitches);
|
||||||
|
end;}
|
||||||
|
|
||||||
|
{ TCmdLineUIControl }
|
||||||
|
|
||||||
|
procedure TCmdLineUIControl.ValueChanged;
|
||||||
|
begin
|
||||||
|
if Assigned(fValueChanged) then fValueChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
141
components/cmdlinecfg/trunk/cmdlinecfguijson.pas
Normal file
141
components/cmdlinecfg/trunk/cmdlinecfguijson.pas
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
unit cmdlinecfguijson;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$mode delphi}
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, cmdlinecfgui, fpjson, jsonparser;
|
||||||
|
|
||||||
|
|
||||||
|
function CmdLineUIJSONReadFile(stream: TStream; lt: TCmdLineLayoutInfo): Boolean; overload;
|
||||||
|
function CmdLineUIJSONReadFile(const FileName: String; lt: TCmdLineLayoutInfo): Boolean; overload;
|
||||||
|
procedure CmdLineCfgUIJSONLoadFilesFromDir(const Dir: String; list: TList; const Mask : string = '*.coptui');
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
type
|
||||||
|
{ TSectionIterator }
|
||||||
|
|
||||||
|
TSectionIterator = class(TObject)
|
||||||
|
public
|
||||||
|
lt : TCmdLineLayoutInfo;
|
||||||
|
sc : TLayoutSection;
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Iterate(Const AName : TJSONStringType; Item: TJSONData; Data: TObject; var DoContinue: Boolean);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function CmdLineUIJSONReadFile(stream: TStream; lt: TCmdLineLayoutInfo): Boolean;
|
||||||
|
var
|
||||||
|
p : TJSONParser;
|
||||||
|
d : TJSONData;
|
||||||
|
core : TJSONObject;
|
||||||
|
st : TSectionIterator;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
d:=nil;
|
||||||
|
p:=TJSONParser.Create(stream);
|
||||||
|
try
|
||||||
|
d:=p.Parse;
|
||||||
|
if d.JSONType<>jtObject then Exit;
|
||||||
|
core:=TJSONObject(d);
|
||||||
|
|
||||||
|
st:=TSectionIterator.Create;
|
||||||
|
try
|
||||||
|
st.lt:=lt;
|
||||||
|
st.sc:=lt.GetSection('');
|
||||||
|
core.Iterate( st.Iterate, st)
|
||||||
|
finally
|
||||||
|
st.Free;
|
||||||
|
end;
|
||||||
|
Result:=true;
|
||||||
|
finally
|
||||||
|
d.Free;
|
||||||
|
p.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CmdLineUIJSONReadFile(const FileName: String; lt: TCmdLineLayoutInfo): Boolean;
|
||||||
|
var
|
||||||
|
fs : TFileStream;
|
||||||
|
begin
|
||||||
|
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
|
||||||
|
try
|
||||||
|
Result:=CmdLineUIJSONReadFile(fs, lt);
|
||||||
|
finally
|
||||||
|
fs.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CmdLineCfgUIJSONLoadFilesFromDir(const Dir: String; list: TList; const Mask : string = '*.coptui');
|
||||||
|
var
|
||||||
|
rslt : TSearchRec;
|
||||||
|
res : Integer;
|
||||||
|
pth : string;
|
||||||
|
cfg : TCmdLineLayoutInfo;
|
||||||
|
begin
|
||||||
|
pth:=IncludeTrailingPathDelimiter(Dir);
|
||||||
|
res:=FindFirst( pth+Mask, faAnyFile, rslt);
|
||||||
|
try
|
||||||
|
while res = 0 do begin
|
||||||
|
if (rslt.Attr and faDirectory=0) and (rslt.Size>0) then begin
|
||||||
|
cfg := TCmdLineLayoutInfo.Create;
|
||||||
|
if not CmdLineUIJSONReadFile(pth+rslt.Name, cfg) then cfg.Free
|
||||||
|
else list.Add(cfg);
|
||||||
|
end;
|
||||||
|
res:=FindNext(rslt);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FindClose(rslt);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TSectionIterator }
|
||||||
|
|
||||||
|
constructor TSectionIterator.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TSectionIterator.Destroy;
|
||||||
|
begin
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSectionIterator.Iterate(const AName: TJSONStringType;
|
||||||
|
Item: TJSONData; Data: TObject; var DoContinue: Boolean);
|
||||||
|
var
|
||||||
|
l : string;
|
||||||
|
a : TJSONArray;
|
||||||
|
i : Integer;
|
||||||
|
st : TSectionIterator;
|
||||||
|
subnm : string;
|
||||||
|
begin
|
||||||
|
l:=AnsiLowerCase(AName);
|
||||||
|
if (l='switches') and (Item.JSONType=jtArray) then begin
|
||||||
|
a:=TJSONArray(Item);
|
||||||
|
for i:=0 to a.Count-1 do begin
|
||||||
|
if (a.Items[i].JSONType=jtString) then
|
||||||
|
sc.AddElement( TJSONString(a.Items[i]).AsString, letSwitch );
|
||||||
|
end;
|
||||||
|
end else if (l='display') and (Item.JSONType=jtString) then begin
|
||||||
|
sc.Display:=Item.AsString;
|
||||||
|
end else if (l='hint') and (Item.JSONType=jtString) then begin
|
||||||
|
sc.GUIHint:=Item.AsString;
|
||||||
|
end else if (item.JSONType=jtObject) then begin
|
||||||
|
// sub section
|
||||||
|
st:=TSectionIterator.Create;
|
||||||
|
try
|
||||||
|
st.sc:=Self.sc.AddElement(AName, letSection);
|
||||||
|
st.lt:=Self.lt;
|
||||||
|
TJSONObject(Item).Iterate(st.Iterate, st);
|
||||||
|
finally
|
||||||
|
st.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
282
components/cmdlinecfg/trunk/cmdlinecfgutils.pas
Normal file
282
components/cmdlinecfg/trunk/cmdlinecfgutils.pas
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
unit cmdlinecfgutils;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$mode delphi}
|
||||||
|
|
||||||
|
uses
|
||||||
|
SysUtils, Classes, cmdlinecfg, process;
|
||||||
|
|
||||||
|
function CmdLineCfgCombine(const ancestor, child: TCmdLineCfg; DoDeleteDashTypes: Boolean = true): Boolean;
|
||||||
|
procedure CmdLineCfgRemoveUnused(cfg: TCmdLineCfg);
|
||||||
|
function CmdLineCfgDetect(listofcfg: TList {of TCmdLineCfg}; const Dir, FullPathExec: string): TCmdLineCfg;
|
||||||
|
|
||||||
|
function ReadOutput(const Dir, ExecCommand: String): string;
|
||||||
|
|
||||||
|
// make the Value to be comand-line friendly, by handling CommandLineINvalidChars
|
||||||
|
// quotes would be added, if white-space characters are found
|
||||||
|
// todo: command lines replacement, should be system specific!
|
||||||
|
function CmdLineNormalizeParam(const Value: String): String;
|
||||||
|
|
||||||
|
// parses a command line into a list of arguments
|
||||||
|
// to be compatbile with RTL: ParamStr, ParamCount
|
||||||
|
procedure CmdLineParse(const cmdline: string; arguments : TStrings);
|
||||||
|
function CmdLineToExecutable(const cmdline: String; var Executable: string; Args: TStrings): Boolean;
|
||||||
|
|
||||||
|
procedure CmdLineAllocMultiValues(opt: TCmdLineCfgOption; const SrcValue: string; Delim: Char; dst: TList);
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function OverrideIfEmpty(const existingValue, ReplacingValue: string): string;
|
||||||
|
begin
|
||||||
|
if existingValue='' then Result:=ReplacingValue else Result:=existingValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CmdLineCfgOptionCopy(const opt: TCmdLineCfgOption): TCmdLineCfgOption;
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
Result:=TCmdLineCfgOption.Create;
|
||||||
|
Result.Section:=opt.Section;
|
||||||
|
Result.SubSection:=opt.SubSection;
|
||||||
|
Result.Name:=opt.Name;
|
||||||
|
Result.OptType:=opt.OptType;
|
||||||
|
Result.Key:=opt.Key;
|
||||||
|
Result.Display:=opt.Display;
|
||||||
|
Result.Condition:=opt.Condition;
|
||||||
|
Result.ValCount:=opt.ValCount;
|
||||||
|
SetLength(Result.Values, Result.ValCount);
|
||||||
|
for i:=0 to Result.ValCount-1 do begin
|
||||||
|
Result.Values[i].Condition:=opt.Values[i].Condition;
|
||||||
|
Result.Values[i].DisplayName:=opt.Values[i].DisplayName;
|
||||||
|
Result.Values[i].CmdLineValue:=opt.Values[i].DisplayName;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SortByName(p1,p2: Pointer): Integer;
|
||||||
|
var
|
||||||
|
o1, o2: TCmdLineCfgOption;
|
||||||
|
begin
|
||||||
|
o1:=TCmdLineCfgOption(p1);
|
||||||
|
o2:=TCmdLineCfgOption(p2);
|
||||||
|
Result:=CompareStr(o1.Name, o2.Name);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CmdLineCfgCombine(const ancestor, child: TCmdLineCfg; DoDeleteDashTypes: Boolean = true): Boolean;
|
||||||
|
var
|
||||||
|
i, j : integer;
|
||||||
|
l1,l2 : TList;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
begin
|
||||||
|
Result:=Assigned(ancestor) and Assigned(child)
|
||||||
|
and (ancestor.Version=child.FromVersion) and (ancestor.Executable=child.Executable);
|
||||||
|
if not Result then Exit;
|
||||||
|
// executable
|
||||||
|
// version
|
||||||
|
// testValue
|
||||||
|
// fromVersion are not inheritable
|
||||||
|
child.TestKey:=OverrideIfEmpty(child.TestKey, ancestor.TestKey);
|
||||||
|
ancestor.Options.Sort(@SortByName);
|
||||||
|
child.Options.Sort(@SortByName);
|
||||||
|
i:=0;
|
||||||
|
j:=0;
|
||||||
|
for i:=0 to ancestor.Options.Count-1 do begin
|
||||||
|
opt:=TCmdLineCfgOption(ancestor.Options[i]);
|
||||||
|
while (j<child.Options.Count) and (CompareStr(opt.Name, TCmdLineCfgOption(child.Options[j]).Name)>0) do
|
||||||
|
inc(j);
|
||||||
|
if (j<child.Options.Count) and (CompareStr(opt.Name, TCmdLineCfgOption(child.Options[j]).Name)<0) then begin
|
||||||
|
child.Options.Add ( CmdLineCfgOptionCopy (opt));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if DoDeleteDashTypes then CmdLineCfgRemoveUnused(child);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CmdLineCfgRemoveUnused(cfg: TCmdLineCfg);
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
for i:=0 to cfg.Options.Count-1 do
|
||||||
|
if TCmdLineCfgOption(cfg.Options[i]).OptType='-' then begin
|
||||||
|
TCmdLineCfgOption(cfg.Options[i]).Free;
|
||||||
|
cfg.Options[i]:=nil;
|
||||||
|
end;
|
||||||
|
cfg.Options.Pack;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ReadOutput(const Dir, ExecCommand: String): string;
|
||||||
|
var
|
||||||
|
p: TProcess;
|
||||||
|
m: TMemoryStream;
|
||||||
|
BytesRead : Integer;
|
||||||
|
n: INteger;
|
||||||
|
exe : string;
|
||||||
|
const
|
||||||
|
READ_BYTES = 1024;
|
||||||
|
begin
|
||||||
|
Result:='';
|
||||||
|
BytesRead:=0;
|
||||||
|
m:=TMemoryStream.Create;
|
||||||
|
p:=TProcess.Create(nil);
|
||||||
|
try
|
||||||
|
exe:='';
|
||||||
|
if not CmdLineToExecutable(ExecCommand, exe, p.Parameters) then Exit;
|
||||||
|
p.Executable:=exe;
|
||||||
|
p.CurrentDirectory:=Dir;
|
||||||
|
p.Options:=[poUsePipes, poStdErrToOutput];
|
||||||
|
p.Execute;
|
||||||
|
while P.Running do begin
|
||||||
|
if P.Output.NumBytesAvailable>0 then begin
|
||||||
|
if M.Size-M.Position<READ_BYTES then begin
|
||||||
|
M.SetSize(BytesRead + READ_BYTES);
|
||||||
|
end;
|
||||||
|
n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
|
||||||
|
if n > 0 then Inc(BytesRead, n) else Sleep(1);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
repeat
|
||||||
|
M.SetSize(BytesRead + READ_BYTES);
|
||||||
|
n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
|
||||||
|
if n > 0 then Inc(BytesRead, n);
|
||||||
|
until n <= 0;
|
||||||
|
if BytesRead > 0 then M.SetSize(BytesRead);
|
||||||
|
M.Position:=0;
|
||||||
|
SetLength(Result, M.Size);
|
||||||
|
if length(Result)>0 then
|
||||||
|
M.Read(Result[1], M.Size);
|
||||||
|
finally
|
||||||
|
p.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SortByTestKey(c1, c2: TCmdLineCfg {these are actually Pointers in here!}): Integer;
|
||||||
|
begin
|
||||||
|
Result:=CompareStr(c1.TestKey, c2.TestKey);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CmdLineCfgDetect(listofcfg: TList {of TCmdLineCfg}; const Dir, FullPathExec: string): TCmdLineCfg;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
cfg : TCmdLineCfg;
|
||||||
|
tk : String;
|
||||||
|
tv : String;
|
||||||
|
search : TList;
|
||||||
|
begin
|
||||||
|
Result:=nil;
|
||||||
|
search:=TList.Create;
|
||||||
|
try
|
||||||
|
tk:='';
|
||||||
|
search.Assign(listofcfg);
|
||||||
|
search.Sort(@SortByTestKey);
|
||||||
|
for i:=0 to listofcfg.Count-1 do begin
|
||||||
|
cfg := TCmdLineCfg(listofcfg[i]);
|
||||||
|
if cfg.TestKey<>tk then begin
|
||||||
|
tk:=cfg.TestKey;
|
||||||
|
tv:=trim(ReadOutput(dir, FullPathExec+' '+tk));
|
||||||
|
end;
|
||||||
|
if cfg.TestValue=tv then begin
|
||||||
|
Result:=cfg;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
search.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CmdLineNormalizeParam(const Value: String): String;
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
const
|
||||||
|
CommandLineInvalidChars : set of Char = ['/','\',':','"','''','?','<','>',' '];
|
||||||
|
begin
|
||||||
|
for i:=0 to length(Value) do
|
||||||
|
if Value[i] in CommandLineInvalidChars then begin
|
||||||
|
//todo!
|
||||||
|
Result:='"'+Result+'"';
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
Result:=Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function CmdLineToExecutable(const cmdline: String; var Executable: string;
|
||||||
|
Args: TStrings): Boolean;
|
||||||
|
var
|
||||||
|
a : TStringList;
|
||||||
|
begin
|
||||||
|
a:=TStringList.Create;
|
||||||
|
try
|
||||||
|
CmdLineParse(cmdline, a);
|
||||||
|
Result:=a.Count>0;
|
||||||
|
if Result then begin
|
||||||
|
Executable:=a[0];
|
||||||
|
a.Delete(0);
|
||||||
|
Args.Assign(a);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
a.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CmdLineParse(const cmdline: string; arguments : TStrings);
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
j : integer;
|
||||||
|
isprm : Boolean;
|
||||||
|
p : string;
|
||||||
|
const
|
||||||
|
WhiteSpace : set of char = [#32,#9,#8,#13,#10];
|
||||||
|
QuoteChar = '"'; // yeah! be academic!
|
||||||
|
begin
|
||||||
|
if not Assigned(arguments) then eXit;
|
||||||
|
j:=1;
|
||||||
|
i:=1;
|
||||||
|
isprm:=false;
|
||||||
|
p:='';
|
||||||
|
while i<=length(cmdline) do begin
|
||||||
|
if not (cmdline[i] in WhiteSpace) then begin
|
||||||
|
if not isprm then j:=i;
|
||||||
|
if cmdline[i]=QuoteChar then begin
|
||||||
|
p:=p+Copy(cmdline, j, i-j);
|
||||||
|
inc(i);
|
||||||
|
j:=i;
|
||||||
|
while (i<=length(cmdline)) and (cmdline[i]<>'"') do
|
||||||
|
inc(i);
|
||||||
|
p:=p+Copy(cmdline, j, i-j);
|
||||||
|
j:=i+1;
|
||||||
|
end;
|
||||||
|
isprm:=true;
|
||||||
|
end else if isprm then begin
|
||||||
|
arguments.Add(p+Copy(cmdline, j, i-j));
|
||||||
|
isprm:=false;
|
||||||
|
p:='';
|
||||||
|
end;
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
if isprm then arguments.Add(p+Copy(cmdline, j, i-j));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CmdLineAllocMultiValues(opt: TCmdLineCfgOption; const SrcValue: string; Delim: Char; dst: TList);
|
||||||
|
var
|
||||||
|
i, j : Integer;
|
||||||
|
vl : TCmdLineOptionValue;
|
||||||
|
v : string;
|
||||||
|
begin
|
||||||
|
if not Assigned(opt) or not Assigned(dst) or (SrcValue='') then Exit;
|
||||||
|
i:=1; j:=1;
|
||||||
|
while i<=length(SrcValue) do begin
|
||||||
|
if SrcValue[i]=Delim then begin
|
||||||
|
v:=Trim(Copy(SrcValue, j, i-j));
|
||||||
|
j:=i+1;
|
||||||
|
if v<>'' then dst.Add( TCmdLineOptionValue.Create(opt, v));
|
||||||
|
end;
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
if j<i then begin
|
||||||
|
v:=Trim(Copy(SrcValue, j, i-j));
|
||||||
|
j:=i+1;
|
||||||
|
if v<>'' then dst.Add( TCmdLineOptionValue.Create(opt, v));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
122
components/cmdlinecfg/trunk/cmdlinefpccond.pas
Normal file
122
components/cmdlinecfg/trunk/cmdlinefpccond.pas
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
unit cmdlinefpccond;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
SysUtils;
|
||||||
|
|
||||||
|
//todo: need to distingiush between cpu and os.
|
||||||
|
// the list however, need to come externally
|
||||||
|
|
||||||
|
type
|
||||||
|
{ TFPCConditionCheck }
|
||||||
|
TFPCConditionCheck = class(TObject)
|
||||||
|
private
|
||||||
|
fCndStr: string;
|
||||||
|
cnt : integer;
|
||||||
|
fCnd : array of record cpu, os: string end;
|
||||||
|
procedure AddSubCond(const cond: string);
|
||||||
|
procedure ParseStr(const ACndStr: string);
|
||||||
|
public
|
||||||
|
constructor Create(const ACndStr: string);
|
||||||
|
function isValid(const cpu, os: string): Boolean;
|
||||||
|
property CndStr: string read fCndStr;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure ParseCPUOS(const cpu_os: string; var cpu, os : string);
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
//todo: see todo above!
|
||||||
|
i:=Pos('-', cpu_os);
|
||||||
|
if i>0 then begin
|
||||||
|
cpu:=Copy(cpu_os, 1, i-1);
|
||||||
|
os:=Copy(cpu_os, i+1, length(cpu_os));
|
||||||
|
end else begin
|
||||||
|
cpu:=cpu_os;
|
||||||
|
os:='';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TFPCConditionCheck }
|
||||||
|
|
||||||
|
procedure TFPCConditionCheck.AddSubCond(const cond: string);
|
||||||
|
var
|
||||||
|
os,cpu: string;
|
||||||
|
begin
|
||||||
|
os:=''; cpu:='';
|
||||||
|
ParseCPUOS(cond, cpu, os);
|
||||||
|
if cpu<>'' then begin
|
||||||
|
if cnt=length(fCnd) then begin
|
||||||
|
if cnt=0 then SetLength(fCnd, 4)
|
||||||
|
else SetLEngth(fCnd, cnt*2);
|
||||||
|
end;
|
||||||
|
fCnd[cnt].cpu:=AnsiLowerCase(cpu);
|
||||||
|
fCnd[cnt].os:=AnsiLowerCase(os);
|
||||||
|
inc(cnt);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFPCConditionCheck.ParseStr(const ACndStr: string);
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
j : integer;
|
||||||
|
s : string;
|
||||||
|
begin
|
||||||
|
j:=1;
|
||||||
|
cnt:=0;
|
||||||
|
i:=1;
|
||||||
|
while i<=length(ACndStr) do begin
|
||||||
|
if ACndStr[i] in [','] then begin
|
||||||
|
s:=trim(Copy(ACndStr, j, i-j));
|
||||||
|
if s<>'' then AddSubCond(s);
|
||||||
|
j:=i+1;
|
||||||
|
end;
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
if j<length(ACndStr) then
|
||||||
|
AddSubCond( Copy(ACndStr, j, i-j));
|
||||||
|
SetLength(fCnd, cnt);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TFPCConditionCheck.Create(const ACndStr: string);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
ParseStr(ACndStr);
|
||||||
|
fCndStr:=ACndStr;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFPCConditionCheck.isValid(const cpu, os: string): Boolean;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
a, b: string;
|
||||||
|
begin
|
||||||
|
if length(fCnd)=0 then begin
|
||||||
|
Result:=true;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
a:=AnsiLowerCase(cpu);
|
||||||
|
b:=AnsiLowerCase(os);
|
||||||
|
if (cpu='') and (os<>'') then begin
|
||||||
|
a:=b;
|
||||||
|
b:='';
|
||||||
|
end;
|
||||||
|
for i:=0 to length(fCnd)-1 do begin
|
||||||
|
Result:=// complete match of os and cpu
|
||||||
|
((fCnd[i].os=b) and (fCnd[i].cpu=a))
|
||||||
|
// this is the check, when only OS or only CPU is specified as a condition
|
||||||
|
// but either CPU or OS has been passed.
|
||||||
|
// i.e.
|
||||||
|
// "i386" valid for "i386-linux" or "i386-Win32"
|
||||||
|
// "darwin" valid for "arm-darwin" or "i386-darwin"
|
||||||
|
// note, that if a condition consists only of a single string, it
|
||||||
|
// will always be saved into "cpu" field of the check record.
|
||||||
|
or ( (fCnd[i].os='') and ((fCnd[i].cpu=a) or (fCnd[i].cpu=b)));
|
||||||
|
if Result then Exit;
|
||||||
|
end;
|
||||||
|
Result:=False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
371
components/cmdlinecfg/trunk/cmdlinelazcompopt.pas
Normal file
371
components/cmdlinecfg/trunk/cmdlinelazcompopt.pas
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
unit cmdlinelazcompopt;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
// this unit depends on IDEIntf package (CompOptsIntf.pas) !
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, CompOptsIntf, cmdlinecfg, cmdlinecfgutils, cmdlinecfgparser, contnrs;
|
||||||
|
|
||||||
|
{ Either procedures depends on a certain names/keys used for the FPC options.
|
||||||
|
This has to be caferully maintained in the configuration file. }
|
||||||
|
procedure LazCompOptToVals(opt: TLazCompilerOptions; cfg: TCmdLineCfg; list: TList {of TCmdLineValueOpts});
|
||||||
|
procedure ValsToLazCompOpt(list: TList {of TCmdLineValueOpts}; opt: TLazCompilerOptions);
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
// hash all values - make their copies and "join" multi values (if available)
|
||||||
|
function AllocLookup(list: TList): TFPHashObjectList;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
v : TCmdLineOptionValue;
|
||||||
|
lv : TCmdLineOptionValue;
|
||||||
|
d : string;
|
||||||
|
begin
|
||||||
|
Result:=TFPHashObjectList.Create(true);
|
||||||
|
for i:=0 to list.Count-1 do begin
|
||||||
|
v:=TCmdLineOptionValue(list[i]);
|
||||||
|
if not Assigned(v) or not Assigned(v.Option) then Continue;
|
||||||
|
lv:=TCmdLineOptionValue(Result.Find(v.Option.Name));
|
||||||
|
if v.Option.isMultiple then begin
|
||||||
|
if not Assigned(lv) then begin
|
||||||
|
lv:=TCmdLineOptionValue.Create(v.Option, v.Value);
|
||||||
|
Result.Add(v.Option.Name, lv);
|
||||||
|
end else begin
|
||||||
|
if (v.Option.OptType='filepath') or (v.Option.OptType='dirpath') then d:=';' else d:=' ';
|
||||||
|
if lv.Value='' then lv.Value:=v.Value else lv.Value:=lv.Value+d+v.Value;
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
if not Assigned(lv) then begin
|
||||||
|
lv:=TCmdLineOptionValue.Create(v.Option, v.Value);
|
||||||
|
Result.Add(v.Option.Name, lv);
|
||||||
|
end else
|
||||||
|
lv.Value:=v.Value;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LookupStr(lp: TFPHashObjectList; const Name: string; const Default: string = ''; Remove: Boolean = true): string;
|
||||||
|
var
|
||||||
|
v: TCmdLineOptionValue;
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
i:=lp.FindIndexOf(Name);
|
||||||
|
if i>=0 then begin
|
||||||
|
v:=TCmdLineOptionValue(lp.Items[i]);
|
||||||
|
Result:=v.Value;
|
||||||
|
if Remove then lp.Delete(i); // frees the object
|
||||||
|
end else
|
||||||
|
Result:=Default;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LookupBool(lp: TFPHashObjectList; const Name: string; const Default: Boolean = false; Remove: Boolean = true): Boolean;
|
||||||
|
var
|
||||||
|
v: TCmdLineOptionValue;
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
i:=lp.FindIndexOf(Name);
|
||||||
|
if i>=0 then begin
|
||||||
|
v:=TCmdLineOptionValue(lp.Items[i]);
|
||||||
|
Result:=v.Value<>'';
|
||||||
|
if Remove then lp.Delete(i); // frees the object
|
||||||
|
end else
|
||||||
|
Result:=Default;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LookupInt(lp: TFPHashObjectList; const Name: string; const Default: Integer = 0; Remove: Boolean = true): Integer;
|
||||||
|
var
|
||||||
|
v: TCmdLineOptionValue;
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
i:=lp.FindIndexOf(Name);
|
||||||
|
if i>=0 then begin
|
||||||
|
v:=TCmdLineOptionValue(lp.Items[i]);
|
||||||
|
Result:=StrToIntDef(v.Value,Default);
|
||||||
|
if Remove then lp.Delete(i); // frees the object
|
||||||
|
end else
|
||||||
|
Result:=Default;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function StrToDbgSymbolType(const vals: string): TCompilerDbgSymbolType;
|
||||||
|
var
|
||||||
|
v : string;
|
||||||
|
begin
|
||||||
|
v:=AnsiLowerCase(vals);
|
||||||
|
if v='s' then Result:=dsStabs
|
||||||
|
else if v='w2' then Result:=dsDwarf2
|
||||||
|
else if v='w' then Result:=dsDwarf2Set // ???
|
||||||
|
else if v='w3' then Result:=dsDwarf3;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ValsToLazCompOpt(list: TList {of TCmdLineValueOpts}; opt: TLazCompilerOptions);
|
||||||
|
var
|
||||||
|
lookup : TFPHashObjectList;
|
||||||
|
i : Integer;
|
||||||
|
l : TList;
|
||||||
|
begin
|
||||||
|
lookup:=AllocLookup(list);
|
||||||
|
try
|
||||||
|
// search paths:
|
||||||
|
opt.IncludePath:=LookupStr(lookup, '-Fi');
|
||||||
|
opt.Libraries:=LookupStr(lookup, '-Fl');
|
||||||
|
opt.ObjectPath:=LookupStr(lookup, '-Fo');
|
||||||
|
opt.OtherUnitFiles:=LookupStr(lookup, '-Fu');
|
||||||
|
//opt.SrcPath (not in compiler options)
|
||||||
|
//opt.DebugPath
|
||||||
|
opt.UnitOutputDirectory:=LookupStr(lookup, '-FU');
|
||||||
|
|
||||||
|
// target:
|
||||||
|
opt.TargetFilename:=LookupStr(lookup, '-o');
|
||||||
|
//opt.TargetFilenameApplyConventions
|
||||||
|
|
||||||
|
// parsing:
|
||||||
|
opt.SyntaxMode:=LookupStr(lookup, '-M');
|
||||||
|
//property AssemblerStyle: Integer read fAssemblerStyle write SetAssemblerStyle;
|
||||||
|
opt.CStyleOperators:=LookupBool(lookup, '-Sc');
|
||||||
|
opt.IncludeAssertionCode:=LookupBool(lookup, '-Sa');
|
||||||
|
opt.AllowLabel:=LookupBool(lookup,'-Sg');
|
||||||
|
opt.UseAnsiStrings:=LookupBool(lookup,'-Sh');
|
||||||
|
opt.CPPInline:=LookupBool(lookup,'-Si');
|
||||||
|
opt.CStyleMacros:=LookupBool(lookup,'-Sm');
|
||||||
|
opt.InitConstructor:=LookupBool(lookup,'-Ss');
|
||||||
|
|
||||||
|
// -St is obsolete option ... so shouldn't be available
|
||||||
|
opt.StaticKeyword:=LookupBool(lookup,'-St');
|
||||||
|
|
||||||
|
// code generation:
|
||||||
|
opt.IOChecks:=LookupBool(lookup,'-Ci');
|
||||||
|
opt.RangeChecks:=LookupBool(lookup,'-Cr');
|
||||||
|
opt.OverflowChecks:=LookupBool(lookup,'-Co');
|
||||||
|
opt.StackChecks:=LookupBool(lookup,'-Ct');
|
||||||
|
opt.SmartLinkUnit:=LookupBool(lookup,'-CX');
|
||||||
|
opt.RelocatableUnit:=LookupBool(lookup,'-WR');
|
||||||
|
opt.EmulatedFloatOpcodes:=LookupBool(lookup,'-Ce');
|
||||||
|
|
||||||
|
opt.HeapSize:=LookupInt(lookup, '-Ch');
|
||||||
|
opt.StackSize:=LookupInt(lookup, '-Cs');
|
||||||
|
opt.VerifyObjMethodCall:=LookupBool(lookup,'-CR');
|
||||||
|
|
||||||
|
opt.SmallerCode :=LookupBool(lookup, '-Os');
|
||||||
|
opt.TargetCPU :=LookupStr(lookup, '-P');
|
||||||
|
opt.TargetProcessor:=LookupStr(lookup, '-Op');
|
||||||
|
opt.TargetOS:=LookupStr(lookup, '-T');
|
||||||
|
opt.VariablesInRegisters:=LookupBool(lookup, '-Or');
|
||||||
|
opt.UncertainOptimizations:=LookupBool(lookup, '-Ou');
|
||||||
|
opt.OptimizationLevel:=StrToIntDef(LookupStr(lookup, '-O'),0);
|
||||||
|
|
||||||
|
// linking:
|
||||||
|
opt.GenerateDebugInfo:=LookupBool(lookup, '-g');
|
||||||
|
|
||||||
|
opt.DebugInfoType:=StrToDbgSymbolType(LookupStr(lookup, '-g'));
|
||||||
|
//opt.DebugInfoTypeStr: String read GetDebugInfoTypeStr;
|
||||||
|
|
||||||
|
opt.UseLineInfoUnit:=LookupBool(lookup, '-gl');
|
||||||
|
opt.UseHeaptrc:=LookupBool(lookup, '-gh');
|
||||||
|
opt.UseValgrind:=LookupBool(lookup, '-gv');
|
||||||
|
opt.GenGProfCode:=LookupBool(lookup, '-pg');
|
||||||
|
opt.StripSymbols:=LookupBool(lookup, '-Xs');
|
||||||
|
opt.LinkSmart:=LookupBool(lookup, '-XX');
|
||||||
|
|
||||||
|
opt.LinkerOptions:=LookupStr(lookup, '-k');
|
||||||
|
opt.PassLinkerOptions:=opt.LinkerOptions<>''; //todo:!
|
||||||
|
|
||||||
|
opt.Win32GraphicApp:=LookupBool(lookup, '-WG');
|
||||||
|
//ExecutableType: TCompilationExecutableType read FExecutableType write SetExecutableType;
|
||||||
|
opt.UseExternalDbgSyms:=LookupBool(lookup, '-Xg');
|
||||||
|
|
||||||
|
// messages:
|
||||||
|
opt.ShowErrors:=LookupBool(lookup, '-ve');
|
||||||
|
opt.ShowWarn:=LookupBool(lookup, '-vw');
|
||||||
|
opt.ShowNotes:=LookupBool(lookup, '-vn');
|
||||||
|
opt.ShowHints:=LookupBool(lookup, '-vh');
|
||||||
|
opt.ShowGenInfo:=LookupBool(lookup, '-vi');
|
||||||
|
opt.ShowLineNum:=LookupBool(lookup, '-vl');
|
||||||
|
opt.ShowAll:=LookupBool(lookup, '-va');
|
||||||
|
opt.ShowAllProcsOnError:=LookupBool(lookup, '-Xs');
|
||||||
|
|
||||||
|
opt.ShowDebugInfo:=LookupBool(lookup, '-vd');
|
||||||
|
opt.ShowUsedFiles:=LookupBool(lookup, '-vu');
|
||||||
|
opt.ShowTriedFiles:=LookupBool(lookup, '-vt');
|
||||||
|
opt.ShowCompProc:=LookupBool(lookup, '-vp');
|
||||||
|
opt.ShowCond:=LookupBool(lookup, '-vc');
|
||||||
|
opt.ShowExecInfo:=LookupBool(lookup, '-vx');
|
||||||
|
opt.ShowNothing:=LookupBool(lookup, '-v0');
|
||||||
|
//opt.ShowSummary
|
||||||
|
//opt.ShowHintsForUnusedUnitsInMainSrc
|
||||||
|
//opt.ShowHintsForSenderNotUsed
|
||||||
|
opt.WriteFPCLogo:=LookupBool(lookup, '-l');
|
||||||
|
opt.StopAfterErrCount:=LookupInt(lookup, '-Se');
|
||||||
|
|
||||||
|
// other
|
||||||
|
opt.DontUseConfigFile:=LookupBool(lookup, '-n');
|
||||||
|
//opt.ConfigFilePath:=LookupStr(lookup, '@');
|
||||||
|
//opt.CustomConfigFile:=opt.ConfigFilePath<>'';
|
||||||
|
|
||||||
|
|
||||||
|
if lookup.Count>0 then begin
|
||||||
|
l:=TList.Create;
|
||||||
|
try
|
||||||
|
for i:=0 to lookup.Count-1 do l.Add(lookup.Items[i]);
|
||||||
|
opt.CustomOptions:=CmdLineMakeOptions(l);
|
||||||
|
finally
|
||||||
|
l.Free; // values, will be freed with lookup
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
lookup.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AddBoolValue(cfg: TCmdLineCfg; const Key: string; AVal: Boolean; list: TList; var Other: string);
|
||||||
|
var
|
||||||
|
o : TCmdLineCfgOption;
|
||||||
|
begin
|
||||||
|
if not AVal then Exit;
|
||||||
|
o:=cfg.FindOption(Key);
|
||||||
|
if Assigned(o) then
|
||||||
|
list.Add(TCmdLineOptionValue.Create(o, '1'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AddStrValue(cfg: TCmdLineCfg; const Key, AVal: string; list: TList; var Other: string);
|
||||||
|
var
|
||||||
|
o : TCmdLineCfgOption;
|
||||||
|
begin
|
||||||
|
if AVal='' then Exit;
|
||||||
|
o:=cfg.FindOption(Key);
|
||||||
|
if Assigned(o) then
|
||||||
|
list.Add(TCmdLineOptionValue.Create(o, AVal));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AddIntValue(cfg: TCmdLineCfg; const Key: string; AVal: Integer; list: TList; var Other: string);
|
||||||
|
var
|
||||||
|
o : TCmdLineCfgOption;
|
||||||
|
begin
|
||||||
|
if AVal<=0 then Exit;
|
||||||
|
o:=cfg.FindOption(Key);
|
||||||
|
if Assigned(o) then
|
||||||
|
list.Add(TCmdLineOptionValue.Create(o, IntToStr(AVal)));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AddMultiStrValue(cfg: TCmdLineCfg; const Key, AVal, Delim: string; list: TList; var Other: string);
|
||||||
|
var
|
||||||
|
o : TCmdLineCfgOption;
|
||||||
|
ch : Char;
|
||||||
|
begin
|
||||||
|
if AVal='' then Exit;
|
||||||
|
o:=cfg.FindOption(Key);
|
||||||
|
if Assigned(o) then begin
|
||||||
|
if length(DElim)>0 then ch:=Delim[1] else ch:=#0;
|
||||||
|
CmdLineAllocMultiValues(o, AVal, ch, list);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure LazCompOptToVals(opt: TLazCompilerOptions; cfg: TCmdLineCfg; list: TList {of TCmdLineValueOpts});
|
||||||
|
var
|
||||||
|
other : string;
|
||||||
|
begin
|
||||||
|
other := '';
|
||||||
|
AddMultiStrValue(cfg, '-Fi', opt.IncludePath, ';', list, Other);
|
||||||
|
AddMultiStrValue(cfg, '-Fl', opt.Libraries, ';', list, Other);
|
||||||
|
AddMultiStrValue(cfg, '-Fo', opt.ObjectPath, ';', list, Other);
|
||||||
|
AddMultiStrValue(cfg, '-Fu', opt.OtherUnitFiles, ';', list, Other);
|
||||||
|
// opt.SrcPath (not in compiler options) ?? -sources for Lazarus itself?
|
||||||
|
|
||||||
|
//opt.DebugPath
|
||||||
|
AddStrValue(cfg, '-FU', opt.UnitOutputDirectory, list, other);
|
||||||
|
|
||||||
|
// target:
|
||||||
|
AddStrValue(cfg, '-o', opt.TargetFilename, list, other);
|
||||||
|
|
||||||
|
// parsing:
|
||||||
|
AddStrValue(cfg, '-M', opt.UnitOutputDirectory, list, other);
|
||||||
|
|
||||||
|
//property AssemblerStyle: Integer read fAssemblerStyle write SetAssemblerStyle;
|
||||||
|
AddBoolValue(cfg, '-Sc', opt.CStyleOperators, list, other);
|
||||||
|
|
||||||
|
AddBoolValue(cfg, '-Sa', opt.IncludeAssertionCode, list, other);
|
||||||
|
AddBoolValue(cfg, '-Sg', opt.AllowLabel, list, other);
|
||||||
|
AddBoolValue(cfg, '-Sh', opt.UseAnsiStrings, list, other);
|
||||||
|
AddBoolValue(cfg, '-Si', opt.CPPInline, list, other);
|
||||||
|
AddBoolValue(cfg, '-Sm', opt.CStyleMacros, list, other);
|
||||||
|
AddBoolValue(cfg, '-Ss', opt.InitConstructor, list, other);
|
||||||
|
|
||||||
|
// -St is obsolete option ... so shouldn't be available
|
||||||
|
AddBoolValue(cfg, '-St', opt.StaticKeyword, list, other);
|
||||||
|
|
||||||
|
// code generation:
|
||||||
|
AddBoolValue(cfg, '-Ci', opt.IOChecks, list, other);
|
||||||
|
AddBoolValue(cfg, '-Cr', opt.RangeChecks, list, other);
|
||||||
|
AddBoolValue(cfg, '-Co', opt.OverflowChecks, list, other);
|
||||||
|
AddBoolValue(cfg, '-Ct', opt.StackChecks, list, other);
|
||||||
|
AddBoolValue(cfg, '-CX', opt.SmartLinkUnit, list, other);
|
||||||
|
AddBoolValue(cfg, '-WR', opt.RelocatableUnit, list, other);
|
||||||
|
AddBoolValue(cfg, '-Ce', opt.EmulatedFloatOpcodes, list, other);
|
||||||
|
|
||||||
|
AddIntValue(cfg, '-Ch', opt.HeapSize, list, other);
|
||||||
|
AddIntValue(cfg, '-Cs', opt.StackSize, list, other);
|
||||||
|
AddBoolValue(cfg, '-CR', opt.VerifyObjMethodCall, list, other);
|
||||||
|
|
||||||
|
AddBoolValue(cfg, '-CR', opt.SmallerCode, list, other);
|
||||||
|
AddStrValue(cfg, '-P', opt.TargetCPU, list, other);
|
||||||
|
AddStrValue(cfg, '-Op', opt.TargetProcessor, list, other);
|
||||||
|
AddStrValue(cfg, '-T', opt.TargetOS, list, other);
|
||||||
|
AddBoolValue(cfg, '-Or', opt.VariablesInRegisters, list, other);
|
||||||
|
AddBoolValue(cfg, '-Ou', opt.UncertainOptimizations, list, other);
|
||||||
|
AddStrValue(cfg, '-O', IntToStr(opt.OptimizationLevel), list, other);
|
||||||
|
|
||||||
|
// linking:
|
||||||
|
AddBoolValue(cfg, '-g', opt.GenerateDebugInfo, list, other);
|
||||||
|
|
||||||
|
//todo: EPIC TODO
|
||||||
|
//AddStrValue(cfg, '-g', opt.DebugInfoType, list, other);
|
||||||
|
//opt.DebugInfoTypeStr: String read GetDebugInfoTypeStr;
|
||||||
|
|
||||||
|
AddBoolValue(cfg, '-gl', opt.UseLineInfoUnit, list, other);
|
||||||
|
AddBoolValue(cfg, '-gh', opt.UseHeaptrc, list, other);
|
||||||
|
AddBoolValue(cfg, '-gv', opt.UseValgrind, list, other);
|
||||||
|
AddBoolValue(cfg, '-pg', opt.GenGProfCode, list, other);
|
||||||
|
AddBoolValue(cfg, '-Xs', opt.StripSymbols, list, other);
|
||||||
|
AddBoolValue(cfg, '-XX', opt.LinkSmart, list, other);
|
||||||
|
|
||||||
|
AddMultiStrValue(cfg, '-k', opt.LinkerOptions, ' ', list, other);
|
||||||
|
{opt.LinkerOptions:=LookupStr(lookup, '-k');
|
||||||
|
opt.PassLinkerOptions:=opt.LinkerOptions<>''; //todo:!}
|
||||||
|
|
||||||
|
AddBoolValue(cfg, '-WG', opt.Win32GraphicApp, list, other);
|
||||||
|
//ExecutableType: TCompilationExecutableType read FExecutableType write SetExecutableType;
|
||||||
|
AddBoolValue(cfg, '-Xg', opt.UseExternalDbgSyms, list, other);
|
||||||
|
|
||||||
|
// messages:
|
||||||
|
AddBoolValue(cfg, '-ve', opt.ShowErrors, list, other);
|
||||||
|
AddBoolValue(cfg, '-vw', opt.ShowWarn, list, other);
|
||||||
|
AddBoolValue(cfg, '-vn', opt.ShowNotes, list, other);
|
||||||
|
AddBoolValue(cfg, '-vh', opt.ShowHints, list, other);
|
||||||
|
AddBoolValue(cfg, '-vi', opt.ShowGenInfo, list, other);
|
||||||
|
AddBoolValue(cfg, '-vl', opt.ShowLineNum, list, other);
|
||||||
|
AddBoolValue(cfg, '-va', opt.ShowAll, list, other);
|
||||||
|
AddBoolValue(cfg, '-Xs', opt.ShowAllProcsOnError, list, other);
|
||||||
|
|
||||||
|
AddBoolValue(cfg, '-vd', opt.ShowDebugInfo, list, other);
|
||||||
|
AddBoolValue(cfg, '-vu', opt.ShowUsedFiles, list, other);
|
||||||
|
AddBoolValue(cfg, '-vt', opt.ShowTriedFiles, list, other);
|
||||||
|
AddBoolValue(cfg, '-vp', opt.ShowCompProc, list, other);
|
||||||
|
AddBoolValue(cfg, '-vc', opt.ShowCond, list, other);
|
||||||
|
AddBoolValue(cfg, '-vx', opt.ShowExecInfo, list, other);
|
||||||
|
AddBoolValue(cfg, '-v0', opt.ShowNothing, list, other);
|
||||||
|
//opt.ShowSummary
|
||||||
|
//opt.ShowHintsForUnusedUnitsInMainSrc
|
||||||
|
//opt.ShowHintsForSenderNotUsed
|
||||||
|
AddBoolValue(cfg, '-l' , opt.WriteFPCLogo, list, other);
|
||||||
|
AddIntValue(cfg, '-Se', opt.StopAfterErrCount, list, other);
|
||||||
|
|
||||||
|
// other
|
||||||
|
AddBoolValue(cfg, '-n', opt.DontUseConfigFile, list, other);
|
||||||
|
CmdLineMatchArgsToOpts(cfg, opt.CustomOptions, list);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
398
components/cmdlinecfg/trunk/cmdlinelclctrlsbox.pas
Normal file
398
components/cmdlinecfg/trunk/cmdlinelclctrlsbox.pas
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
unit cmdlinelclctrlsbox;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, Controls, Forms, StdCtrls, Graphics
|
||||||
|
, cmdlinecfg, cmdlinecfgutils, cmdlinelclutils, cmdlinecfgui
|
||||||
|
, contnrs
|
||||||
|
, cmdlinefpccond;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TControlInfo }
|
||||||
|
|
||||||
|
TControlInfo = class(TObject)
|
||||||
|
public
|
||||||
|
check : TFPCConditionCheck;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
ctrl : TControl;
|
||||||
|
constructor Create(aopt: TCmdLineCfgOption; actrl: TControl);
|
||||||
|
destructor Destroy; override;
|
||||||
|
function isAllowed(const cpu, os: string): Boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineScrollBoxControl }
|
||||||
|
|
||||||
|
TCmdLineScrollBoxControl = class(TCmdLineUIControl)
|
||||||
|
private
|
||||||
|
fScrollBox : TScrollBox;
|
||||||
|
fCfg : TCmdLineCfg;
|
||||||
|
fControls : TList;
|
||||||
|
fOptToCtrl : TFPHashObjectList;
|
||||||
|
protected
|
||||||
|
flayout: TCmdLineLayoutInfo;
|
||||||
|
fusedoptlist: TStringList;
|
||||||
|
procedure OnChange(Sender: TObject);
|
||||||
|
procedure OnCndChange(Sender: TObject);
|
||||||
|
procedure RevaluateConditions;
|
||||||
|
function AllocControls(AParent: TWinControl; VOffset: Integer; listofopt: TList): Integer;
|
||||||
|
function AllocHeaderLabel(AParent: TWinControl; VOffset: Integer; const Caption: String): Integer;
|
||||||
|
function AllocForSection(AParent: TWinControl; VOffset: Integer; sct : TLayoutSection; SkipHeader: Boolean = false): Integer;
|
||||||
|
procedure Reset;
|
||||||
|
public
|
||||||
|
constructor Create(AParent: TWinControl);
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo); override;
|
||||||
|
procedure SetValues(list: TList {of TCmdLineOptionValue}); override;
|
||||||
|
procedure Serialize(list: TList {of TCmdLineOptionValue}); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ReleaseScrollBox(box: TCmdLineScrollBoxControl);
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure ReleaseScrollBox(box: TCmdLineScrollBoxControl);
|
||||||
|
begin
|
||||||
|
if not Assigned(box) then Exit;
|
||||||
|
box.fScrollBox.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TControlInfo }
|
||||||
|
|
||||||
|
constructor TControlInfo.Create(aopt: TCmdLineCfgOption; actrl: TControl);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
ctrl:=actrl;
|
||||||
|
opt:=aopt;
|
||||||
|
if aopt.Condition<>'' then
|
||||||
|
check := TFPCConditionCheck.Create(aopt.Condition)
|
||||||
|
else
|
||||||
|
check:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TControlInfo.Destroy;
|
||||||
|
begin
|
||||||
|
check.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TControlInfo.isAllowed(const cpu, os: string): Boolean;
|
||||||
|
begin
|
||||||
|
Result:=(not Assigned(check)) or (check.isValid(cpu, os));
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCmdLineScrollBoxControl }
|
||||||
|
|
||||||
|
procedure TCmdLineScrollBoxControl.OnChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
ValueChanged;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineScrollBoxControl.OnCndChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
OnChange(Sender);
|
||||||
|
RevaluateConditions;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineScrollBoxControl.RevaluateConditions;
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
cpu : string;
|
||||||
|
os : string;
|
||||||
|
ci : TControlInfo;
|
||||||
|
begin
|
||||||
|
ci:=TControlInfo(fOptToCtrl.Find('-P'));
|
||||||
|
if Assigned(ci) then SerializeAControl(ci.opt, ci.ctrl, cpu)
|
||||||
|
else cpu:='';
|
||||||
|
ci:=TControlInfo(fOptToCtrl.Find('-T'));
|
||||||
|
if Assigned(ci) then SerializeAControl(ci.opt, ci.ctrl, os)
|
||||||
|
else os:='';
|
||||||
|
|
||||||
|
for i:=0 to fOptToCtrl.Count-1 do begin
|
||||||
|
ci:=TControlInfo(fOptToCtrl.Items[i]);
|
||||||
|
if (ci.opt.Name='-P') or (ci.opt.Name='-T') then Continue;
|
||||||
|
if Assigned(ci.check) then begin
|
||||||
|
ci.ctrl.Enabled:=ci.isAllowed(cpu, os);
|
||||||
|
end;
|
||||||
|
//todo: values availability
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCmdLineScrollBoxControl.AllocControls(AParent: TWinControl;
|
||||||
|
VOffset: Integer; listofopt: TList): Integer;
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
y : Integer;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
chk : TCheckBox;
|
||||||
|
dd : TComboBox;
|
||||||
|
YOffset : Integer;
|
||||||
|
XOffset : Integer;
|
||||||
|
lbl : TLabel;
|
||||||
|
mctrl : TControl;
|
||||||
|
edt : TEdit;
|
||||||
|
begin
|
||||||
|
y:=VOffset;
|
||||||
|
YOffset:=0; //todo: get from the widgetset
|
||||||
|
XOffset:=10;
|
||||||
|
|
||||||
|
for i:=0 to listofopt.Count-1 do begin
|
||||||
|
mctrl:=nil;
|
||||||
|
opt:=TCmdLineCfgOption(listofopt[i]);
|
||||||
|
if opt.AliasToKey <>'' then Continue;
|
||||||
|
|
||||||
|
if opt.ValCount>0 then begin
|
||||||
|
CreateComboBoxWithLabel(opt, APArent, dd, lbl);
|
||||||
|
lbl.Left:=XOffset;
|
||||||
|
lbl.Top:=y;
|
||||||
|
dd.Style:=csDropDownList;
|
||||||
|
dd.Top:=y;
|
||||||
|
dd.Left:=lbl.Width;
|
||||||
|
//todo: hardcoded key names :(
|
||||||
|
if (opt.Name='-P') or (opt.Name='-T') then
|
||||||
|
dd.OnSelect:=OnCndChange
|
||||||
|
else
|
||||||
|
dd.OnSelect:=OnChange;
|
||||||
|
ControlSpanToRight(dd);
|
||||||
|
AnchorControls(lbl, dd);
|
||||||
|
mctrl:=dd;
|
||||||
|
inc(y, dd.Height);
|
||||||
|
end else if opt.OptType='switch' then begin
|
||||||
|
CreateCheckBox(opt, AParent, true, chk);
|
||||||
|
chk.Top:=y;
|
||||||
|
chk.Left:=XOffset;
|
||||||
|
chk.OnClick:=OnChange;
|
||||||
|
mctrl:=chk;
|
||||||
|
inc(y, chk.Height + YOffset);
|
||||||
|
end else begin
|
||||||
|
CreateEdit(opt, AParent, lbl, edt);
|
||||||
|
edt.Top:=y;
|
||||||
|
lbl.Top:=y;
|
||||||
|
lbl.Left:=XOffset;
|
||||||
|
mctrl:=edt;
|
||||||
|
edt.OnEditingDone:=OnChange;
|
||||||
|
AnchorControls(lbl, edt);
|
||||||
|
ControlSpanToRight(edt);
|
||||||
|
inc(y, edt.Height + YOffset);
|
||||||
|
end;
|
||||||
|
if Assigned(mctrl) then begin
|
||||||
|
mctrl.Tag:=PtrUInt(opt);
|
||||||
|
fControls.Add(mctrl);
|
||||||
|
fOptToCtrl.Add( opt.Name, TControlInfo.Create(opt, mctrl) );
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:=y;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCmdLineScrollBoxControl.AllocHeaderLabel(AParent: TWinControl;
|
||||||
|
VOffset: Integer; const Caption: String): Integer;
|
||||||
|
var
|
||||||
|
lbl : TLabel;
|
||||||
|
begin
|
||||||
|
inc(VOffset, 10);//todo: this information should come from a widgetset
|
||||||
|
lbl:=TLabel.Create(APArent);
|
||||||
|
lbl.Caption:=Caption;
|
||||||
|
lbl.Parent:=AParent;
|
||||||
|
lbl.Top:=VOffset;
|
||||||
|
lbl.Left:=0;
|
||||||
|
lbl.Width:=AParent.ClientWidth;
|
||||||
|
lbl.Anchors:=lbl.Anchors+[akRight];
|
||||||
|
lbl.Alignment:=taCenter;
|
||||||
|
inc(VOffset, lbl.Height);
|
||||||
|
Result:=VOffset;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCmdLineScrollBoxControl.AllocForSection(AParent: TWinControl; VOffset: Integer; sct : TLayoutSection; SkipHeader: Boolean ): Integer;
|
||||||
|
var
|
||||||
|
ls : TLayoutSection;
|
||||||
|
sw : TStringList;
|
||||||
|
y : Integer;
|
||||||
|
l : TList;
|
||||||
|
j : Integer;
|
||||||
|
k : Integer;
|
||||||
|
box : TGroupBox;
|
||||||
|
by : integer;
|
||||||
|
begin
|
||||||
|
if not Assigned(sct) then begin
|
||||||
|
Result:=VOffset;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
y:=VOffset;
|
||||||
|
sw:=TStringList.Create;
|
||||||
|
l:=TList.Create;
|
||||||
|
try
|
||||||
|
if (sct.Name<>'') and not SkipHeader then
|
||||||
|
y:=AllocHeaderLabel(APArent, y, sct.Display);
|
||||||
|
|
||||||
|
for j:=0 to sct.ElemCount-1 do begin
|
||||||
|
ls:=sct.Elements[j];
|
||||||
|
if ls.ElementType=letSection then begin
|
||||||
|
if l.Count>0 then begin
|
||||||
|
y:=AllocControls(AParent, y, l);
|
||||||
|
l.Clear;
|
||||||
|
end;
|
||||||
|
if ls.GUIHint='groupbox' then begin
|
||||||
|
box := TGroupBox.Create(AParent);
|
||||||
|
box.Parent:=AParent;
|
||||||
|
box.Caption:=ls.Display;
|
||||||
|
box.Width:=AParent.Width-10;
|
||||||
|
box.Anchors:=box.Anchors+[akRight];
|
||||||
|
by:=AllocForSection(box, 0, ls, true);
|
||||||
|
box.Height:=by+22; //todo: define the border size by widgetset
|
||||||
|
box.Top:=y;
|
||||||
|
inc(y, box.Height);
|
||||||
|
end else
|
||||||
|
y:=AllocForSection(AParent, y, ls );
|
||||||
|
end else begin
|
||||||
|
k:=fusedoptlist.IndexOf(ls.Name);
|
||||||
|
if (k>=0) then begin
|
||||||
|
l.Add( fusedoptlist.Objects[k] );
|
||||||
|
fusedoptlist.Delete(k);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if l.Count>0 then y:=AllocControls(AParent, y, l);
|
||||||
|
finally
|
||||||
|
sw.Free;
|
||||||
|
l.Free;
|
||||||
|
Result:=y;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineScrollBoxControl.Reset;
|
||||||
|
var
|
||||||
|
i :Integer;
|
||||||
|
begin
|
||||||
|
for i:=0 to fControls.Count-1 do
|
||||||
|
ResetValue(fControls[i]);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TCmdLineScrollBoxControl.Create(AParent: TWinControl);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
fScrollBox := TScrollBox.Create(AParent);
|
||||||
|
fScrollBox.Align:=alClient;
|
||||||
|
fScrollBox.Parent:=AParent;
|
||||||
|
fScrollBox.VertScrollBar.Tracking:=true;
|
||||||
|
fControls:=TList.Create;
|
||||||
|
fOptToCtrl:=TFPHashObjectList.Create(true);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TCmdLineScrollBoxControl.Destroy;
|
||||||
|
begin
|
||||||
|
// fill not free fScrollBox as it should be destroyed by the parent
|
||||||
|
fOptToCtrl.Free;
|
||||||
|
fControls.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineScrollBoxControl.Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo);
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
list : TStringList;
|
||||||
|
l : TList;
|
||||||
|
nm : string;
|
||||||
|
y : Integer;
|
||||||
|
begin
|
||||||
|
if not Assigned(cfg) then Exit;
|
||||||
|
fCfg:=cfg;
|
||||||
|
list:=TStringList.Create;
|
||||||
|
list.CaseSensitive:=true; // must be case sensitive
|
||||||
|
l:=TList.Create;
|
||||||
|
fOptToCtrl.Clear;
|
||||||
|
fusedoptlist:=list;
|
||||||
|
flayout:=layout;
|
||||||
|
try
|
||||||
|
y:=24;
|
||||||
|
for i:=0 to cfg.Options.Count-1 do begin
|
||||||
|
opt:=TCmdLineCfgOption(cfg.Options[i]);
|
||||||
|
nm:=opt.Name;
|
||||||
|
if nm='' then nm:=opt.Key;
|
||||||
|
list.AddObject(nm, cfg.Options[i]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Assigned(layout) then y:=AllocForSection(fScrollBox, y, layout.GetSection(''));
|
||||||
|
if Assigned(layout) then begin
|
||||||
|
y:=AllocHeaderLabel(fScrollBox, y, 'Other');
|
||||||
|
end;
|
||||||
|
l.Clear;
|
||||||
|
for i:=0 to list.Count-1 do
|
||||||
|
l.Add(list.Objects[i]);
|
||||||
|
AllocControls(fScrollBox, y, l);
|
||||||
|
finally
|
||||||
|
fusedoptlist:=nil;
|
||||||
|
flayout:=nil;
|
||||||
|
l.Free;
|
||||||
|
list.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineScrollBoxControl.SetValues(list: TList);
|
||||||
|
var
|
||||||
|
vl : TCmdLineOptionValue;
|
||||||
|
ctrl : TControl;
|
||||||
|
i : Integer;
|
||||||
|
mlt : TFPHashList;
|
||||||
|
isPath : Boolean;
|
||||||
|
const
|
||||||
|
Delims : array [Boolean] of string = (' ', ';');
|
||||||
|
begin
|
||||||
|
if not Assigned(fCfg) or not Assigned(list) then Exit;
|
||||||
|
Reset;
|
||||||
|
mlt:=TFPHashList.Create;
|
||||||
|
try
|
||||||
|
for i:=0 to list.Count-1 do begin
|
||||||
|
vl:=TCmdLineOptionValue(list[i]);
|
||||||
|
if not Assigned(vl.Option) then Continue;
|
||||||
|
ctrl:=TControlInfo(fOptToCtrl.Find(vl.Option.Name)).ctrl;
|
||||||
|
if not Assigned(ctrl) then Continue;
|
||||||
|
if ctrl is TComboBox then SetValueComboBox(vl.Option, vl.Value, TComboBoX(ctrl))
|
||||||
|
else if ctrl is TCheckBox then SetValueCheckBox(vl.Option, vl.Value, TCheckBox(ctrl))
|
||||||
|
else if ctrl is TEdit and not vl.Option.isMultiple then SetValueEdit(vl.Option, vl.Value, TEdit(ctrl))
|
||||||
|
else if ctrl is TEdit and vl.Option.isMultiple then begin
|
||||||
|
if mlt.FindIndexOf(vl.Option.Name) <0 then begin
|
||||||
|
TEdit(ctrl).Text:='';
|
||||||
|
mlt.Add(vl.Option.Name, ctrl);
|
||||||
|
end;
|
||||||
|
isPath:=(vl.Option.OptType='dirpath') or (vl.Option.OptType='filepath');
|
||||||
|
SetMultiValueEdit(vl.Option, vl.Value, Delims[isPath], TEdit(ctrl));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
mlt.Free;
|
||||||
|
end;
|
||||||
|
RevaluateConditions;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineScrollBoxControl.Serialize(list: TList);
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
vl : TCmdLineOptionValue;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
ctrl : TControl;
|
||||||
|
v : string;
|
||||||
|
dlm : char;
|
||||||
|
begin
|
||||||
|
if not Assigned(fCfg) then Exit;
|
||||||
|
for i:=0 to fControls.Count-1 do begin
|
||||||
|
ctrl:=TControl(fControls[i]);
|
||||||
|
opt:=TCmdLineCfgOption(ctrl.Tag);
|
||||||
|
if not Assigned(opt) then Continue;
|
||||||
|
if SerializeAControl(opt, ctrl, v) then begin
|
||||||
|
if opt.isMultiple then begin
|
||||||
|
if (opt.OptType = 'filepath') or (opt.OptType='dirpath') then dlm:=';' else dlm:=' ';
|
||||||
|
CmdLineAllocMultiValues(opt, v, dlm, list);
|
||||||
|
end else
|
||||||
|
list.Add( TCmdLineOptionValue.Create(opt, v));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
233
components/cmdlinecfg/trunk/cmdlinelclpropgrid.pas
Normal file
233
components/cmdlinecfg/trunk/cmdlinelclpropgrid.pas
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
unit cmdlinelclpropgrid;
|
||||||
|
|
||||||
|
//todo: this unit is incomplete
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, Controls, ValEdit, StdCtrls
|
||||||
|
, cmdlinecfg, cmdlinecfgui;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TCmdLineGridControl }
|
||||||
|
|
||||||
|
TCmdLineGridControl = class(TCmdLineUIControl)
|
||||||
|
private
|
||||||
|
fPropGrid : TValueListEditor;
|
||||||
|
fCfg : TCmdLineCfg;
|
||||||
|
fDropdown : TComboBox;
|
||||||
|
fEditCol,fEditRow: Integer;
|
||||||
|
public
|
||||||
|
procedure OnSelectEditor(Sender: TObject; aCol, aRow: Integer; var Editor: TWinControl);
|
||||||
|
procedure OnHeaderSizing(sender: TObject; const IsColumn: boolean;
|
||||||
|
const aIndex, aSize: Integer) ;
|
||||||
|
procedure OnEditingDone(Sender: TObject);
|
||||||
|
procedure OnDDKeyPress(Sender: TObject; var Key: char);
|
||||||
|
procedure OnDDSelect(Sender: TObject);
|
||||||
|
procedure OnExit(Sender: TObject);
|
||||||
|
procedure OnCanSelect(Sender: TObject; aCol, aRow: Integer; var CanSelect: Boolean);
|
||||||
|
procedure OnTopLeftChanged(Sender: TObject);
|
||||||
|
|
||||||
|
procedure UpdateEditorBounds;
|
||||||
|
procedure UpdateValue(aCol, arow: Integer; const newval: string; NotifyChange: Boolean = true);
|
||||||
|
public
|
||||||
|
constructor Create(AParent: TWinControl);
|
||||||
|
procedure Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo); override;
|
||||||
|
procedure SetValues(list: TList {of TCmdLineOptionValue}); override;
|
||||||
|
procedure Serialize(list: TList {of TCmdLineOptionValue}); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{ TCmdLineGridControl }
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.OnSelectEditor(Sender: TObject; aCol,
|
||||||
|
aRow: Integer; var Editor: TWinControl);
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
dd : TComboBox;
|
||||||
|
j : integer;
|
||||||
|
nm : string;
|
||||||
|
begin
|
||||||
|
if not Assigned(fCfg) then Exit;
|
||||||
|
|
||||||
|
i:=aRow-1;
|
||||||
|
if (i<0) or (i>=fCfg.Options.Count) then Exit;
|
||||||
|
opt:=TCmdLineCfgOption(fPropGrid.Objects[aCol, aRow]);
|
||||||
|
if not Assigned(opt) then Exit;
|
||||||
|
|
||||||
|
fEditCol:=aCol;
|
||||||
|
fEditRow:=aRow;
|
||||||
|
if (opt.OptType='switch') or (opt.ValCount>0) then begin
|
||||||
|
if not Assigned(fDropdown) then begin
|
||||||
|
dd:=TComboBox.Create(fPropGrid);
|
||||||
|
dd.OnSelect:=OnDDSelect;
|
||||||
|
dd.OnKeyPress:=OnDDKeyPress;
|
||||||
|
dd.OnExit:=OnExit;
|
||||||
|
fDropdown:=dd;
|
||||||
|
end else
|
||||||
|
dd:=fDropdown;
|
||||||
|
dd.Style:=csDropDownList;
|
||||||
|
dd.Items.Clear;
|
||||||
|
if opt.OptType='switch' then begin
|
||||||
|
dd.Items.Add('false');
|
||||||
|
dd.Items.Add('true');
|
||||||
|
end else if opt.ValCount>0 then
|
||||||
|
for j:=0 to opt.ValCount-1 do begin
|
||||||
|
nm:=opt.Values[j].DisplayName;
|
||||||
|
if nm='' then nm:=opt.Values[j].CmdLineValue;
|
||||||
|
dd.Items.Add(nm);
|
||||||
|
end;
|
||||||
|
dd.ItemIndex:=dd.Items.IndexOf( fPropGrid.Cells[aCol, aRow]);
|
||||||
|
dd.BoundsRect:=fPropGrid.CellRect(aCol,Arow);
|
||||||
|
Editor:=dd;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.OnEditingDone(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if not Assigned(fCfg) then Exit;
|
||||||
|
if Assigned(fDropdown) and (fDropdown.Visible) then begin
|
||||||
|
fDropdown.Hide;
|
||||||
|
UpdateValue(fEditCol, fEditRow, fDropdown.Text);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.OnDDKeyPress(Sender: TObject; var Key: char);
|
||||||
|
begin
|
||||||
|
if Key=#13 then begin
|
||||||
|
fPropGrid.EditingDone;
|
||||||
|
fDropdown.Hide;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.OnDDSelect(Sender: TObject);
|
||||||
|
begin
|
||||||
|
|
||||||
|
UpdateValue(fEditCol, fEditRow, fDropdown.Text);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.OnExit(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if Assigned(fDropDown) then fDropdown.Hide;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.OnCanSelect(Sender: TObject; aCol, aRow: Integer;
|
||||||
|
var CanSelect: Boolean);
|
||||||
|
begin
|
||||||
|
CanSelect:=aCol>0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.OnTopLeftChanged(Sender: TObject);
|
||||||
|
begin
|
||||||
|
UpdateEditorBounds;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.UpdateEditorBounds;
|
||||||
|
begin
|
||||||
|
if Assigned(fPropGrid.Editor) then begin
|
||||||
|
fPropGrid.Editor.BoundsRect:=fPropGrid.CellRect(fEditCol,fEditRow);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.UpdateValue(aCol, arow: Integer;
|
||||||
|
const newval: string; NotifyChange: Boolean );
|
||||||
|
begin
|
||||||
|
fPropGrid.Cells[aCol, aRow]:=newval;
|
||||||
|
if NotifyChange then ValueChanged;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.OnHeaderSizing(sender: TObject;
|
||||||
|
const IsColumn: boolean; const aIndex, aSize: Integer);
|
||||||
|
begin
|
||||||
|
UpdateEditorBounds;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TCmdLineGridControl.Create(AParent: TWinControl);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
fPropGrid:=TValueListEditor.Create(AParent);
|
||||||
|
fPropGrid.Parent:=AParent;
|
||||||
|
fPropGrid.Align:=alClient;
|
||||||
|
fPropGrid.OnSelectEditor:=Self.OnSelectEditor;
|
||||||
|
fPropGrid.OnHeaderSizing:=OnHeaderSizing;
|
||||||
|
fPropGrid.OnEditingDone:=OnEditingDone;
|
||||||
|
fPropGrid.OnExit:=OnExit;
|
||||||
|
fPropGrid.OnSelectCell:=OnCanSelect;
|
||||||
|
fPropGrid.OnTopLeftChanged:=OnTopLeftChanged;
|
||||||
|
fPropGrid.OnResize:=OnTopLeftChanged;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.Init(cfg: TCmdLineCfg; layout: TCmdLineLayoutInfo);
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
j : integer;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
chk : TCheckBox;
|
||||||
|
cr : TRect;
|
||||||
|
begin
|
||||||
|
// todo: Clean if exists
|
||||||
|
fCfg:=cfg;
|
||||||
|
if Assigned(fcfg) then begin
|
||||||
|
fPropGrid.BeginUpdate;
|
||||||
|
try
|
||||||
|
fPropGrid.RowCount:=cfg.Options.Count+1;
|
||||||
|
j:=1;
|
||||||
|
for i:=0 to cfg.Options.Count-1 do begin
|
||||||
|
opt:=TCmdLineCfgOption(cfg.Options[i]);
|
||||||
|
if opt.AliasToKey <>'' then Continue;
|
||||||
|
fPropGrid.Keys[j]:=opt.Display;
|
||||||
|
fPropGrid.Objects[1, j]:=opt;
|
||||||
|
if opt.OptType='switch' then begin
|
||||||
|
fPropGrid.Values[opt.Display]:='false';
|
||||||
|
end;
|
||||||
|
inc(j);
|
||||||
|
end;
|
||||||
|
fPropGrid.RowCount:=j;
|
||||||
|
finally
|
||||||
|
fPropGrid.EndUpdate;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.SetValues(list: TList);
|
||||||
|
begin
|
||||||
|
if not Assigned(fCfg) then Exit;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCmdLineGridControl.Serialize(list: TList);
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
j : Integer;
|
||||||
|
vl : TCmdLineOptionValue;
|
||||||
|
opt : TCmdLineCfgOption;
|
||||||
|
v : string;
|
||||||
|
begin
|
||||||
|
if not Assigned(fCfg) then Exit;
|
||||||
|
for i:=1 to fPropGrid.RowCount-1 do begin
|
||||||
|
opt:=TCmdLineCfgOption(fPropGrid.Objects[1, i]);
|
||||||
|
if not Assigned(opt) then Continue;
|
||||||
|
vl := TCmdLineOptionValue.Create;
|
||||||
|
if opt.ValCount>0 then begin
|
||||||
|
v:=fPropGrid.Cells[1, i];
|
||||||
|
for j:=0 to opt.ValCount-1 do
|
||||||
|
if ((opt.Values[j].DisplayName <> '') and (opt.Values[j].DisplayName=v)) or (opt.Values[j].CmdLineValue=v) then begin
|
||||||
|
vl.Value:=opt.Values[j].CmdLineValue;
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
vl.Value:=fPropGrid.Cells[1, i];
|
||||||
|
vl.Option:=opt;
|
||||||
|
if vl.Option.OptType='switch' then begin
|
||||||
|
if vl.Value='false' then vl.Value:='' else vl.Value:='1';
|
||||||
|
end;
|
||||||
|
list.Add(vl);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
217
components/cmdlinecfg/trunk/cmdlinelclutils.pas
Normal file
217
components/cmdlinecfg/trunk/cmdlinelclutils.pas
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
unit cmdlinelclutils;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses Controls, SysUtils, StdCtrls, Classes, cmdlinecfg;
|
||||||
|
|
||||||
|
var
|
||||||
|
ADirsDialogs : function (var path: string): Boolean = nil;
|
||||||
|
AFilesDialogs : function (var path: string): Boolean = nil;
|
||||||
|
|
||||||
|
procedure CreateComboBoxWithLabel(opt: TCmdLineCfgOption; AOwner: TWinControl; var combo: TComboBox; var lbl: TLabel);
|
||||||
|
procedure CreateComboBox(opt: TCmdLineCfgOption; AOwner: TWinControl; var combo: TComboBox);
|
||||||
|
procedure CreateCheckBox(opt: TCmdLineCfgOption; AOwner: TWinControl; SetCaptionToDisplay: Boolean; var chk: TCheckBox);
|
||||||
|
procedure AnchorControls(left, right: TControl; Spacing: Integer = 10);
|
||||||
|
procedure ControlSpanToRight(ctrl: TControl; XOffset: Integer = 10);
|
||||||
|
function SerializeComboBox(opt: TCmdLineCfgOption; combo: TComboBox): string;
|
||||||
|
function SerializeCheckBox(opt: TCmdLineCfgOption; chk: TCheckBox): string;
|
||||||
|
function SerializeEdit(opt: TCmdLineCfgOption; edt: TEdit): string;
|
||||||
|
procedure SetValueComboBox(opt: TCmdLineCfgOption; const vl: string; combo: TComboBox);
|
||||||
|
procedure SetValueCheckBox(opt: TCmdLineCfgOption; const vl: string; chk: TCheckBox);
|
||||||
|
procedure SetValueEdit(opt: TCmdLineCfgOption; const vl: string; edt: TEdit);
|
||||||
|
procedure SetMultiValueEdit(opt: TCmdLineCfgOption; const vl: string; const Delim: string; edt: TEdit);
|
||||||
|
|
||||||
|
procedure ResetValue(ctrl: TControl);
|
||||||
|
function SerializeAControl(opt: TCmdLineCfgOption; ctrl: TControl; var v: string): Boolean;
|
||||||
|
|
||||||
|
type
|
||||||
|
TEditPathsOpt = (epoSingleFileOnly, epoSingleDirOnly, epoFilesOnly, epoDirsOnly);
|
||||||
|
|
||||||
|
function ExecuteEditPathsDialogs(var path: string; DialogOption: TEditPathsOpt ): Boolean;
|
||||||
|
procedure CreatePathsEdit(opt: TCmdLineCfgOption; AOwner: TWinControl;
|
||||||
|
var lbl: TLabel; var edit: TEdit; var lookupbtn: TButton);
|
||||||
|
procedure CreateEdit(opt: TCmdLineCfgOption; AOwner: TWinControl; var lbl: TLabel; var edit: TEdit);
|
||||||
|
|
||||||
|
function OptKeyLabel(opt: TCmdLineCfgOption): string;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function OptKeyLabel(opt: TCmdLineCfgOption): string;
|
||||||
|
begin
|
||||||
|
if not Assigned(opt) then Result:=''
|
||||||
|
else Result:='('+StringReplace(opt.key, '%value%','', [rfIgnoreCase, rfReplaceAll])+')';
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AnchorControls(left, right: TControl; Spacing: Integer);
|
||||||
|
begin
|
||||||
|
right.AnchorSideLeft.Control:=left;
|
||||||
|
right.AnchorSideLeft.Side:=asrRight;
|
||||||
|
right.BorderSpacing.Left:=Spacing;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SerializeEdit(opt: TCmdLineCfgOption; edt: TEdit): string;
|
||||||
|
begin
|
||||||
|
Result:=edt.Text;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SetValueComboBox(opt: TCmdLineCfgOption; const vl: string; combo: TComboBox);
|
||||||
|
var
|
||||||
|
j : Integer;
|
||||||
|
begin
|
||||||
|
if vl='' then begin
|
||||||
|
combo.ItemIndex:=-1;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
for j:=0 to opt.ValCount-1 do begin
|
||||||
|
if (opt.Values[j].CmdLineValue =vl) then begin
|
||||||
|
if j<=combo.Items.Count then begin
|
||||||
|
combo.ItemIndex:=j;
|
||||||
|
end;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SetValueCheckBox(opt: TCmdLineCfgOption; const vl: string; chk: TCheckBox);
|
||||||
|
begin
|
||||||
|
chk.Checked:=vl<>'';
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SetValueEdit(opt: TCmdLineCfgOption; const vl: string; edt: TEdit);
|
||||||
|
begin
|
||||||
|
edt.Text:=vl;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SetMultiValueEdit(opt: TCmdLineCfgOption; const vl: string;
|
||||||
|
const Delim: string; edt: TEdit);
|
||||||
|
begin
|
||||||
|
if vl<>'' then begin
|
||||||
|
if edt.Text<>'' then edt.Text:=edt.Text+Delim+vl
|
||||||
|
else edt.Text:=vl;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ControlSpanToRight(ctrl: TControl; XOffset: Integer = 10);
|
||||||
|
begin
|
||||||
|
if not Assigned(ctrl) or not Assigned(ctrl.Parent) then Exit;
|
||||||
|
ctrl.Anchors:=ctrl.Anchors-[akRight];
|
||||||
|
ctrl.Width:=ctrl.Parent.ClientWidth-ctrl.Left-XOffset;
|
||||||
|
ctrl.Anchors:=ctrl.Anchors+[akRight];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ExecuteEditPathsDialogs(var path: string; DialogOption: TEditPathsOpt
|
||||||
|
): Boolean;
|
||||||
|
begin
|
||||||
|
case DialogOption of
|
||||||
|
epoSingleFileOnly: begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
epoSingleDirOnly: begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
epoDirsOnly: if not Assigned(ADirsDialogs) then Result:=false
|
||||||
|
else Result:=ADirsDialogs(path);
|
||||||
|
epoFilesOnly: if not Assigned(AFilesDialogs) then Result:=false;
|
||||||
|
else Result:=AFilesDialogs(path);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CreatePathsEdit(opt: TCmdLineCfgOption; AOwner: TWinControl;
|
||||||
|
var lbl: TLabel; var edit: TEdit; var lookupbtn: TButton);
|
||||||
|
begin
|
||||||
|
lbl:=TLabel.Create(AOwner);
|
||||||
|
lbl.Caption:=opt.Display+' '+OptKeyLabel(opt);
|
||||||
|
edit:=TEdit.Create(AOwner);
|
||||||
|
lookupbtn:=TButton.Create(AOwner);
|
||||||
|
lookupbtn.Caption:='...';
|
||||||
|
lookupbtn.AutoSize:=true;
|
||||||
|
AnchorControls(lbl, edit);
|
||||||
|
AnchorControls(edit, lookupbtn);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CreateEdit(opt: TCmdLineCfgOption; AOwner: TWinControl; var lbl: TLabel; var edit: TEdit);
|
||||||
|
begin
|
||||||
|
lbl:=TLabel.Create(AOwner);
|
||||||
|
lbl.Caption:=opt.Display+' '+OptKeyLabel(opt);
|
||||||
|
edit:=TEdit.Create(AOwner);
|
||||||
|
edit.Parent:=AOwner;
|
||||||
|
lbl.Parent:=AOwner;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CreateComboBoxWithLabel(opt: TCmdLineCfgOption; AOwner: TWinControl;
|
||||||
|
var combo: TComboBox; var lbl: TLabel);
|
||||||
|
begin
|
||||||
|
lbl:=TLabel.Create(AOwner);
|
||||||
|
lbl.Caption:=opt.Display + ' '+OptKeyLabel(opt);
|
||||||
|
lbl.Parent:=AOwner;
|
||||||
|
CreateComboBox(opt, AOwner, combo);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CreateComboBox(opt: TCmdLineCfgOption; AOwner: TWinControl; var combo: TComboBox);
|
||||||
|
var
|
||||||
|
dd : TComboBox;
|
||||||
|
j : Integer;
|
||||||
|
nm : string;
|
||||||
|
begin
|
||||||
|
dd:=TComboBox.Create(AOwner);
|
||||||
|
for j:=0 to opt.ValCount-1 do begin
|
||||||
|
nm:=opt.Values[j].DisplayName;
|
||||||
|
if nm='' then nm:=opt.Values[j].CmdLineValue;
|
||||||
|
dd.Items.Add(nm);
|
||||||
|
end;
|
||||||
|
dd.Parent:=AOwner;
|
||||||
|
combo:=dd;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SerializeComboBox(opt: TCmdLineCfgOption; combo: TComboBox): string;
|
||||||
|
var
|
||||||
|
vl : string;
|
||||||
|
j : Integer;
|
||||||
|
begin
|
||||||
|
vl:=combo.Text;
|
||||||
|
Result:='';
|
||||||
|
if vl='' then Exit;
|
||||||
|
for j:=0 to opt.ValCount-1 do
|
||||||
|
if (opt.Values[j].DisplayName='') then begin
|
||||||
|
if (opt.Values[j].CmdLineValue =vl) then begin
|
||||||
|
Result:=vl;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end else if (opt.Values[j].DisplayName=vl) then begin
|
||||||
|
Result:=opt.Values[j].CmdLineValue;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
Result:=vl;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CreateCheckBox(opt: TCmdLineCfgOption; AOwner: TWinControl;
|
||||||
|
SetCaptionToDisplay: Boolean; var chk: TCheckBox);
|
||||||
|
begin
|
||||||
|
chk := TCheckBox.Create(AOwner);
|
||||||
|
if SetCaptionToDisplay then chk.Caption:=opt.Display+' '+ OptKeyLabel(opt);
|
||||||
|
chk.Parent:=AOwner;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SerializeCheckBox(opt: TCmdLineCfgOption; chk: TCheckBox): string;
|
||||||
|
begin
|
||||||
|
if chk.Checked then Result:='1' else Result:='';
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ResetValue(ctrl: TControl);
|
||||||
|
begin
|
||||||
|
if ctrl is TEdit then TEdit(ctrl).Text:=''
|
||||||
|
else if ctrl is TCheckBox then TCheckBox(ctrl).Checked:=false
|
||||||
|
else if ctrl is TComboBox then TComboBox(ctrl).ItemIndex:=-1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function SerializeAControl(opt: TCmdLineCfgOption; ctrl: TControl; var v: string): Boolean;
|
||||||
|
begin
|
||||||
|
v:='';
|
||||||
|
Result:=true;
|
||||||
|
if ctrl is TComboBox then v:=SerializeComboBox(opt, TComboBox(ctrl))
|
||||||
|
else if ctrl is TCheckBox then v:=SerializeCheckBox(opt, TCheckBox(ctrl))
|
||||||
|
else if ctrl is TEdit then v:=SerializeEdit(opt, TEdit(ctrl))
|
||||||
|
else Result:=false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
327
components/cmdlinecfg/trunk/fpc.copt
Normal file
327
components/cmdlinecfg/trunk/fpc.copt
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
{
|
||||||
|
"executable":"fpc",
|
||||||
|
"version":"2.6.0",
|
||||||
|
"testkey":"-iV",
|
||||||
|
"testValue":"2.6.0",
|
||||||
|
"options": [
|
||||||
|
{ "key":"-a", "display":"The compiler doesn't delete the generated assembler file" }
|
||||||
|
,{"key":"-al", "display":"List sourcecode lines in assembler file", "masterkey":"-a"}
|
||||||
|
,{"key":"-an", "display":"List node info in assembler file", "masterkey":"-a" }
|
||||||
|
,{"key":"-ar", "display":"List register allocation/release info in assembler file", "masterkey":"-a"}
|
||||||
|
,{"key":"-at", "display":"List temp allocation/release info in assembler file", "masterkey":"-a"}
|
||||||
|
,{"key":"-A%value%", "display":"Output format:",
|
||||||
|
"options": [
|
||||||
|
{ "value": "default", "display":"Use default assembler" }
|
||||||
|
,{ "value": "as", "display":"Assemble using GNU AS" }
|
||||||
|
,{ "value": "macho", "display":"Mach-O (Darwin, Intel 32 bit) using internal writer" }
|
||||||
|
,{ "value": "nasmcoff", "display":"COFF (Go32v2) file using Nasm" }
|
||||||
|
,{ "value": "nasmelf", "display":"ELF32 (Linux) file using Nasm" }
|
||||||
|
,{ "value": "nasmwin32Win32", "display":"object file using Nasm" }
|
||||||
|
,{ "value": "nasmwdosxWin32/WDOSX", "display":"object file using Nasm" }
|
||||||
|
,{ "value": "wasm", "display":"Obj file using Wasm (Watcom)" }
|
||||||
|
,{ "value": "nasmobj", "display":"Obj file using Nasm" }
|
||||||
|
,{ "value": "masm", "display":"Obj file using Masm (Microsoft)" }
|
||||||
|
,{ "value": "tasm", "display":"Obj file using Tasm (Borland)" }
|
||||||
|
,{ "value": "elf", "display":"ELF (Linux) using internal writer" }
|
||||||
|
,{ "value": "coff", "display":"COFF (Go32v2) using internal writer" }
|
||||||
|
,{ "value": "pecoff", "display":"PE-COFF (Win32) using internal writer" }
|
||||||
|
]}
|
||||||
|
,{ "key":"-b", "display": "Generate browser info" }
|
||||||
|
,{ "key":"-bl", "display": "Generate local symbol info" }
|
||||||
|
,{ "key":"-B", "display": "Build all modules" }
|
||||||
|
,{ "key":"-C3", "display": "Turn on ieee error checking for constants" }
|
||||||
|
,{ "key":"-Ca%value%", "display":"Select ABI, see fpc -i for possible values"
|
||||||
|
,"options": [
|
||||||
|
{"value": "DEFAULT"}
|
||||||
|
,{"value": "SYSV"}
|
||||||
|
,{"value": "AIX"}
|
||||||
|
,{"value": "EABI"}
|
||||||
|
,{"value": "ARMEB"}
|
||||||
|
]}
|
||||||
|
,{ "key":"-Cb", "display":"Generate big-endian code" }
|
||||||
|
,{ "key":"-Cc%value%", "display":"Set default calling convention.", "type":"string" }
|
||||||
|
,{ "key":"-CD", "display":"Create also dynamic library (not supported)" }
|
||||||
|
,{ "key":"-Ce", "display":"Compilation with emulated floating point opcodes" }
|
||||||
|
,{ "key":"-Cf%value%", "display":"Select fpu instruction set to use"
|
||||||
|
,"options": [
|
||||||
|
{"value":"X87"}
|
||||||
|
,{"value":"SSE"}
|
||||||
|
,{"value":"SSE2"}
|
||||||
|
,{"value":"SSE3"}
|
||||||
|
]}
|
||||||
|
,{ "key":"-CF%value%", "display":"Minimal floating point constant precision"
|
||||||
|
,"options": [
|
||||||
|
{"value":"default"}
|
||||||
|
,{"value":"32"}
|
||||||
|
,{"value":"64"}
|
||||||
|
]}
|
||||||
|
,{ "key":"-Cg", "display":"Generate PIC code" }
|
||||||
|
,{ "key":"-Ch%value%", "display":"Bytes heap (between 1023 and 67107840)"
|
||||||
|
, "type":"bytesize" }
|
||||||
|
,{ "key":"-Ci", "display":"IO-checking" }
|
||||||
|
,{ "key":"-Cn", "display":"Omit linking stage" }
|
||||||
|
,{ "key":"-Co", "display":"Check overflow of integer operations" }
|
||||||
|
,{ "key":"-CO", "display":"Check for possible overflow of integer operations" }
|
||||||
|
,{ "key":"-Cp%value%", "display":"Select instruction set"
|
||||||
|
,"options": [
|
||||||
|
{"value":"386"}
|
||||||
|
,{"value":"PENTIUM"}
|
||||||
|
,{"value":"PENTIUM2"}
|
||||||
|
,{"value":"PENTIUM3"}
|
||||||
|
,{"value":"PENTIUM4"}
|
||||||
|
,{"value":"PENTIUMM"}
|
||||||
|
]}
|
||||||
|
,{ "key":"-CPPACKSET=%value%", "display":"Packing of sets"
|
||||||
|
,"options": [
|
||||||
|
{"value":"0"}
|
||||||
|
,{"value":"1"}
|
||||||
|
,{"value":"DEFAULT"}
|
||||||
|
,{"value":"NORMAL"}
|
||||||
|
,{"value":"2"}
|
||||||
|
,{"value":"4"}
|
||||||
|
,{"value":"8"}
|
||||||
|
]}
|
||||||
|
,{ "key":"-Cr", "display":"Range checking" }
|
||||||
|
,{ "key":"-CR", "display":"Verify object method call validity" }
|
||||||
|
,{ "key":"-Cs%value%", "display":"Set stack checking size", "type":"bytesize" }
|
||||||
|
,{ "key":"-Ct", "display":"Stack checking (for testing only, see manual)" }
|
||||||
|
,{ "key":"-CX", "display":"Create also smartlinked library" }
|
||||||
|
,{ "key":"-d%value%", "display":"Defines the symbol <x>", "multiple":true, type:"string" }
|
||||||
|
,{ "key":"-D", "display":"Generate a DEF file" }
|
||||||
|
,{ "key":"-Dd%value%", "display":"Set description", "type":"string" }
|
||||||
|
,{ "key":"-Dv%value%", "display":"Set DLL version", "type":"string" }
|
||||||
|
,{ "key":"-e%value%", "display":"Set path to executable", "type":"filepath" }
|
||||||
|
,{ "key":"-E", "alias":"-E" }
|
||||||
|
,{ "key":"-fPIC", "alias":"-Cg" }
|
||||||
|
|
||||||
|
,{ "key":"-Fa%value%", "display":"(for a program) load units <x> and [y] before uses is parsed", "type": "string", "multiple": true }
|
||||||
|
,{ "key":"-Fc%value%", "display":"Set input codepage to <x>", type:"string"}
|
||||||
|
,{ "key":"-FC%value%", "display":"Set RC compiler binary name to <x>", type:"string" }
|
||||||
|
,{ "key":"-Fd", "display":"Disable the compiler's internal directory cache" }
|
||||||
|
,{ "key":"-FD%value%", "display":"Set the directory where to search for compiler utilities", type:"dirpath", "multiple": true }
|
||||||
|
,{ "key":"-Fe%value%", "display":"Redirect error output to <x>", type:"filepath" }
|
||||||
|
,{ "key":"-Ff%value%", "display":"Add <x> to framework path", type:"string", "multiple": true
|
||||||
|
,"condition":"darwin" }
|
||||||
|
,{ "key":"-FE%value%", "display":"Set exe/unit output path to <x>", type: "dirpath" }
|
||||||
|
,{ "key":"-Fi%value%", "display":"Add <x> to include path", type: "dirpath", "multiple": true }
|
||||||
|
,{ "key":"-Fl%value%", "display":"Add <x> to library path", type: "dirpath", "multiple": true }
|
||||||
|
,{ "key":"-FL%value%", "display":"Use <x> as dynamic linker", type: "string" }
|
||||||
|
,{ "key":"-Fm%value%", "display":"Load unicode conversion table from <x>.txt in the compiler dir", type: "filepath" }
|
||||||
|
,{ "key":"-Fo%value%", "display":"Add <x> to object path", type: "dirpath", "multiple": true }
|
||||||
|
,{ "key":"-Fr%value%", "display":"Load error message file <x>", type: "filepath" }
|
||||||
|
,{ "key":"-FR%value%", "display":"Set resource (.res) linker to <x>", type: "filepath" }
|
||||||
|
,{ "key":"-Fu%value%", "display":"Add <x> to unit path", type: "dirpath", "multiple": true }
|
||||||
|
,{ "key":"-FU%value%", "display":"Set unit output path to <x>", type: "dirpath" }
|
||||||
|
,{ "key":"-FW%value%", "display":"Store generated whole-program optimization feedback in <x>", type: "filepath" }
|
||||||
|
,{ "key":"-Fw%value%", "display":"Load previously stored whole-program optimization feedback from <x>", type: "filepath" }
|
||||||
|
|
||||||
|
,{ "key":"-g", "display":"Generate debug information (default format for target)" }
|
||||||
|
,{ "key":"-gc", "display":"Generate checks for pointers" }
|
||||||
|
,{ "key":"-gh", "display":"Use heaptrace unit (for memory leak/corruption debugging)" }
|
||||||
|
,{ "key":"-gl", "display":"Use line info unit (show more info with backtraces)" }
|
||||||
|
,{ "key":"-godwarfsets", "display":"Enable DWARF 'set' type debug information (breaks gdb < 6.5)" }
|
||||||
|
,{ "key":"-gostabsabsincludes", "display":"Store absolute/full include file paths in Stabs" }
|
||||||
|
,{ "key":"-godwarfmethodclassprefix", "display":"Prefix method names in DWARF with class name" }
|
||||||
|
,{ "key":"-gp", "display":"Preserve case in stabs symbol names" }
|
||||||
|
,{ "key":"-gs", "display":"Generate Stabs debug information" }
|
||||||
|
,{ "key":"-gt", "display":"Trash local variables (to detect uninitialized uses)" }
|
||||||
|
,{ "key":"-gv", "display":"Generates programs traceable with Valgrind" }
|
||||||
|
,{ "key":"-gw", "alias":"-gw2" }
|
||||||
|
,{ "key":"-gw2", "display":"Generate DWARFv2 debug information" }
|
||||||
|
,{ "key":"-gw3", "display":"Generate DWARFv3 debug information" }
|
||||||
|
,{ "key":"-gw4", "display":"Generate DWARFv4 debug information (experimental)" }
|
||||||
|
,{ "key":"-I%value%", "display":"Add <x> to include path", "type":"dirpath", "multiple":true }
|
||||||
|
,{ "key":"-k%value%", "display":"Pass <x> to the linker", "type":"string", "multiple":true }
|
||||||
|
,{ "key":"-M%value%", "display":"Set language mode to <x>"
|
||||||
|
,"options": [
|
||||||
|
{ "value":"fpc", "display":"Free Pascal dialect (default)" }
|
||||||
|
,{ "value":"objfpc", "display":"FPC mode with Object Pascal support" }
|
||||||
|
,{ "value":"delphi", "display":"Delphi 7 compatibility mode" }
|
||||||
|
,{ "value":"tp", "display":"TP/BP 7.0 compatibility mode" }
|
||||||
|
,{ "value":"macpas", "display":"Macintosh Pascal dialects compatibility mode" }
|
||||||
|
]}
|
||||||
|
,{ "key":"-n", "display":"Do not read the default config files" }
|
||||||
|
,{ "key":"-N<x>", "display":"Node tree optimizations" }
|
||||||
|
,{ "key":"-Nu", "display":"Unroll loops" }
|
||||||
|
,{ "key":"-o%value%", "display":"Name of the executable produced"
|
||||||
|
,"type" : "filename" }
|
||||||
|
,{ "key":"-O%value%", "display":"Optimizations:"
|
||||||
|
,"options": [
|
||||||
|
{ "value":"-", "display":"Disable optimizations" }
|
||||||
|
,{ "value":"1", "display":"Level 1 optimizations (quick and debugger friendly)" }
|
||||||
|
,{ "value":"2", "display":"Level 2 optimizations (-O1 + quick optimizations)" }
|
||||||
|
,{ "value":"3", "display":"Level 3 optimizations (-O2 + slow optimizations)" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
,{ "key":"-OaPROC=%value%", "display":"Set the alignment for procedure entry points" }
|
||||||
|
,{ "key":"-OaJUMP=%value%", "display":"Set the alignment for jump destination locations" }
|
||||||
|
,{ "key":"-OaLOOP=%value%", "display":"Set alignment for loops (for, while, repeat)" }
|
||||||
|
,{ "key":"-OaCONSTMIN=%value%", "display":"Minimum alignment for constants (both typed and untyped)" }
|
||||||
|
,{ "key":"-OaCONSTMAX=%value%", "display":"Maximum alignment for constants (both typed and untyped)" }
|
||||||
|
,{ "key":"-OaVARMIN=%value%", "display":"Minimum alignment for static and global variables" }
|
||||||
|
,{ "key":"-OaVARMAX=%value%", "display":"Maximum alignment for static and global variables" }
|
||||||
|
,{ "key":"-OaLOCALMIN=%value%", "display":"Minimum alignment for local variables" }
|
||||||
|
,{ "key":"-OaLOCALMAX=%value%", "display":"Maximum alignment for local variables" }
|
||||||
|
,{ "key":"-OaRECORDMIN=%value%", "display":"Minimum alignment for record fields" }
|
||||||
|
,{ "key":"-OaRECORDMAX=%value%", "display":"Maximum alignment for record fields" }
|
||||||
|
,{ "key":"-OoAll", "display":"Enable or disable whole program optimization" }
|
||||||
|
,{ "key":"-OoDEVIRTCALLS", "display":"Enable or disable whole program optimization DEVIRTCALLS" }
|
||||||
|
,{ "key":"-OoOPTVMTS", "display":"Enable or disable whole program optimization OPTVMTS" }
|
||||||
|
,{ "key":"-OoSYMBOLLIVENESS", "display":"Enable or disable whole program optimization SYMBOLLIVENESS" }
|
||||||
|
,{ "key":"-Op%value%", "display":"Set target cpu for optimizing"
|
||||||
|
,"options":[
|
||||||
|
{"value":"REGVAR"}
|
||||||
|
,{"value":"UNCERTAIN"}
|
||||||
|
,{"value":"STACKFRAME"}
|
||||||
|
,{"value":"PEEPHOLE"}
|
||||||
|
,{"value":"ASMCSE"}
|
||||||
|
,{"value":"LOOPUNROLL"}
|
||||||
|
,{"value":"TAILREC"}
|
||||||
|
,{"value":"CSE"}
|
||||||
|
]}
|
||||||
|
,{ "key":"-OW<x>", "display":"Generate whole-program optimization feedback for optimization <x>, see fpc -i for possible values" }
|
||||||
|
,{ "key":"-Ow<x>", "display":"Perform whole-program optimization <x>, see fpc -i for possible values" }
|
||||||
|
,{ "key":"-Os", "display":"Optimize for size rather than speed" }
|
||||||
|
,{ "key":"-pg", "display":"Generate profile code for gprof (defines FPC_PROFILE)" }
|
||||||
|
|
||||||
|
,{ "key":"-R%value%", "display":"Assembler reading style:"
|
||||||
|
,"options":[
|
||||||
|
{ "value":"default", "display":"Use default assembler for target" }
|
||||||
|
,{ "value":"att", "display":"Read AT&T style assembler" }
|
||||||
|
,{ "value":"intel", "display":"Read Intel style assembler" }
|
||||||
|
]}
|
||||||
|
|
||||||
|
,{ "key":"-S2", "display":"Same as -Mobjfpc", "alias":"" }
|
||||||
|
,{ "key":"-Sd", "display":"Same as -Mdelphi", "alias":"" }
|
||||||
|
,{ "key":"-So", "display":"Same as -Mtp", "alias":"" }
|
||||||
|
,{ "key":"-Sc", "display":"Support operators like C (*=,+=,/= and -=)", "masterkey": "-S" }
|
||||||
|
,{ "key":"-Sa", "display":"Turn on assertions" , "masterkey": "-S"}
|
||||||
|
,{ "key":"-Se%value%", "display":"Compiler Compiler halts after the number of errors (default is 1)", "type":"int" }
|
||||||
|
,{ "key":"-Sew", "display":"Compiler also halts after warnings", "type":"int" }
|
||||||
|
,{ "key":"-Sen", "display":"Compiler also halts after notes", "type":"int" }
|
||||||
|
,{ "key":"-Seh", "display":"Compiler also halts after hints", "type":"int" }
|
||||||
|
,{ "key":"-Sg", "display":"Enable LABEL and GOTO (default in -Mtp and -Mdelphi)", "masterkey": "-S" }
|
||||||
|
,{ "key":"-Sh", "display":"Use ansistrings by default instead of shortstrings", "masterkey": "-S" }
|
||||||
|
,{ "key":"-Si", "display":"Turn on inlining of procedures/functions declared as \"inline\"","masterkey": "-S" }
|
||||||
|
,{ "key":"-Sk", "display":"Load fpcylix unit","masterkey": "-S" }
|
||||||
|
,{ "key":"-SI%value%", "display":"Set interface style"
|
||||||
|
,"options": [
|
||||||
|
{ "value":"com", "display":"COM compatible interface (default)" }
|
||||||
|
,{ "value":"corba", "display":"CORBA compatible interface" }
|
||||||
|
]}
|
||||||
|
,{ "key":"-Sm", "display":"Support macros like C (global)","masterkey": "-S" }
|
||||||
|
,{ "key":"-Ss", "display":"Constructor name must be init (destructor must be done)","masterkey": "-S" }
|
||||||
|
,{ "key":"-Sx", "display":"Enable exception keywords (default in Delphi/ObjFPC modes)","masterkey": "-S" }
|
||||||
|
,{ "key":"-Sy", "display":"@<pointer> returns a typed pointer, same as $T+","masterkey": "-S" }
|
||||||
|
|
||||||
|
,{ "key":"-s", "display":"Do not call assembler and linker" }
|
||||||
|
,{ "key":"-sh", "display":"Generate script to link on host", "masterkey": "-s" }
|
||||||
|
,{ "key":"-st", "display":"Generate script to link on target", "masterkey": "-s" }
|
||||||
|
,{ "key":"-sr", "display":"Skip register allocation phase (use with -alr)", "masterkey": "-s" }
|
||||||
|
|
||||||
|
,{ "key":"-T%value%", "display":"Target operating system:",
|
||||||
|
"options": [
|
||||||
|
{ "value":"darwin", "display":"Darwin/Mac OS X" }
|
||||||
|
,{ "value":"emx", "display":"OS/2 via EMX (including EMX/RSX extender)" }
|
||||||
|
,{ "value":"freebsd", "display":"FreeBSD" }
|
||||||
|
,{ "value":"go32v2", "display":"Version 2 of DJ Delorie DOS extender" }
|
||||||
|
,{ "value":"iphonesim", "display":"iPhoneSimulator from iOS SDK 3.2+ (older versions: -Tdarwin)" }
|
||||||
|
,{ "value":"linux", "display":"Linux" }
|
||||||
|
,{ "value":"netbsd", "display":"NetBSD" }
|
||||||
|
,{ "value":"netware", "display":"Novell Netware Module (clib)" }
|
||||||
|
,{ "value":"netwlibc", "display":"Novell Netware Module (libc)" }
|
||||||
|
,{ "value":"openbsd", "display":"OpenBSD" }
|
||||||
|
,{ "value":"os2", "display":"OS/2 / eComStation" }
|
||||||
|
,{ "value":"sunos", "display":"SunOS/Solaris" }
|
||||||
|
,{ "value":"symbian", "display":"Symbian OS" }
|
||||||
|
,{ "value":"solaris", "display":"Solaris" }
|
||||||
|
,{ "value":"watcom", "display":"Watcom compatible DOS extender" }
|
||||||
|
,{ "value":"wdosx", "display":"WDOSX DOS extender" }
|
||||||
|
,{ "value":"win32", "display":"Windows 32 Bit" }
|
||||||
|
,{ "value":"wince", "display":"Windows CE" }
|
||||||
|
]}
|
||||||
|
,{ "key":"-P%value%", "display":"Target processor family:",
|
||||||
|
"options": [
|
||||||
|
{ "value":"arm", "display":"arm" }
|
||||||
|
,{ "value":"i386", "display":"i386" }
|
||||||
|
,{ "value":"m68k", "display":"m68k" }
|
||||||
|
,{ "value":"powerpc", "display":"powerpc" }
|
||||||
|
,{ "value":"sparc", "display":"sparc" }
|
||||||
|
,{ "value":"x86_64", "display":"x86_64" }
|
||||||
|
,{ "value":"mipsel", "display":"mipsel" }
|
||||||
|
]}
|
||||||
|
|
||||||
|
|
||||||
|
,{ "key":"-u%value%", "display":"Undefines the symbol", "multiple": true, "type": "string" }
|
||||||
|
|
||||||
|
,{ "key":"-Un", "display":"Do not check where the unit name matches the file name" }
|
||||||
|
,{ "key":"-Ur", "display":"Generate release unit files (never automatically recompiled)" }
|
||||||
|
,{ "key":"-Us", "display":"Compile a system unit" }
|
||||||
|
|
||||||
|
,{ "key":"-ve", "display":"Show errors (default)", "masterkey": "-v" }
|
||||||
|
,{ "key":"-v0", "display":"Show nothing (except errors)", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vw", "display":"Show warnings", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vu", "display":"Show unit info", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vn", "display":"Show notes", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vt", "display":"Show tried/used files", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vh", "display":"Show hints", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vc", "display":"Show conditionals", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vi", "display":"Show general info", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vd", "display":"Show debug info", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vl", "display":"Show linenumbers", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vr", "display":"Rhide/GCC compatibility mode", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vs", "display":"Show time stamps", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vq", "display":"Show message numbers", "masterkey": "-v" }
|
||||||
|
,{ "key":"-va", "display":"Show everything", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vx", "display":"Executable info", "masterkey": "-v"
|
||||||
|
,"condition":"win32" }
|
||||||
|
,{ "key":"-vb", "display":"Write file names messages with full path", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vp", "display":"Write tree.log with parse tree", "masterkey": "-v" }
|
||||||
|
,{ "key":"-vv", "display":"Write fpcdebug.txt with lots of debugging info", "masterkey": "-v" }
|
||||||
|
|
||||||
|
,{ "key":"-WA", "display":"Specify native type application", "masterkey": "-W"
|
||||||
|
,"condition":"win32" }
|
||||||
|
,{ "key":"-Wb", "display":"Create a bundle instead of a library", "masterkey": "-W"
|
||||||
|
,"condition":"darwin" }
|
||||||
|
,{ "key":"-WB%value%", "display":"Set image base to ", "type":"bytesize"
|
||||||
|
,"condition":"symbian,win32" }
|
||||||
|
,{ "key":"-WC", "display":"Specify console type application ", "masterkey": "-W"
|
||||||
|
,"condition":"OS/2,win32" }
|
||||||
|
,{ "key":"-WD", "display":"Use DEFFILE to export functions of DLL or EXE", "masterkey": "-W"
|
||||||
|
,"condition":"OS/2,win32" }
|
||||||
|
,{ "key":"-We", "display":"Use external resources", "masterkey": "-W"
|
||||||
|
,"condition":"darwin" }
|
||||||
|
,{ "key":"-WF", "display":"Specify full-screen type application", "masterkey": "-W"
|
||||||
|
,"condition":"OS/2" }
|
||||||
|
,{ "key":"-WG", "display":"Specify graphic type application", "masterkey": "-W"
|
||||||
|
,"condition":"OS/2,win32" }
|
||||||
|
,{ "key":"-Wi", "display":"Use internal resources", "masterkey": "-W"
|
||||||
|
,"condition":"darwin" }
|
||||||
|
,{ "key":"-WI", "display":"Turn on/off the usage of import sections", "masterkey": "-W"
|
||||||
|
,"condition":"win32" }
|
||||||
|
,{ "key":"-WN", "display":"Do not generate relocation code, needed for debugging", "masterkey": "-W"
|
||||||
|
,"condition":"win32" }
|
||||||
|
,{ "key":"-WR", "display":"Generate relocation code", "masterkey": "-W"
|
||||||
|
,"condition":"win32" }
|
||||||
|
,{ "key":"-WX", "display":"Enable executable stack", "masterkey": "-W"
|
||||||
|
,"condition":"linux" }
|
||||||
|
,{ "key":"-Xc", "display":"Pass --shared/-dynamic to the linker", "masterkey": "-X"
|
||||||
|
,"condition":"beos,darwin,freebsd,linux" }
|
||||||
|
,{ "key":"-Xd", "display":"Do not use standard library search path (needed for cross compile)", "masterkey": "-X" }
|
||||||
|
,{ "key":"-Xe", "display":"Use external linker", "masterkey": "-X" }
|
||||||
|
,{ "key":"-Xg", "display":"Create debuginfo in a separate file and add a debuglink section to executable", "masterkey": "-X" }
|
||||||
|
,{ "key":"-XD", "display":"Try to link units dynamically", "masterkey": "-X" }
|
||||||
|
,{ "key":"-Xi", "display":"Use internal linker", "masterkey": "-X" }
|
||||||
|
,{ "key":"-Xm", "display":"Generate link map", "masterkey": "-X" }
|
||||||
|
,{ "key":"-XM%value%", "display":"Set the name of the 'main' program routine (default is 'main')", "type":"string" }
|
||||||
|
,{ "key":"-XP%value%", "display":"Prepend the binutils names with the prefix <x>", "type":"dirpath" }
|
||||||
|
,{ "key":"-Xr%value%", "display":"Set the linker's rlink-path", "type": "dirpath"
|
||||||
|
,"condition":"beos,linux" }
|
||||||
|
,{ "key":"-XR%value%", "display":"Prepend to all linker search paths", "type": "dirpath"
|
||||||
|
,"condition":"beos,darwin,freebsd,linux,solaris,macos"}
|
||||||
|
,{ "key":"-Xs", "display":"Strip all symbols from executable", "masterkey": "-X" }
|
||||||
|
,{ "key":"-XS", "display":"Try to link units statically (default, defines FPC_LINK_STATIC)", "masterkey": "-X" }
|
||||||
|
,{ "key":"-Xt", "display":"Link with static libraries (-static is passed to linker)", "masterkey": "-X" }
|
||||||
|
,{ "key":"-XX", "display":"Try to smartlink units (defines FPC_LINK_SMART)", "masterkey": "-X" }
|
||||||
|
]
|
||||||
|
}
|
97
components/cmdlinecfg/trunk/idecompopt/cfgcompopt.lpk
Normal file
97
components/cmdlinecfg/trunk/idecompopt/cfgcompopt.lpk
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<Package Version="4">
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Name Value="cfgcompopt"/>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<SearchPaths>
|
||||||
|
<OtherUnitFiles Value=".."/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Other>
|
||||||
|
<CompilerMessages>
|
||||||
|
<MsgFileName Value=""/>
|
||||||
|
</CompilerMessages>
|
||||||
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Files Count="13">
|
||||||
|
<Item1>
|
||||||
|
<Filename Value="optviewform.pas"/>
|
||||||
|
<UnitName Value="optviewform"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Filename Value="..\cmdlinelclctrlsbox.pas"/>
|
||||||
|
<UnitName Value="cmdlinelclctrlsbox"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<Filename Value="..\cmdlinelclpropgrid.pas"/>
|
||||||
|
<UnitName Value="cmdlinelclpropgrid"/>
|
||||||
|
</Item3>
|
||||||
|
<Item4>
|
||||||
|
<Filename Value="..\cmdlinelclutils.pas"/>
|
||||||
|
<UnitName Value="cmdlinelclutils"/>
|
||||||
|
</Item4>
|
||||||
|
<Item5>
|
||||||
|
<Filename Value="..\cmdlinecfg.pas"/>
|
||||||
|
<UnitName Value="cmdlinecfg"/>
|
||||||
|
</Item5>
|
||||||
|
<Item6>
|
||||||
|
<Filename Value="..\cmdlinecfgjson.pas"/>
|
||||||
|
<UnitName Value="cmdlinecfgjson"/>
|
||||||
|
</Item6>
|
||||||
|
<Item7>
|
||||||
|
<Filename Value="..\cmdlinecfgparser.pas"/>
|
||||||
|
<UnitName Value="cmdlinecfgparser"/>
|
||||||
|
</Item7>
|
||||||
|
<Item8>
|
||||||
|
<Filename Value="..\cmdlinecfgui.pas"/>
|
||||||
|
<UnitName Value="cmdlinecfgui"/>
|
||||||
|
</Item8>
|
||||||
|
<Item9>
|
||||||
|
<Filename Value="..\cmdlinecfguijson.pas"/>
|
||||||
|
<UnitName Value="cmdlinecfguijson"/>
|
||||||
|
</Item9>
|
||||||
|
<Item10>
|
||||||
|
<Filename Value="..\cmdlinecfgutils.pas"/>
|
||||||
|
<UnitName Value="cmdlinecfgutils"/>
|
||||||
|
</Item10>
|
||||||
|
<Item11>
|
||||||
|
<Filename Value="..\cmdlinefpccond.pas"/>
|
||||||
|
<UnitName Value="cmdlinefpccond"/>
|
||||||
|
</Item11>
|
||||||
|
<Item12>
|
||||||
|
<Filename Value="cfgcompoptreg.pas"/>
|
||||||
|
<HasRegisterProc Value="True"/>
|
||||||
|
<UnitName Value="cfgcompoptreg"/>
|
||||||
|
</Item12>
|
||||||
|
<Item13>
|
||||||
|
<Filename Value="optviewform.lfm"/>
|
||||||
|
<Type Value="LFM"/>
|
||||||
|
</Item13>
|
||||||
|
</Files>
|
||||||
|
<Type Value="DesignTime"/>
|
||||||
|
<RequiredPkgs Count="3">
|
||||||
|
<Item1>
|
||||||
|
<PackageName Value="IDEIntf"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<PackageName Value="lcl"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<PackageName Value="FCL"/>
|
||||||
|
</Item3>
|
||||||
|
</RequiredPkgs>
|
||||||
|
<UsageOptions>
|
||||||
|
<UnitPath Value="$(PkgOutDir)"/>
|
||||||
|
</UsageOptions>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<CustomOptions Items="ExternHelp" Version="2">
|
||||||
|
<_ExternHelp Items="Count"/>
|
||||||
|
</CustomOptions>
|
||||||
|
</Package>
|
||||||
|
</CONFIG>
|
24
components/cmdlinecfg/trunk/idecompopt/cfgcompopt.pas
Normal file
24
components/cmdlinecfg/trunk/idecompopt/cfgcompopt.pas
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{ This file was automatically created by Lazarus. Do not edit!
|
||||||
|
This source is only used to compile and install the package.
|
||||||
|
}
|
||||||
|
|
||||||
|
unit cfgcompopt;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
optviewform, cmdlinelclctrlsbox, cmdlinelclpropgrid, cmdlinelclutils,
|
||||||
|
cmdlinecfg, cmdlinecfgjson, cmdlinecfgparser, cmdlinecfgui,
|
||||||
|
cmdlinecfguijson, cmdlinecfgutils, cmdlinefpccond, cfgcompoptreg,
|
||||||
|
LazarusPackageIntf;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure Register;
|
||||||
|
begin
|
||||||
|
RegisterUnit('cfgcompoptreg', @cfgcompoptreg.Register);
|
||||||
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
RegisterPackage('cfgcompopt', @Register);
|
||||||
|
end.
|
126
components/cmdlinecfg/trunk/idecompopt/cfgcompoptreg.pas
Normal file
126
components/cmdlinecfg/trunk/idecompopt/cfgcompoptreg.pas
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
unit cfgcompoptreg;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, Forms, Dialogs
|
||||||
|
, LazIDEIntf, MenuIntf
|
||||||
|
, cmdlinecfg, cmdlinecfgutils
|
||||||
|
, cmdlinecfgjson, cmdlinecfgui, cmdlinecfguijson
|
||||||
|
, optviewform
|
||||||
|
, XMLConf;
|
||||||
|
|
||||||
|
procedure Register;
|
||||||
|
|
||||||
|
var
|
||||||
|
listOfOpt : TList;
|
||||||
|
listOfLayout : TList;
|
||||||
|
|
||||||
|
CompOptVers : string; // the version of fpc compiler used
|
||||||
|
CompOptCfg : TCmdLineCfg; // fpc compiler options
|
||||||
|
CfgLayout : TCmdLineLayoutInfo; // compiler options layout hints
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
resourcestring
|
||||||
|
mnuViewCfgCompilerOpt = 'Review Compiler Options';
|
||||||
|
|
||||||
|
function GetCompilerPath: string;
|
||||||
|
var
|
||||||
|
path : string;
|
||||||
|
xml : TXMLConfig;
|
||||||
|
begin
|
||||||
|
//appears to be a hack, but is there a better way to do that?
|
||||||
|
path := LazarusIDE.GetPrimaryConfigPath;
|
||||||
|
xml := TXMLConfig.Create(nil);
|
||||||
|
try
|
||||||
|
xml.RootName:='CONFIG';
|
||||||
|
xml.Filename:=IncludeTrailingPathDelimiter(path)+'environmentoptions.xml';
|
||||||
|
Result:=xml.GetValue('EnvironmentOptions/CompilerFilename/Value', '');
|
||||||
|
finally
|
||||||
|
xml.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ReviewCompOpt(Sender: TObject);
|
||||||
|
var
|
||||||
|
cmp : string;
|
||||||
|
begin
|
||||||
|
if not Assigned(CompOptCfg) then begin
|
||||||
|
cmp:=GetCompilerPath;
|
||||||
|
if cmp<>'' then
|
||||||
|
CompOptCfg:=CmdLineCfgDetect(listOfOpt, ExtractFileDir(cmp), cmp);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//todo: better selection of default options
|
||||||
|
if not Assigned(CompOptCfg) and (listOfOpt.Count>0) then
|
||||||
|
CompOptCfg:=TCmdLineCfg(listOfOpt[0]);
|
||||||
|
|
||||||
|
if not Assigned(CompOptCfg) then begin
|
||||||
|
ShowMessage('Unable to detect the compiler version.');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Assigned(LazarusIDE.ActiveProject) then begin
|
||||||
|
if not Assigned(OptView) then OptView:=TOptView.Create(Application);
|
||||||
|
ReviewOpts(CompOptCfg, CfgLayout);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DoRegister;
|
||||||
|
var
|
||||||
|
cmd : TIDEMenuCommand;
|
||||||
|
begin
|
||||||
|
cmd := RegisterIDEMenuCommand(itmProjectWindowSection, 'showCfgCompOpt',
|
||||||
|
mnuViewCfgCompilerOpt, nil, ReviewCompOpt, nil, '');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ReadConfig;
|
||||||
|
var
|
||||||
|
path : string;
|
||||||
|
begin
|
||||||
|
path:=ExcludeTrailingPathDelimiter(LazarusIDE.GetPrimaryConfigPath);
|
||||||
|
if not DirectoryExists( path ) then path:=ExcludeTrailingPathDelimiter(LazarusIDE.GetSecondaryConfigPath );
|
||||||
|
CmdLineCfgJSONLoadFilesFromDir( path , listOfOpt );
|
||||||
|
CmdLineCfgUIJSONLoadFilesFromDir( path , listOfLayout );
|
||||||
|
|
||||||
|
|
||||||
|
//todo: make a smarter layout selection
|
||||||
|
if listOfLayout.Count>0 then CfgLayout:=TCmdLineLayoutInfo(listOfLayout[0]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Register;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
DoRegister;
|
||||||
|
ReadConfig;
|
||||||
|
except
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Init;
|
||||||
|
begin
|
||||||
|
listOfOpt := TList.Create;
|
||||||
|
listOfLayout := TList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Release;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
for i:=0 to listOfOpt.Count-1 do TObject(listOfOpt[i]).Free;
|
||||||
|
listOfOpt.Free;
|
||||||
|
for i:=0 to listOfLayout.Count-1 do TObject(listOfLayout[i]).Free;
|
||||||
|
listOfLayout.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
Init;
|
||||||
|
|
||||||
|
finalization
|
||||||
|
Release;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
50
components/cmdlinecfg/trunk/idecompopt/optviewform.lfm
Normal file
50
components/cmdlinecfg/trunk/idecompopt/optviewform.lfm
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
object OptView: TOptView
|
||||||
|
Left = 359
|
||||||
|
Height = 240
|
||||||
|
Top = 214
|
||||||
|
Width = 320
|
||||||
|
Caption = 'OptView'
|
||||||
|
ClientHeight = 240
|
||||||
|
ClientWidth = 320
|
||||||
|
OnDestroy = FormDestroy
|
||||||
|
OnShow = FormShow
|
||||||
|
LCLVersion = '1.1'
|
||||||
|
object Panel1: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 190
|
||||||
|
Top = 0
|
||||||
|
Width = 320
|
||||||
|
Align = alClient
|
||||||
|
Caption = 'Panel1'
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object Panel2: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 50
|
||||||
|
Top = 190
|
||||||
|
Width = 320
|
||||||
|
Align = alBottom
|
||||||
|
Caption = 'Panel2'
|
||||||
|
ClientHeight = 50
|
||||||
|
ClientWidth = 320
|
||||||
|
TabOrder = 1
|
||||||
|
object btnOk: TButton
|
||||||
|
Left = 33
|
||||||
|
Height = 25
|
||||||
|
Top = 15
|
||||||
|
Width = 75
|
||||||
|
Caption = 'Ok'
|
||||||
|
ModalResult = 1
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object btnCancel: TButton
|
||||||
|
Left = 115
|
||||||
|
Height = 25
|
||||||
|
Top = 15
|
||||||
|
Width = 75
|
||||||
|
Caption = 'Cancel'
|
||||||
|
ModalResult = 2
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
108
components/cmdlinecfg/trunk/idecompopt/optviewform.pas
Normal file
108
components/cmdlinecfg/trunk/idecompopt/optviewform.pas
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
unit optviewform;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
|
||||||
|
LCLIntf,
|
||||||
|
StdCtrls, LazIDEIntf, IDEOptionsIntf, ProjectIntf, CompOptsIntf, cmdlinecfg,
|
||||||
|
cmdlinecfgjson, cmdlinecfgui, cmdlinecfguijson, cmdlinelclctrlsbox, cmdlinelazcompopt;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TOptView }
|
||||||
|
|
||||||
|
TOptView = class(TForm)
|
||||||
|
btnOk: TButton;
|
||||||
|
btnCancel: TButton;
|
||||||
|
Panel1: TPanel;
|
||||||
|
Panel2: TPanel;
|
||||||
|
procedure FormDestroy(Sender: TObject);
|
||||||
|
procedure FormShow(Sender: TObject);
|
||||||
|
private
|
||||||
|
{ private declarations }
|
||||||
|
cmd : TCmdLineScrollBoxControl;
|
||||||
|
cfg : TCmdLineCfg;
|
||||||
|
layout : TCmdLineLayoutInfo;
|
||||||
|
procedure InitOpts(acfg: TCmdLineCfg; alayout: TCmdLineLayoutInfo);
|
||||||
|
public
|
||||||
|
{ public declarations }
|
||||||
|
function ShowForOpts(opt: TLazCompilerOptions): Integer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
OptView: TOptView = nil;
|
||||||
|
|
||||||
|
function ReviewOpts(acfg: TCmdLineCfg; alayout: TCmdLineLayoutInfo; opt: TLazCompilerOptions = nil): Integer;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{$R *.lfm}
|
||||||
|
|
||||||
|
{ TOptView }
|
||||||
|
|
||||||
|
function ReviewOpts(acfg: TCmdLineCfg; alayout: TCmdLineLayoutInfo; opt: TLazCompilerOptions = nil): Integer;
|
||||||
|
begin
|
||||||
|
if not Assigned(OptView) then OptView:=TOptView.Create(Application);
|
||||||
|
if (OptView.cfg<>acfg) or (OptView.layout<>alayout) then
|
||||||
|
OptView.InitOpts(acfg, alayout);
|
||||||
|
if not Assigned(opt) and Assigned(LazarusIDE.ActiveProject) then
|
||||||
|
opt:=LazarusIDE.ActiveProject.LazCompilerOptions;
|
||||||
|
|
||||||
|
if Assigned(OptView.cmd) and Assigned(opt) then
|
||||||
|
Result:=OptView.ShowForOpts(opt)
|
||||||
|
else
|
||||||
|
Result:=mrCancel;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TOptView.FormDestroy(Sender: TObject);
|
||||||
|
begin
|
||||||
|
cmd.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TOptView.FormShow(Sender: TObject);
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TOptView.InitOpts(acfg: TCmdLineCfg; alayout: TCmdLineLayoutInfo);
|
||||||
|
begin
|
||||||
|
ReleaseScrollBox(cmd);
|
||||||
|
cmd.Free;
|
||||||
|
cfg:=acfg;
|
||||||
|
layout:=alayout;
|
||||||
|
cmd:=TCmdLineScrollBoxControl.Create(Panel1);
|
||||||
|
cmd.Init(cfg, layout);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TOptView.ShowForOpts(opt: TLazCompilerOptions): Integer;
|
||||||
|
var
|
||||||
|
list : TList;
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
list := TList.Create;
|
||||||
|
try
|
||||||
|
LazCompOptToVals(opt, cfg, list);
|
||||||
|
cmd.SetValues(list);
|
||||||
|
for i:=0 to list.Count-1 do TObject(list[i]).Free;
|
||||||
|
|
||||||
|
Result:=ShowModal;
|
||||||
|
if Result=mrOK then begin
|
||||||
|
list.Clear;
|
||||||
|
cmd.Serialize(list);
|
||||||
|
ValsToLazCompOpt(list, opt);
|
||||||
|
for i:=0 to list.Count-1 do TObject(list[i]).Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
finally
|
||||||
|
list.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
101
components/cmdlinecfg/trunk/readme.txt
Normal file
101
components/cmdlinecfg/trunk/readme.txt
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
Command Line Configuration
|
||||||
|
|
||||||
|
|
||||||
|
== JSON Storage ==
|
||||||
|
|
||||||
|
The configuration can be stored in JSON format.
|
||||||
|
Root values are
|
||||||
|
|
||||||
|
executable : string - the name of executable (don't have to match the actual binary name)
|
||||||
|
must be the same accross multiple versions
|
||||||
|
version : string - the executable version.
|
||||||
|
testkey : string - the test command-line key that needs to be passed to the executable
|
||||||
|
to retrieve the test value
|
||||||
|
testValue : string - the value that's unique to this version of executable
|
||||||
|
option : array - an array of options, where each option is described as json object
|
||||||
|
fromversion : string - the version of the same executable that configuration file can be used.
|
||||||
|
thus "incremental" configuration files are allowed.
|
||||||
|
however, previous version of the file must be available as well.
|
||||||
|
Any new values or options
|
||||||
|
|
||||||
|
Option values are:
|
||||||
|
|
||||||
|
key : string (required) - the command-line text that needs to be added to a parameter
|
||||||
|
if the option is selected or any value is assigned to this option
|
||||||
|
(in case any value is accepted, such as: int, size, filepath, dirpath, etc)
|
||||||
|
name : string (optional) - code name of the option (the same name should be shared accross multiple
|
||||||
|
versions of the executable - to store the value);
|
||||||
|
section : string (optional) - the section of command line option.
|
||||||
|
subsection : string (optional) - the sub section of the section ... todo: make a better description here
|
||||||
|
masterkey : string (optional) - the "key" prefix that should be used to combining multiple values into
|
||||||
|
a single key entry. Example:
|
||||||
|
two switches -Ct -Co will be combined into -Cto, if both have -C as master key.
|
||||||
|
display : string (optional) - the display name of the option. (if blank, name is used)
|
||||||
|
condition : string (optional) - free form condition string (see FPC Condition below)
|
||||||
|
type : string (default switch) - the type of an option. Available types are:
|
||||||
|
switch - simple enabled or disabled
|
||||||
|
select - multple options are available (expected "options" to be defined)
|
||||||
|
filename - name of a file
|
||||||
|
dirname - name of a directory
|
||||||
|
int - an integer value
|
||||||
|
string - a free form string
|
||||||
|
- - (dash) if type is a dash, the option is removed from this version
|
||||||
|
of the compiler. (used with "fromversion" configuration)
|
||||||
|
options : array (optional) - a list of available values.
|
||||||
|
mutiple : boolean (default false) - multiple entries of the same value is allowed. typically
|
||||||
|
is used for filename or dirnames. However, even for dirname of filename
|
||||||
|
it still defaults to false and must be reinitialized;
|
||||||
|
alias : string (optional) - the current key is considered to be deprecated is, the better
|
||||||
|
key to be used is specified by the "alias" field
|
||||||
|
|
||||||
|
|
||||||
|
Example of JSON Storage:
|
||||||
|
|
||||||
|
{
|
||||||
|
"executable":"fpc",
|
||||||
|
"version":"2.6.0",
|
||||||
|
"testkey":"-iV",
|
||||||
|
"testValue":"2.6.0",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
section:"execopt",
|
||||||
|
key:"Xm",
|
||||||
|
name:"generatelinkmap",
|
||||||
|
display:"Generate Link Map"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
section:"codegen",
|
||||||
|
key: "Cp%value%",
|
||||||
|
display: "Instruction set",
|
||||||
|
name: "instructionset",
|
||||||
|
options: [
|
||||||
|
{ value: "80386", condition:"i386,x86_64" }
|
||||||
|
,{ value: "PENTIUM", condition:"i386,x86_64" }
|
||||||
|
,{ value: "PENTIUM2", condition:"i386,x86_64" }
|
||||||
|
,{ value: "PENTIUM3", condition:"i386,x86_64" }
|
||||||
|
,{ value: "PENTIUM4", condition:"i386,x86_64" }
|
||||||
|
,{ value: "PENTIUMM", condition:"i386,x86_64" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
== FPC Condition ==
|
||||||
|
|
||||||
|
Free Pascal Compiler condition define for what target (CPU, CPU-OS) the option or value of an option
|
||||||
|
is available. The format follows the FPC convention of target platforms naming:
|
||||||
|
CPU-OS
|
||||||
|
or
|
||||||
|
CPU
|
||||||
|
|
||||||
|
Example, if an option is available for Intel 386 (32-bit machines), the condition should be set to
|
||||||
|
i386
|
||||||
|
If an option is specific to Windows on i386 machine, the condition would be
|
||||||
|
i386-win32
|
||||||
|
(No whitespaces are allowed between)
|
||||||
|
|
||||||
|
If an option is available for multple platforms, each condition has to be comma separated:
|
||||||
|
i386,x86_64,arm-linux
|
||||||
|
|
||||||
|
|
||||||
|
|
28
components/cmdlinecfg/trunk/test.copt
Normal file
28
components/cmdlinecfg/trunk/test.copt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"executable":"fpc",
|
||||||
|
"version":"2.6.0",
|
||||||
|
"testkey":"-iV",
|
||||||
|
"testValue":"2.6.0",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
section:"execopt",
|
||||||
|
key:"Xm",
|
||||||
|
name:"generatelinkmap",
|
||||||
|
display:"Generate Link Map"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
section:"codegen",
|
||||||
|
key: "Cp%value%",
|
||||||
|
display: "Instruction set",
|
||||||
|
name: "instructionset",
|
||||||
|
options: [
|
||||||
|
{ value: "80386", condition:"i386,x86_64" }
|
||||||
|
,{ value: "PENTIUM", condition:"i386,x86_64" }
|
||||||
|
,{ value: "PENTIUM2", condition:"i386,x86_64" }
|
||||||
|
,{ value: "PENTIUM3", condition:"i386,x86_64" }
|
||||||
|
,{ value: "PENTIUM4", condition:"i386,x86_64" }
|
||||||
|
,{ value: "PENTIUMM", condition:"i386,x86_64" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
72
components/cmdlinecfg/trunk/testcmdlineparse.lpi
Normal file
72
components/cmdlinecfg/trunk/testcmdlineparse.lpi
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="9"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<General>
|
||||||
|
<Flags>
|
||||||
|
<MainUnitHasCreateFormStatements Value="False"/>
|
||||||
|
<MainUnitHasTitleStatement Value="False"/>
|
||||||
|
</Flags>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
|
<Title Value="testcmdlineparse"/>
|
||||||
|
<UseAppBundle Value="False"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
</General>
|
||||||
|
<i18n>
|
||||||
|
<EnableI18N LFM="False"/>
|
||||||
|
</i18n>
|
||||||
|
<VersionInfo>
|
||||||
|
<StringTable ProductVersion=""/>
|
||||||
|
</VersionInfo>
|
||||||
|
<BuildModes Count="1">
|
||||||
|
<Item1 Name="Default" Default="True"/>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<local>
|
||||||
|
<FormatVersion Value="1"/>
|
||||||
|
</local>
|
||||||
|
</RunParams>
|
||||||
|
<Units Count="1">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="testcmdlineparse.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="testcmdlineparse"/>
|
||||||
|
</Unit0>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="testcmdlineparse"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Other>
|
||||||
|
<CompilerMessages>
|
||||||
|
<MsgFileName Value=""/>
|
||||||
|
</CompilerMessages>
|
||||||
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions Count="3">
|
||||||
|
<Item1>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item3>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
79
components/cmdlinecfg/trunk/testcmdlineparse.lpr
Normal file
79
components/cmdlinecfg/trunk/testcmdlineparse.lpr
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
program testcmdlineparse;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||||
|
cthreads,
|
||||||
|
{$ENDIF}{$ENDIF}
|
||||||
|
SysUtils, Classes
|
||||||
|
, cmdlinecfg, cmdlinecfgutils, cmdlinecfgparser, cmdlinecfgjson
|
||||||
|
{ you can add units after this };
|
||||||
|
|
||||||
|
|
||||||
|
procedure TestConfigLineParam(const cmdlinefn, conffn: string);
|
||||||
|
var
|
||||||
|
cfg : TcmdLineCfg;
|
||||||
|
prm : TStringList;
|
||||||
|
result :TList;
|
||||||
|
i : integer;
|
||||||
|
v : TCmdLineOptionValue;
|
||||||
|
p : string;
|
||||||
|
begin
|
||||||
|
prm:=TStringList.Create;
|
||||||
|
result:=TList.Create;
|
||||||
|
try
|
||||||
|
prm.LoadFromFile(cmdlinefn);
|
||||||
|
p:=prm.Text;
|
||||||
|
prm.Clear;
|
||||||
|
CmdLineParse(p, prm);
|
||||||
|
writeln('total input arguments: ', prm.Count);
|
||||||
|
for i:=0 to prm.Count-1 do writeln(prm[i]);
|
||||||
|
writeln;
|
||||||
|
|
||||||
|
if FileExists(conffn) then begin
|
||||||
|
cfg:=TCmdLineCfg.Create;
|
||||||
|
try
|
||||||
|
CmdLineCfgJSONReadFile(conffn, cfg);
|
||||||
|
|
||||||
|
CmdLineMatchArgsToOpts(cfg, prm, result);
|
||||||
|
writeln('known values: ');
|
||||||
|
for i:=0 to result.Count-1 do begin
|
||||||
|
v:=TCmdLineOptionValue(result[i]);
|
||||||
|
if v.Option = nil then Continue;
|
||||||
|
writeln(' ', v.Option.Key,' (',v.Option.Display,')');
|
||||||
|
writeln(' value: ', v.Value);
|
||||||
|
end;
|
||||||
|
writeln;
|
||||||
|
|
||||||
|
writeln('unknown values: ');
|
||||||
|
for i:=0 to result.Count-1 do begin
|
||||||
|
v:=TCmdLineOptionValue(result[i]);
|
||||||
|
if v.Option <> nil then Continue;
|
||||||
|
writeln(' ',v.Value);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
cfg.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
finally
|
||||||
|
prm.Free;
|
||||||
|
result.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Paramcount=0 then begin
|
||||||
|
writeln('Please specify file name that contains command lines to be parsed');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if ParamCount=1 then begin
|
||||||
|
writeln('Simple command line parsing test');
|
||||||
|
TestConfigLineParam(ParamStr(1), '');
|
||||||
|
end else if PAramCount=2 then begin
|
||||||
|
writeln('Command line to configuration parsing test');
|
||||||
|
TestConfigLineParam(ParamSTr(1), Paramstr(2));
|
||||||
|
end;
|
||||||
|
end.
|
||||||
|
|
89
components/cmdlinecfg/trunk/testcompconfread.lpi
Normal file
89
components/cmdlinecfg/trunk/testcompconfread.lpi
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="9"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<General>
|
||||||
|
<Flags>
|
||||||
|
<MainUnitHasCreateFormStatements Value="False"/>
|
||||||
|
<MainUnitHasTitleStatement Value="False"/>
|
||||||
|
</Flags>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
|
<Title Value="project1"/>
|
||||||
|
<UseAppBundle Value="False"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
</General>
|
||||||
|
<i18n>
|
||||||
|
<EnableI18N LFM="False"/>
|
||||||
|
</i18n>
|
||||||
|
<VersionInfo>
|
||||||
|
<StringTable ProductVersion=""/>
|
||||||
|
</VersionInfo>
|
||||||
|
<BuildModes Count="1">
|
||||||
|
<Item1 Name="Default" Default="True"/>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
||||||
|
<ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<local>
|
||||||
|
<FormatVersion Value="1"/>
|
||||||
|
</local>
|
||||||
|
</RunParams>
|
||||||
|
<Units Count="3">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="testcompconfread.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="testcompconfread"/>
|
||||||
|
</Unit0>
|
||||||
|
<Unit1>
|
||||||
|
<Filename Value="cmdlinecfg.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="cmdlinecfg"/>
|
||||||
|
</Unit1>
|
||||||
|
<Unit2>
|
||||||
|
<Filename Value="cmdlinecfgjson.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="cmdlinecfgjson"/>
|
||||||
|
</Unit2>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="testcompconfread"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Parsing>
|
||||||
|
<SyntaxOptions>
|
||||||
|
<SyntaxMode Value="Delphi"/>
|
||||||
|
</SyntaxOptions>
|
||||||
|
</Parsing>
|
||||||
|
<Other>
|
||||||
|
<CompilerMessages>
|
||||||
|
<MsgFileName Value=""/>
|
||||||
|
</CompilerMessages>
|
||||||
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions Count="3">
|
||||||
|
<Item1>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item3>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
29
components/cmdlinecfg/trunk/testcompconfread.pas
Normal file
29
components/cmdlinecfg/trunk/testcompconfread.pas
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
program testcompconfread;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
SysUtils, Classes, cmdlinecfg, cmdlinecfgjson, cmdlinecfgutils
|
||||||
|
{ you can add units after this };
|
||||||
|
|
||||||
|
var
|
||||||
|
cfg : TCmdLineCfg;
|
||||||
|
begin
|
||||||
|
if Paramcount=0 then begin
|
||||||
|
writeln('please provide the configuration file name');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
try
|
||||||
|
cfg := TCmdLineCfg.Create;
|
||||||
|
try
|
||||||
|
CmdLineCfgJSONReadFile(ParamStr(1), cfg);
|
||||||
|
CmdLineDebug(cfg);
|
||||||
|
finally
|
||||||
|
cfg.Free;
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
on e: Exception do
|
||||||
|
writeln(e.message);
|
||||||
|
end;
|
||||||
|
end.
|
||||||
|
|
74
components/cmdlinecfg/trunk/testgetversion.lpi
Normal file
74
components/cmdlinecfg/trunk/testgetversion.lpi
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="9"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<General>
|
||||||
|
<Flags>
|
||||||
|
<MainUnitHasCreateFormStatements Value="False"/>
|
||||||
|
<MainUnitHasTitleStatement Value="False"/>
|
||||||
|
</Flags>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
|
<Title Value="project1"/>
|
||||||
|
<UseAppBundle Value="False"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
</General>
|
||||||
|
<i18n>
|
||||||
|
<EnableI18N LFM="False"/>
|
||||||
|
</i18n>
|
||||||
|
<VersionInfo>
|
||||||
|
<StringTable ProductVersion=""/>
|
||||||
|
</VersionInfo>
|
||||||
|
<BuildModes Count="1">
|
||||||
|
<Item1 Name="Default" Default="True"/>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
||||||
|
<ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<local>
|
||||||
|
<FormatVersion Value="1"/>
|
||||||
|
</local>
|
||||||
|
</RunParams>
|
||||||
|
<Units Count="1">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="testgetversion.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="testgetversion"/>
|
||||||
|
</Unit0>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="testgetversion"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Other>
|
||||||
|
<CompilerMessages>
|
||||||
|
<MsgFileName Value=""/>
|
||||||
|
</CompilerMessages>
|
||||||
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions Count="3">
|
||||||
|
<Item1>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item3>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
34
components/cmdlinecfg/trunk/testgetversion.lpr
Normal file
34
components/cmdlinecfg/trunk/testgetversion.lpr
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
program testgetversion;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, cmdlinecfg, cmdlinecfgutils, cmdlinecfgjson;
|
||||||
|
|
||||||
|
var
|
||||||
|
s : string;
|
||||||
|
list : TList;
|
||||||
|
cfg : TCmdLineCfg;
|
||||||
|
exe : string;
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
exe := 'fpc';
|
||||||
|
if ParamCount>0 then exe:=ParamStr(1);
|
||||||
|
writeln('executable: ', exe);
|
||||||
|
list := TList.Create;
|
||||||
|
try
|
||||||
|
CmdLineCfgJSONLoadFilesFromDir( GetCurrentDir, list );
|
||||||
|
writeln('found configurations: ', list.Count);
|
||||||
|
for i:=0 to list.Count-1 do
|
||||||
|
writeln( TCmdLineCfg(list[i]).Version );
|
||||||
|
|
||||||
|
cfg:=CmdLineCfgDetect( list, GetCurrentDir, exe);
|
||||||
|
if Assigned(cfg) then begin
|
||||||
|
writeln('version detected: ', cfg.Version);
|
||||||
|
end else
|
||||||
|
writeln('not found');
|
||||||
|
finally
|
||||||
|
list.Free;
|
||||||
|
end;
|
||||||
|
end.
|
||||||
|
|
47
components/cmdlinecfg/trunk/testguibuild/conf.coptui
Normal file
47
components/cmdlinecfg/trunk/testguibuild/conf.coptui
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"paths": {
|
||||||
|
"display": "Paths",
|
||||||
|
"switches": ["-Fu","-Fi","-Fl","-FU","-o"]
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"display": "Config and Target",
|
||||||
|
"switches": ["-n"],
|
||||||
|
"platform": {
|
||||||
|
"display": "Target Platform",
|
||||||
|
"hint" : "groupbox",
|
||||||
|
"switches": ["-T","-P","-Op"]
|
||||||
|
},
|
||||||
|
"switches": ["-WG"]
|
||||||
|
},
|
||||||
|
"parsing": {
|
||||||
|
"display": "Parsing",
|
||||||
|
"switches": ["-M","-Sc","-Sa","-Sg","-Si","-Sm","-Ss","-St","-Sh","-R"]
|
||||||
|
},
|
||||||
|
"compiler": {
|
||||||
|
"display": "Compilation and Linking",
|
||||||
|
"switches": ["-O","-Os","-CX","-WR","-Ch","-Cs","-XX","-k"]
|
||||||
|
},
|
||||||
|
"debugging": {
|
||||||
|
"display": "Debugging",
|
||||||
|
"checks" : {
|
||||||
|
"display":"Checks and assertions",
|
||||||
|
"hint" : "groupbox",
|
||||||
|
"switches":["-Ci","-Cr","-Co","-Ct","-CR","-Sa"]
|
||||||
|
},
|
||||||
|
"switches": ["-g"],
|
||||||
|
"infos" : {
|
||||||
|
"display": "Info for GDB",
|
||||||
|
"hint" : "groupbox",
|
||||||
|
"switches": ["-WG", "-gl","-gv","-Xg"]
|
||||||
|
},
|
||||||
|
"otherdebug" :{
|
||||||
|
"display" : "Other debugging Info",
|
||||||
|
"hint" : "groupbox",
|
||||||
|
"switches":["-gh","-gt","-pg","-Xs"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"verbosity": {
|
||||||
|
"display": "Verbosity",
|
||||||
|
"switches": ["-ve","-vw", "-vn","-vh","-vi","-vp","-vc","-vx","-v0","-vd","-vu","-vt","-vl","-vb","-va","-l","-Se"]
|
||||||
|
}
|
||||||
|
}
|
67
components/cmdlinecfg/trunk/testguibuild/mainform.lfm
Normal file
67
components/cmdlinecfg/trunk/testguibuild/mainform.lfm
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
object Form1: TForm1
|
||||||
|
Left = 411
|
||||||
|
Height = 319
|
||||||
|
Top = 197
|
||||||
|
Width = 425
|
||||||
|
Caption = 'Form1'
|
||||||
|
ClientHeight = 319
|
||||||
|
ClientWidth = 425
|
||||||
|
OnCreate = FormCreate
|
||||||
|
OnDestroy = FormDestroy
|
||||||
|
LCLVersion = '1.1'
|
||||||
|
object Memo1: TMemo
|
||||||
|
Left = 0
|
||||||
|
Height = 90
|
||||||
|
Top = 179
|
||||||
|
Width = 425
|
||||||
|
Align = alBottom
|
||||||
|
Lines.Strings = (
|
||||||
|
'Memo1'
|
||||||
|
)
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object Splitter1: TSplitter
|
||||||
|
Cursor = crVSplit
|
||||||
|
Left = 0
|
||||||
|
Height = 5
|
||||||
|
Top = 174
|
||||||
|
Width = 425
|
||||||
|
Align = alBottom
|
||||||
|
ResizeAnchor = akBottom
|
||||||
|
end
|
||||||
|
object Label1: TLabel
|
||||||
|
Left = 47
|
||||||
|
Height = 13
|
||||||
|
Top = 44
|
||||||
|
Width = 31
|
||||||
|
Caption = 'Label1'
|
||||||
|
ParentColor = False
|
||||||
|
end
|
||||||
|
object Edit1: TEdit
|
||||||
|
Left = 105
|
||||||
|
Height = 21
|
||||||
|
Top = 46
|
||||||
|
Width = 191
|
||||||
|
TabOrder = 2
|
||||||
|
Text = 'Edit1'
|
||||||
|
end
|
||||||
|
object Panel1: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 50
|
||||||
|
Top = 269
|
||||||
|
Width = 425
|
||||||
|
Align = alBottom
|
||||||
|
ClientHeight = 50
|
||||||
|
ClientWidth = 425
|
||||||
|
TabOrder = 3
|
||||||
|
object toOpt: TButton
|
||||||
|
Left = 8
|
||||||
|
Height = 25
|
||||||
|
Top = 9
|
||||||
|
Width = 75
|
||||||
|
Caption = 'To Options'
|
||||||
|
OnClick = toOptClick
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
104
components/cmdlinecfg/trunk/testguibuild/mainform.pas
Normal file
104
components/cmdlinecfg/trunk/testguibuild/mainform.pas
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
unit mainform;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ValEdit,
|
||||||
|
StdCtrls, ExtCtrls
|
||||||
|
,cmdlinecfg , cmdlinelclctrlsbox, cmdlinecfgjson //, patheditor
|
||||||
|
,cmdlinecfgui, cmdlinecfguijson
|
||||||
|
,cmdlinecfgparser;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TForm1 }
|
||||||
|
|
||||||
|
TForm1 = class(TForm)
|
||||||
|
toOpt: TButton;
|
||||||
|
Edit1: TEdit;
|
||||||
|
Label1: TLabel;
|
||||||
|
Memo1: TMemo;
|
||||||
|
Panel1: TPanel;
|
||||||
|
Splitter1: TSplitter;
|
||||||
|
procedure FormCreate(Sender: TObject);
|
||||||
|
procedure FormDestroy(Sender: TObject);
|
||||||
|
procedure toOptClick(Sender: TObject);
|
||||||
|
private
|
||||||
|
{ private declarations }
|
||||||
|
ctrl : TCmdLineScrollBoxControl;
|
||||||
|
cfg : TCmdLineCfg;
|
||||||
|
lt : TCmdLineLayoutInfo;
|
||||||
|
public
|
||||||
|
{ public declarations }
|
||||||
|
procedure OnValueChanged(Sender: TObject);
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
Form1: TForm1;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{$R *.lfm}
|
||||||
|
|
||||||
|
{ TForm1 }
|
||||||
|
|
||||||
|
procedure TForm1.FormCreate(Sender: TObject);
|
||||||
|
begin
|
||||||
|
{cmdlinelclutils.ADirsDialogs:=DummyEditPaths;
|
||||||
|
cmdlinelclutils.AFilesDialogs:=DummyEditPaths;}
|
||||||
|
|
||||||
|
ctrl:=TCmdLineScrollBoxControl.Create(Self);
|
||||||
|
if ParamCount>0 then begin
|
||||||
|
cfg:=TCmdLineCfg.Create;
|
||||||
|
CmdLineCfgJSONReadFile(ParamStr(1), cfg);
|
||||||
|
if ParamCOunt>1 then begin
|
||||||
|
lt:=TCmdLineLayoutInfo.Create;
|
||||||
|
CmdLineUIJSONReadFile(PAramStr(2), lt);
|
||||||
|
end;
|
||||||
|
ctrl.Init(cfg, lt);
|
||||||
|
ctrl.OnValueChanged:=OnValueChanged;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TForm1.FormDestroy(Sender: TObject);
|
||||||
|
begin
|
||||||
|
ctrl.Free;
|
||||||
|
lt.Free;
|
||||||
|
cfg.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TForm1.toOptClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
vl : TList;
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
vl := TList.Create;
|
||||||
|
try
|
||||||
|
CmdLineMatchArgsToOpts(cfg, Memo1.Text, vl);
|
||||||
|
ctrl.SetValues(vl);
|
||||||
|
for i:=0 to vl.Count-1 do TObject(vl[i]).Free;
|
||||||
|
finally
|
||||||
|
vl.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TForm1.OnValueChanged(Sender: TObject);
|
||||||
|
var
|
||||||
|
l : TList;
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
l :=TList.create;
|
||||||
|
try
|
||||||
|
ctrl.Serialize(l);
|
||||||
|
Memo1.Text:=CmdLineMakeOptions(l);
|
||||||
|
for i:=0 to l.Count-1 do
|
||||||
|
TObject(l[i]).Free;
|
||||||
|
finally
|
||||||
|
l.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
106
components/cmdlinecfg/trunk/testguibuild/testguibuild.lpi
Normal file
106
components/cmdlinecfg/trunk/testguibuild/testguibuild.lpi
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="9"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<General>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
|
<Title Value="project1"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
<UseXPManifest Value="True"/>
|
||||||
|
<Icon Value="0"/>
|
||||||
|
</General>
|
||||||
|
<i18n>
|
||||||
|
<EnableI18N LFM="False"/>
|
||||||
|
</i18n>
|
||||||
|
<VersionInfo>
|
||||||
|
<StringTable ProductVersion=""/>
|
||||||
|
</VersionInfo>
|
||||||
|
<BuildModes Count="1">
|
||||||
|
<Item1 Name="Default" Default="True"/>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
||||||
|
<ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<local>
|
||||||
|
<FormatVersion Value="1"/>
|
||||||
|
</local>
|
||||||
|
</RunParams>
|
||||||
|
<RequiredPackages Count="1">
|
||||||
|
<Item1>
|
||||||
|
<PackageName Value="LCL"/>
|
||||||
|
</Item1>
|
||||||
|
</RequiredPackages>
|
||||||
|
<Units Count="4">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="testguibuild.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="testguibuild"/>
|
||||||
|
</Unit0>
|
||||||
|
<Unit1>
|
||||||
|
<Filename Value="mainform.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<ComponentName Value="Form1"/>
|
||||||
|
<HasResources Value="True"/>
|
||||||
|
<ResourceBaseClass Value="Form"/>
|
||||||
|
<UnitName Value="mainform"/>
|
||||||
|
</Unit1>
|
||||||
|
<Unit2>
|
||||||
|
<Filename Value="..\cmdlinelclctrlsbox.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="cmdlinelclctrlsbox"/>
|
||||||
|
</Unit2>
|
||||||
|
<Unit3>
|
||||||
|
<Filename Value="..\commonui\patheditor.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<ComponentName Value="PathEditorForm"/>
|
||||||
|
<HasResources Value="True"/>
|
||||||
|
<ResourceBaseClass Value="Form"/>
|
||||||
|
<UnitName Value="patheditor"/>
|
||||||
|
</Unit3>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="testguibuild"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<OtherUnitFiles Value="..;..\commonui"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<CodeGeneration>
|
||||||
|
<Checks>
|
||||||
|
<IOChecks Value="True"/>
|
||||||
|
<RangeChecks Value="True"/>
|
||||||
|
<OverflowChecks Value="True"/>
|
||||||
|
<StackChecks Value="True"/>
|
||||||
|
</Checks>
|
||||||
|
</CodeGeneration>
|
||||||
|
<Other>
|
||||||
|
<CompilerMessages>
|
||||||
|
<MsgFileName Value=""/>
|
||||||
|
</CompilerMessages>
|
||||||
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions Count="3">
|
||||||
|
<Item1>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item3>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
23
components/cmdlinecfg/trunk/testguibuild/testguibuild.lpr
Normal file
23
components/cmdlinecfg/trunk/testguibuild/testguibuild.lpr
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
program testguibuild;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
heaptrc,
|
||||||
|
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||||
|
cthreads,
|
||||||
|
{$ENDIF}{$ENDIF}
|
||||||
|
Interfaces, // this includes the LCL widgetset
|
||||||
|
Forms, mainform, cmdlinelclctrlsbox//, patheditor
|
||||||
|
{ you can add units after this };
|
||||||
|
|
||||||
|
{$R *.res}
|
||||||
|
|
||||||
|
begin
|
||||||
|
SetHeapTraceOutput('test.txt');
|
||||||
|
RequireDerivedFormResource := True;
|
||||||
|
Application.Initialize;
|
||||||
|
Application.CreateForm(TForm1, Form1);
|
||||||
|
Application.Run;
|
||||||
|
end.
|
||||||
|
|
86
components/cmdlinecfg/trunk/testlazopt.lpi
Normal file
86
components/cmdlinecfg/trunk/testlazopt.lpi
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="9"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<General>
|
||||||
|
<Flags>
|
||||||
|
<MainUnitHasCreateFormStatements Value="False"/>
|
||||||
|
<MainUnitHasTitleStatement Value="False"/>
|
||||||
|
</Flags>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
|
<Title Value="testlazopt"/>
|
||||||
|
<UseAppBundle Value="False"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
</General>
|
||||||
|
<i18n>
|
||||||
|
<EnableI18N LFM="False"/>
|
||||||
|
</i18n>
|
||||||
|
<VersionInfo>
|
||||||
|
<StringTable ProductVersion=""/>
|
||||||
|
</VersionInfo>
|
||||||
|
<BuildModes Count="1">
|
||||||
|
<Item1 Name="Default" Default="True"/>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<local>
|
||||||
|
<FormatVersion Value="1"/>
|
||||||
|
</local>
|
||||||
|
</RunParams>
|
||||||
|
<RequiredPackages Count="2">
|
||||||
|
<Item1>
|
||||||
|
<PackageName Value="IDEIntf"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<PackageName Value="LCL"/>
|
||||||
|
</Item2>
|
||||||
|
</RequiredPackages>
|
||||||
|
<Units Count="2">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="testlazopt.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="testlazopt"/>
|
||||||
|
</Unit0>
|
||||||
|
<Unit1>
|
||||||
|
<Filename Value="cmdlinelazcompopt.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="cmdlinelazcompopt"/>
|
||||||
|
</Unit1>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="testlazopt"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<OtherUnitFiles Value="c:\library\;c:\library2\"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Other>
|
||||||
|
<CompilerMessages>
|
||||||
|
<MsgFileName Value=""/>
|
||||||
|
</CompilerMessages>
|
||||||
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions Count="3">
|
||||||
|
<Item1>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item3>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
14
components/cmdlinecfg/trunk/testlazopt.lpr
Normal file
14
components/cmdlinecfg/trunk/testlazopt.lpr
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
program testlazopt;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||||
|
cthreads,
|
||||||
|
{$ENDIF}{$ENDIF}
|
||||||
|
Interfaces,
|
||||||
|
Classes;
|
||||||
|
|
||||||
|
begin
|
||||||
|
end.
|
||||||
|
|
74
components/cmdlinecfg/trunk/testmakeline.lpi
Normal file
74
components/cmdlinecfg/trunk/testmakeline.lpi
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="9"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<General>
|
||||||
|
<Flags>
|
||||||
|
<MainUnitHasCreateFormStatements Value="False"/>
|
||||||
|
<MainUnitHasTitleStatement Value="False"/>
|
||||||
|
</Flags>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
|
<Title Value="project1"/>
|
||||||
|
<UseAppBundle Value="False"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
</General>
|
||||||
|
<i18n>
|
||||||
|
<EnableI18N LFM="False"/>
|
||||||
|
</i18n>
|
||||||
|
<VersionInfo>
|
||||||
|
<StringTable ProductVersion=""/>
|
||||||
|
</VersionInfo>
|
||||||
|
<BuildModes Count="1">
|
||||||
|
<Item1 Name="Default" Default="True"/>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
||||||
|
<ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<local>
|
||||||
|
<FormatVersion Value="1"/>
|
||||||
|
</local>
|
||||||
|
</RunParams>
|
||||||
|
<Units Count="1">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="testmakeline.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="testmakeline"/>
|
||||||
|
</Unit0>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="testmakeline"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Other>
|
||||||
|
<CompilerMessages>
|
||||||
|
<MsgFileName Value=""/>
|
||||||
|
</CompilerMessages>
|
||||||
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions Count="3">
|
||||||
|
<Item1>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item3>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
31
components/cmdlinecfg/trunk/testmakeline.lpr
Normal file
31
components/cmdlinecfg/trunk/testmakeline.lpr
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
program testmakeline;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, cmdlinecfg, cmdlinecfgutils, cmdlinecfgjson;
|
||||||
|
|
||||||
|
var
|
||||||
|
cfg : TCmdLineCfg;
|
||||||
|
vals : TList;
|
||||||
|
begin
|
||||||
|
if ParamCount=0 then begin
|
||||||
|
writeln('please specify a configuration file');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
cfg := TCmdLineCfg.Create;
|
||||||
|
vals:= TList.Create;
|
||||||
|
try
|
||||||
|
CmdLineCfgJSONReadFile(ParamStr(1), cfg);
|
||||||
|
vals.Add(TCmdLineOptionValue.Create( cfg.FindOption('instructionset'), 'PENTIUM' ));
|
||||||
|
vals.Add(TCmdLineOptionValue.Create( cfg.FindOption('generatelinkmap'), '-1' ));
|
||||||
|
vals.Add(TCmdLineOptionValue.Create( cfg.FindOption('shownotes'), '1' ));
|
||||||
|
vals.Add(TCmdLineOptionValue.Create( cfg.FindOption('showhints'), '1' ));
|
||||||
|
writeln( CmdLineMakeOptions ( vals ));
|
||||||
|
finally
|
||||||
|
vals.Free;
|
||||||
|
cfg.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
74
components/cmdlinecfg/trunk/testuijson.lpi
Normal file
74
components/cmdlinecfg/trunk/testuijson.lpi
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="9"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<General>
|
||||||
|
<Flags>
|
||||||
|
<MainUnitHasCreateFormStatements Value="False"/>
|
||||||
|
<MainUnitHasTitleStatement Value="False"/>
|
||||||
|
</Flags>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
|
<Title Value="testuijson"/>
|
||||||
|
<UseAppBundle Value="False"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
</General>
|
||||||
|
<i18n>
|
||||||
|
<EnableI18N LFM="False"/>
|
||||||
|
</i18n>
|
||||||
|
<VersionInfo>
|
||||||
|
<StringTable ProductVersion=""/>
|
||||||
|
</VersionInfo>
|
||||||
|
<BuildModes Count="1">
|
||||||
|
<Item1 Name="Default" Default="True"/>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
||||||
|
<ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<local>
|
||||||
|
<FormatVersion Value="1"/>
|
||||||
|
</local>
|
||||||
|
</RunParams>
|
||||||
|
<Units Count="1">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="testuijson.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="testuijson"/>
|
||||||
|
</Unit0>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="testuijson"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Other>
|
||||||
|
<CompilerMessages>
|
||||||
|
<MsgFileName Value=""/>
|
||||||
|
</CompilerMessages>
|
||||||
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions Count="3">
|
||||||
|
<Item1>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item3>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
41
components/cmdlinecfg/trunk/testuijson.lpr
Normal file
41
components/cmdlinecfg/trunk/testuijson.lpr
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
program testuijson;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, cmdlinecfgui, cmdlinecfguijson;
|
||||||
|
|
||||||
|
procedure DebugSection(sc: TLayoutSection);
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
if sc.Name<>'' then writeln(sc.Display, ' (', sc.Name,')');
|
||||||
|
for i:=0 to sc.ElemCount-1 do begin
|
||||||
|
if sc.Elements[i].ElementType=letSwitch then
|
||||||
|
writeln(' ', sc.Elements[i].Name)
|
||||||
|
else
|
||||||
|
DebugSection(sc.Elements[i]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TestUIConfFile(const fn: string);
|
||||||
|
var
|
||||||
|
layout : TCmdLineLayoutInfo;
|
||||||
|
begin
|
||||||
|
layout:=TCmdLineLayoutInfo.Create;
|
||||||
|
try
|
||||||
|
CmdLineUIJSONReadFile(fn, layout);
|
||||||
|
DebugSection(layout.GetSection(''));
|
||||||
|
finally
|
||||||
|
layout.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if ParamCount=0 then begin
|
||||||
|
writeln('Please specify UI configuration file');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
TestUIConfFile(ParamStr(1));
|
||||||
|
end.
|
||||||
|
|
Reference in New Issue
Block a user