fcl-res, fpcres: command line switches for include and defines

Reintegrate fpcres-rc branch by Martok

git-svn-id: trunk@46387 -
This commit is contained in:
svenbarth 2020-08-12 19:06:20 +00:00
parent a2750fc5dc
commit 5eabf9851e
6 changed files with 99 additions and 6 deletions

View File

@ -30,6 +30,8 @@ type
private
fExtensions : string;
fDescription : string;
fRCIncludeDirs: TStringList;
fRCDefines: TStringList;
protected
function GetExtensions : string; override;
function GetDescription : string; override;
@ -39,6 +41,8 @@ type
public
constructor Create; override;
destructor Destroy; override;
property RCIncludeDirs: TStringList read fRCIncludeDirs;
property RCDefines: TStringList read fRCDefines;
end;
implementation
@ -81,6 +85,8 @@ begin
end;
procedure TRCResourceReader.ReadRCFile(aResources: TResources; aLocation: String; aStream: TStream);
var
i: Integer;
begin
AssignStream(lexlib.yyinput, aStream);
Reset(lexlib.yyinput);
@ -90,8 +96,11 @@ begin
SetTextCodePage(lexlib.yyinput, rcparser.opt_code_page);
rcparser.yinclude:= tyinclude.Create;
rcparser.yinclude.WorkDir:= aLocation;
rcparser.yinclude.SearchPaths.Assign(fRCIncludeDirs);
rcparser.ypreproc:= typreproc.Create;
rcparser.ypreproc.Defines.Add('RC_INVOKED', '');
for i:= 0 to fRCDefines.Count-1 do
rcparser.ypreproc.Defines.Items[fRCDefines.Names[i]]:= fRCDefines.ValueFromIndex[i];
rcparser.aktresources:= aResources;
if rcparser.yyparse <> 0 then
raise EReadError.Create('Parse Error');
@ -106,11 +115,15 @@ constructor TRCResourceReader.Create;
begin
fExtensions:='.rc';
fDescription:='RC script resource reader';
fRCDefines:= TStringList.Create;
fRCIncludeDirs:= TStringList.Create;
end;
destructor TRCResourceReader.Destroy;
begin
fRCIncludeDirs.Free;
fRCDefines.Free;
inherited;
end;
initialization

View File

@ -90,14 +90,20 @@ begin
if FileExists(f) then
Exit(f);
end;
yyerror('Invalid file not found on search paths: "'+fn+'"');
yyerror('Include file not found on search paths: <'+fn+'>');
end
else if (fn[1] = '"') and (fn[length(fn)] = '"') then begin
fn:= copy(fn, 2, Length(fn)-2);
f:= ConcatPaths([WorkDir, fn]);
if FileExists(f) then
Exit(f);
yyerror('Invalid file not found: "'+fn+'"');
if fn = 'windows.h' then begin
// treat windows.h as an alias for windres.h
f:= ConcatPaths([WorkDir, 'windres.h']);
if FileExists(f) then
Exit(f);
end;
yyerror('Include file not found: "'+fn+'"');
end;
end;
yyerror('Invalid include directive: "'+fn+'"');
@ -105,7 +111,7 @@ end;
constructor tyinclude.Create;
begin
inherited;
inherited Create;
level:= 0;
WorkDir:= GetCurrentDir;
SearchPaths:= TStringList.Create;

View File

@ -27,7 +27,7 @@ var
constructor typreproc.Create;
begin
inherited;
inherited Create;
Defines:= TFPStringHashTable.Create;
level:= 0;
cheadermode:= false;

View File

@ -65,6 +65,10 @@ begin
writeln(' --version, -V Show program version.');
writeln(' --verbose, -v Be verbose.');
writeln(' --input, -i <x> Ignored for compatibility.');
writeln(' --include, -I <x> RC files: add a path for include searches');
writeln(' --define, -D <sym>[=<val>]');
writeln(' RC files: define a symbol (and value)');
writeln(' --undefine, -U <sym> RC files: undefine a symbol');
writeln(' --output, -o <x> Set the output file name.');
writeln(' -of <format> Set the output file format. Supported formats:');
writeln(' res, elf, coff, mach-o, external');
@ -212,6 +216,8 @@ begin
resources:=TResources.Create;
sourcefiles:=TSourceFiles.Create;
sourcefiles.FileList.AddStrings(params.InputFiles);
sourcefiles.RCDefines.AddStrings(params.RCDefines);
sourcefiles.RCIncludeDirs.AddStrings(params.RCIncludeDirs);
try
sourcefiles.Load(resources);
except

View File

