فهرست منبع

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

Reintegrate fpcres-rc branch by Martok

git-svn-id: trunk@46387 -
svenbarth 5 سال پیش
والد
کامیت
5eabf9851e

+ 14 - 1
packages/fcl-res/src/rcreader.pp

@@ -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

+ 9 - 3
packages/fcl-res/src/yyinclude.pp

@@ -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;

+ 1 - 1
packages/fcl-res/src/yypreproc.pp

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

+ 6 - 0
utils/fpcres/fpcres.pas

@@ -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

+ 54 - 0
utils/fpcres/paramparser.pas

@@ -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.

+ 15 - 1
utils/fpcres/sourcehandler.pas

@@ -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');