* importtl new parameter --ref-style that allows to set different styles for reference input param. (var, constref or const [ref])

A more complete solution for bugreport #30764. 
Changed importtl to getopts for param parsing

git-svn-id: trunk@38338 -
This commit is contained in:
marco 2018-02-25 14:52:51 +00:00
parent 6e811d057c
commit d49deb183b
2 changed files with 87 additions and 35 deletions

View File

@ -39,6 +39,12 @@ interface
uses uses
Classes, SysUtils,comobj,activex,windows; Classes, SysUtils,comobj,activex,windows;
// Style of input ref parameters:
Type
TParamInputRefType = (ParamInputVar, // old delphi [in] becomes VAR, Default
ParamInputConstRef, // (old) FPC [in] becomes CONSTREF
ParamInputConstRefDelphi); // XE3+ style CONST [Ref]
{ {
Reads type information from 'FileName' and converts it in a freepascal binding unit. The Reads type information from 'FileName' and converts it in a freepascal binding unit. The
contents of the unit is returned as the function result. contents of the unit is returned as the function result.
@ -52,12 +58,12 @@ To load a different type of library resource, append an integer index to 'FileNa
Example: C:\WINDOWS\system32\msvbvm60.dll\3 Example: C:\WINDOWS\system32\msvbvm60.dll\3
} }
function ImportTypelib(FileName: WideString;var sUnitName:string;var slDependencies:TStringList; function ImportTypelib(FileName: WideString;var sUnitName:string;var slDependencies:TStringList;
bActiveX,bPackage,bRemoveStructTag:boolean;var sPackageSource,sPackageRegUnitSource:String):string; bActiveX,bPackage,bRemoveStructTag:boolean;var sPackageSource,sPackageRegUnitSource:String;inreftype :TParamInputRefType = ParamInputVar):string;
Type Type
{ TTypeLibImporter } { TTypeLibImporter }
TTypeLibImporter = Class(TComponent) TTypeLibImporter = Class(TComponent)
@ -65,6 +71,7 @@ Type
FActiveX: Boolean; FActiveX: Boolean;
FAppendVersionNumber: Boolean; FAppendVersionNumber: Boolean;
FCreatePackage: Boolean; FCreatePackage: Boolean;
FInParamRefStyle : TParamInputRefType;
FDependencies: TStringList; FDependencies: TStringList;
FRemoveStructTag: Boolean; FRemoveStructTag: Boolean;
FUnitSource: TStringList; FUnitSource: TStringList;
@ -157,6 +164,8 @@ Type
Property RemoveStructTag : Boolean read FRemoveStructTag write SetRemoveStructTag Default False; Property RemoveStructTag : Boolean read FRemoveStructTag write SetRemoveStructTag Default False;
// Set automatically by OutputFileName or by Execute // Set automatically by OutputFileName or by Execute
Property UnitName : string Read FUnitname Write SetUnitName; Property UnitName : string Read FUnitname Write SetUnitName;
// generate constref for [in] parameters instead of delphi compatible VAR, mantis 30764
Property InParamRefStyle : TParamInputRefType read fInParamRefStyle write FInParamRefStyle;
end; end;
@ -166,7 +175,7 @@ Resourcestring
SErrInvalidUnitName = 'Invalid unit name : %s'; SErrInvalidUnitName = 'Invalid unit name : %s';
function ImportTypelib(FileName: WideString;var sUnitName:string;var slDependencies:TStringList; function ImportTypelib(FileName: WideString;var sUnitName:string;var slDependencies:TStringList;
bActiveX,bPackage,bRemoveStructTag:boolean;var sPackageSource,sPackageRegUnitSource:String):string; bActiveX,bPackage,bRemoveStructTag:boolean;var sPackageSource,sPackageRegUnitSource:String;inreftype :TParamInputRefType = ParamInputVar):string;
var i:integer; var i:integer;
begin begin
With TTypeLibImporter.Create(Nil) do With TTypeLibImporter.Create(Nil) do
@ -175,11 +184,13 @@ begin
ActiveX:=bActiveX; ActiveX:=bActiveX;
CreatePackage:=bPackage; CreatePackage:=bPackage;
RemoveStructTag:=bRemoveStructTag; RemoveStructTag:=bRemoveStructTag;
InParamRefStyle :=inreftype;
Execute; Execute;
Result:=UnitSource.Text; Result:=UnitSource.Text;
sUnitname:=UnitName; sUnitname:=UnitName;
sPackageSource:=FPackageSource.Text; sPackageSource:=FPackageSource.Text;
sPackageRegUnitSource:=FPackageRegUnitSource.Text; sPackageRegUnitSource:=FPackageRegUnitSource.Text;
if Assigned(slDependencies) then if Assigned(slDependencies) then
begin //add new dependencies begin //add new dependencies
for i:=0 to Dependencies.Count-1 do for i:=0 to Dependencies.Count-1 do
@ -643,7 +654,12 @@ begin
case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and (PARAMFLAG_FIN or PARAMFLAG_FOUT) of case FD^.lprgelemdescParam[k].paramdesc.wParamFlags and (PARAMFLAG_FIN or PARAMFLAG_FOUT) of
PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var '; PARAMFLAG_FIN or PARAMFLAG_FOUT:sPar:='var ';
PARAMFLAG_FOUT:sPar:='out '; PARAMFLAG_FOUT:sPar:='out ';
PARAMFLAG_FIN:sPar:='var '; //constref in safecall? TBD PARAMFLAG_NONE,
PARAMFLAG_FIN: case FInParamRefStyle of
ParamInputVar : sPar:='var '; //constref in safecall? TBD
ParamInputConstRef : sPar:='constref ';
ParamInputConstRefDelphi : sPar:='const [ref] ';
end;
end; end;
if not MakeValidId(GetName(k+1),sVarName) then if not MakeValidId(GetName(k+1),sVarName) then
AddToHeader('// Warning: renamed parameter ''%s'' in %s.%s to ''%s''',[GetName(k+1),iname,sMethodName,sVarName],True); AddToHeader('// Warning: renamed parameter ''%s'' in %s.%s to ''%s''',[GetName(k+1),iname,sMethodName,sVarName],True);