@ -45,8 +45,12 @@ type
fInputFiles : TStringList;
fOutputFile : string;
fTarget : TResTarget;
fRCIncludeDirs: TStringList;
fRCDefines: TStringList;
procedure ParseInputFiles(aList : TStringList; var index : integer; const parname : string);
procedure ParseRCInclude(aList: TStringList; var index: integer; const parname: string);
procedure ParseRCUnDefine(aList: TStringList; var index: integer; const parname: string);
procedure ParseOutputFile(aList : TStringList; var index : integer; const parname : string);
procedure ParseOutputFormat(aList : TStringList; var index : integer; const parname : string);virtual;
procedure ParseArchitecture(aList : TStringList; var index : integer; const parname : string);virtual;
@ -65,6 +69,8 @@ type
property Version : boolean read fVersion;
property Verbose : boolean read fVerbose;
property InputFiles : TStringList read fInputFiles;
property RCIncludeDirs: TStringList read fRCIncludeDirs;
property RCDefines: TStringList read fRCDefines;
property OutputFile : string read fOutputFile write fOutputFile;
property Target : TResTarget read fTarget;
end;
@ -195,6 +201,42 @@ begin
end;
end;
procedure TParameters.ParseRCInclude(aList: TStringList; var index: integer;
const parname : string);
var
tmp: String;
begin
inc(index);
tmp:=DoMandatoryArgument(aList,index);
if tmp='' then
raise EArgumentMissingException.Create(parname);
fRCIncludeDirs.Add(tmp);
end;
procedure TParameters.ParseRCUnDefine(aList: TStringList; var index: integer;
const parname : string);
var
tmp: String;
i: integer;
begin
inc(index);
tmp:=DoMandatoryArgument(aList,index);
if tmp='' then
raise EArgumentMissingException.Create(parname);
if (parname='-D') or (parname='--define') then begin
i:= pos('=', tmp);
if i<1 then
fRCDefines.Values[tmp]:= ''
else
fRCDefines.Values[Copy(tmp, 1, i-1)]:= Copy(tmp, i+1);
end else begin
i:= fRCDefines.IndexOfName(tmp);
if i >= 0 then
fRCDefines.Delete(i);
end;
fRCIncludeDirs.Add(tmp);
end;
procedure TParameters.ParseOutputFile(aList: TStringList; var index: integer;
const parname : string);
begin
@ -361,6 +403,11 @@ begin
fVerbose:=true
else if ((tmp='-i') or (tmp='--input')) then
ParseInputFiles(fList,i,tmp)
else if ((tmp='-I') or (tmp='--include')) then
ParseRCInclude(fList,i,tmp)
else if ((tmp='-D') or (tmp='--define'))
or ((tmp='-U') or (tmp='--undefine')) then
ParseRCUnDefine(fList,i,tmp)
else if ((tmp='-o') or (tmp='--output')) then
ParseOutputFile(fList,i,tmp)
else if (tmp='-of') then
@ -386,10 +433,14 @@ end;
constructor TParameters.Create;
begin
inherited Create;
fHelp:=false;
fVersion:=false;
fVerbose:=false;
fInputFiles:=TStringList.Create;
fRCIncludeDirs:= TStringList.Create;
fRCIncludeDirs.Duplicates:= dupIgnore;
fRCDefines:= TStringList.Create;
fOutputFile:='';
fTarget.machine:=mtnone;
GetDefaultSubMachineForMachine(fTarget.machine);
@ -398,7 +449,10 @@ end;
destructor TParameters.Destroy;
begin
fRCDefines.Free;
fRCIncludeDirs.Free;
fInputFiles.Free;
inherited;
end;
end.

View File

@ -36,33 +36,43 @@ type
private
protected
fFileList : TStringList;
fRCIncludeDirs: TStringList;
fRCDefines: TStringList;
fStreamList : TFPList;
public
constructor Create;
destructor Destroy; override;
procedure Load(aResources : TResources);
property FileList : TStringList read fFileList;
property RCIncludeDirs: TStringList read fRCIncludeDirs;
property RCDefines: TStringList read fRCDefines;
end;
implementation
uses msghandler, closablefilestream;
uses msghandler, closablefilestream, rcreader;
{ TSourceFiles }
constructor TSourceFiles.Create;
begin
inherited Create;
fFileList:=TStringList.Create;
fStreamList:=TFPList.Create;
fRCDefines:= TStringList.Create;
fRCIncludeDirs:= TStringList.Create;
end;
destructor TSourceFiles.Destroy;
var i : integer;
begin
fRCIncludeDirs.Free;
fRCDefines.Free;
fFileList.Free;
for i:=0 to fStreamList.Count-1 do
TStream(fStreamList[i]).Free;
fStreamList.Free;
inherited;
end;
procedure TSourceFiles.Load(aResources: TResources);
@ -90,6 +100,10 @@ begin
Messages.DoVerbose(Format('Chosen reader: %s',[aReader.Description]));
try
Messages.DoVerbose('Reading resource information...');
if aReader is TRCResourceReader then begin
TRCResourceReader(aReader).RCIncludeDirs.Assign(fRCIncludeDirs);
TRCResourceReader(aReader).RCDefines.Assign(fRCDefines);
end;
tmpres.LoadFromStream(aStream,aReader);
aResources.MoveFrom(tmpres);
Messages.DoVerbose('Resource information read');