View File

@ -3,7 +3,29 @@ program importtl;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{$apptype console} {$apptype console}
uses uses
classes,typelib,sysutils; classes,typelib,sysutils,getopts;
var
theopts : array[1..2] of TOption;
procedure InitOptions;
begin
with theopts[1] do
begin
name:='ref-style';
has_arg:=Required_Argument;
flag:=nil;
value:=#0;
end;
with theopts[2] do
begin
name:='';
has_arg:=0;
flag:=nil;
value:=#0;
end;
end;
var var
unitname,sPackageSource,sPackageRegUnitSource:string; unitname,sPackageSource,sPackageRegUnitSource:string;
@ -11,41 +33,53 @@ var
F:text; F:text;
slDep:TStringList; slDep:TStringList;
i:integer; i:integer;
FileName : string;
bNoRecurse,bHelp,bActiveX,bPackage,bRemoveStructTag:boolean; bNoRecurse,bHelp,bActiveX,bPackage,bRemoveStructTag:boolean;
InRefStyle : TParamInputRefType;
optionindex : Longint;
c:char;
begin begin
InitOptions;
slDep:=TStringList.Create; slDep:=TStringList.Create;
bNoRecurse:=false; bNoRecurse:=false;
bHelp:=false; bHelp:=false;
bActiveX:=false; bActiveX:=false;
bPackage:=false; bPackage:=false;
i:=1; InRefStyle:=ParamInputVar;
while i<=Paramcount do
begin repeat
if pos('-n',ParamStr(i))>0 then bNoRecurse:=true c:=getlongopts('ad:hnpt',@theopts[1],optionindex);
else if pos('-a',ParamStr(i))>0 then bActiveX:=true case c of
else if pos('-h',ParamStr(i))>0 then bHelp:=true #0 : begin
else if pos('-p',ParamStr(i))>0 then bPackage:=true case optionindex-1 of
else if pos('-t',ParamStr(i))>0 then bRemoveStructTag:=true 0 : if lowercase(optarg)='var' then
else if pos('-d',ParamStr(i))>0 then InRefStyle:=ParamInputVar
begin else
sOutDir:=trim(copy(ParamStr(i), pos('-d',ParamStr(i))+2, 260)); // windows MAX_PATH if lowercase(optarg)='constref' then
if sOutDir='' then InRefStyle:=ParamInputConstRef
if i<Paramcount-1 then else
begin if lowercase(optarg)='constrefdelphi' then
i:=i+1; InRefStyle:=ParamInputConstRefDelphi
sOutDir:=trim(ParamStr(i)); end;
end end;
else 'n' : bNoRecurse:=true;
begin 'a' : bActiveX:=true;
bHelp:=true; 'p' : bPackage:=true;
sOutDir:='\'; 'h' : bHelp:=true;
end; 't' : bRemoveStructTag:=true;
if not (sOutDir[length(sOutDir)] in [':','\']) then 'd' : if (length(optarg)>0) and (optarg[1]='-') then
sOutDir:=sOutDir+'\'; bHelp:=true
end; else
i:=i+1; sOutDir:=IncludeTrailingPathDelimiter(optarg);
end; '?',':' : writeln ('Error parsing option : ',optopt);
if bHelp or (Paramcount=0) or (pos('-',paramstr(Paramcount))=1) then end; { case }
until c=endofoptions;
FileName:='';
if optind=paramcount then
FileName:=paramstr(optind);
if bHelp or (Paramcount=0) or (filename='')then
begin begin
writeln('Usage: importtl [options] file'); writeln('Usage: importtl [options] file');
writeln('Reads type information from "file" and converts it into a freepascal binding'); writeln('Reads type information from "file" and converts it into a freepascal binding');
@ -58,13 +92,15 @@ begin
writeln(' dependencies.'); writeln(' dependencies.');
writeln(' -p : create lazarus package for ActiveXContainer descendants'); writeln(' -p : create lazarus package for ActiveXContainer descendants');
writeln(' -t : remove "tag" prefix from structs'); writeln(' -t : remove "tag" prefix from structs');
exit; writeln(' --ref-style st : input parameter style, parameter st=var,constref');
writeln(' or constrefdelphi (= XE3+ const [ref])');
halt;
end; end;
slDep.Add(paramstr(Paramcount)); slDep.Add(paramstr(Paramcount));
i:=0; i:=0;
repeat repeat
writeln('Reading typelib from '+slDep[i]+ ' ...'); writeln('Reading typelib from '+slDep[i]+ ' ...');
sTL:=ImportTypelib(slDep[i],unitname,slDep,bActiveX,bPackage,bRemoveStructTag,sPackageSource,sPackageRegUnitSource); sTL:=ImportTypelib(slDep[i],unitname,slDep,bActiveX,bPackage,bRemoveStructTag,sPackageSource,sPackageRegUnitSource,InRefStyle);
unitname:=sOutDir+unitname; unitname:=sOutDir+unitname;
if (bPackage) and (sPackageSource<>'') then if (bPackage) and (sPackageSource<>'') then
begin begin