webidl2pas.pp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. {
  2. This file is part of the Free Component Library
  3. WEBIDL to pascal code converter program
  4. Copyright (c) 2018 by Michael Van Canneyt [email protected]
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. program webidl2pas;
  12. {$mode objfpc}{$H+}
  13. uses
  14. Classes, SysUtils, CustApp, webidlscanner, webidltopas, pascodegen, typinfo;
  15. type
  16. TWebIDLToPasFormat = (
  17. wifPas2js,
  18. wifWasmJob
  19. );
  20. const
  21. WebIDLToPasFormatNames: array[TWebIDLToPasFormat] of string = (
  22. 'pas2js',
  23. 'wasmjob'
  24. );
  25. type
  26. { TWebIDLToPasApplication }
  27. TWebIDLToPasApplication = class(TCustomApplication)
  28. private
  29. FOutputFormat: TWebIDLToPasFormat;
  30. FWebIDLToPas: TBaseWebIDLToPas;
  31. function Checkoption(Var O: TConversionOptions; C: TCOnversionOPtion;
  32. const AShort: Char; const aLong: String): Boolean;
  33. procedure DoConvertLog(Sender: TObject; {%H-}LogType: TCodegenLogType; const Msg: String);
  34. function GetInputFileName: String;
  35. function GetOutputFileName: String;
  36. function GetUnitName: String;
  37. procedure SetinputFileName(AValue: String);
  38. procedure SetOutputFileName(AValue: String);
  39. procedure SetunitName(AValue: String);
  40. protected
  41. procedure DoRun; override;
  42. procedure InitWebIDLToPas; virtual;
  43. Protected
  44. Property WebIDLToPas : TBaseWebIDLToPas Read FWebIDLToPas;
  45. public
  46. constructor Create(TheOwner: TComponent); override;
  47. destructor Destroy; override;
  48. procedure WriteHelp(Const Msg : string); virtual;
  49. Property UnitName : String Read GetUnitName Write SetunitName;
  50. property InputFileName : String Read GetInputFileName Write SetinputFileName;
  51. property OutputFileName : String Read GetOutputFileName Write SetOutputFileName;
  52. property OutputFormat: TWebIDLToPasFormat read FOutputFormat write FOutputFormat;
  53. end;
  54. { TWebIDLToPasApplication }
  55. function TWebIDLToPasApplication.GetInputFileName: String;
  56. begin
  57. Result:=FWebIDLToPas.InputFileName;
  58. end;
  59. procedure TWebIDLToPasApplication.DoConvertLog(Sender: TObject;
  60. LogType: TCodegenLogType; const Msg: String);
  61. begin
  62. {AllowWriteln}
  63. Writeln(Msg);
  64. {AllowWriteln-}
  65. end;
  66. function TWebIDLToPasApplication.GetOutputFileName: String;
  67. begin
  68. Result:=FWebIDLToPas.OutputFileName
  69. end;
  70. function TWebIDLToPasApplication.GetUnitName: String;
  71. begin
  72. Result:=FWebIDLToPas.OutputUnitName;
  73. end;
  74. procedure TWebIDLToPasApplication.SetinputFileName(AValue: String);
  75. begin
  76. FWebIDLToPas.InputFileName:=aValue;
  77. end;
  78. procedure TWebIDLToPasApplication.SetOutputFileName(AValue: String);
  79. begin
  80. FWebIDLToPas.OutputFileName:=aValue;
  81. end;
  82. procedure TWebIDLToPasApplication.SetunitName(AValue: String);
  83. begin
  84. FWebIDLToPas.OutputUnitName:=aValue;
  85. end;
  86. function TWebIDLToPasApplication.Checkoption(var O: TConversionOptions;
  87. C: TCOnversionOPtion; const AShort: Char; const aLong: String): Boolean;
  88. begin
  89. Result:=HasOption(aShort,ALong);
  90. if Result then
  91. Include(O,C);
  92. end;
  93. procedure TWebIDLToPasApplication.DoRun;
  94. procedure E(const Msg: string);
  95. begin
  96. writeln('Error: ',Msg);
  97. Halt(1);
  98. end;
  99. var
  100. A,ErrorMsg: String;
  101. O : TConversionOptions;
  102. I : Integer;
  103. ok: Boolean;
  104. f: TWebIDLToPasFormat;
  105. begin
  106. Terminate;
  107. // quick check parameters
  108. ErrorMsg:=CheckOptions('ced::hi:m:n:o:pt:u:vw:x:', [
  109. 'help',
  110. 'constexternal',
  111. 'dicttoclass::',
  112. 'expandunionargs',
  113. 'outputformat:',
  114. 'input:',
  115. 'implementation:',
  116. 'include:',
  117. 'output:',
  118. 'optionsinheader',
  119. 'typealiases:',
  120. 'unitname:',
  121. 'verbose',
  122. 'webidlversion:',
  123. 'extra:'
  124. ]);
  125. if (ErrorMsg<>'') or HasOption('h','help') then
  126. begin
  127. WriteHelp(ErrorMsg);
  128. if ErrorMsg<>'' then
  129. Halt(1)
  130. else
  131. Exit;
  132. end;
  133. // first read outputformat and create FWebIDLToPas
  134. if HasOption('f','outputformat') then
  135. begin
  136. A:=GetOptionValue('f','outputformat');
  137. ok:=false;
  138. for f in TWebIDLToPasFormat do
  139. begin
  140. if SameText(A,WebIDLToPasFormatNames[f]) then
  141. begin
  142. OutputFormat:=f;
  143. ok:=true;
  144. end;
  145. end;
  146. if not ok then
  147. E('unknown outputformat "'+A+'"');
  148. end;
  149. InitWebIDLToPas;
  150. // then set verbosity
  151. FWebIDLToPas.Verbose:=HasOption('v','verbose');
  152. // read other options
  153. O:=[];
  154. Checkoption(O,coExternalConst,'c','constexternal');
  155. if Checkoption(O,coDictionaryAsClass,'d','dicttoclass') then
  156. FWebIDLToPas.DictionaryClassParent:=GetOptionValue('d','dicttoclass');
  157. Checkoption(O,coExpandUnionTypeArgs,'e','expandunionargs');
  158. InputFileName:=GetOptionValue('i','input');
  159. if HasOption('m','implementation') then
  160. FWebIDLToPas.IncludeImplementationCode.LoadFromFile(GetOptionValue('m','implementation'));
  161. if HasOption('n','include') then
  162. FWebIDLToPas.IncludeInterfaceCode.LoadFromFile(GetOptionValue('n','include'));
  163. OutputFileName:=GetOptionValue('o','output');
  164. CheckOption(O,coAddOptionsToHeader,'p','optionsinheader');
  165. FWebIDLToPas.Options:=O;
  166. A:=GetOptionValue('t','typealiases');
  167. if (Copy(A,1,1)='@') then
  168. begin
  169. Delete(A,1,1);
  170. FWebIDLToPas.TypeAliases.LoadFromFile(A);
  171. end
  172. else
  173. FWebIDLToPas.TypeAliases.CommaText:=A;
  174. UnitName:=GetOptionValue('u','unitname');
  175. if UnitName='' then
  176. UnitName:=ChangeFileExt(ExtractFileName(InputFileName),'');
  177. if OutputFileName='' then
  178. begin
  179. if (UnitName<>'') then
  180. OutputFileName:=ExtractFilePath(InputFileName)+UnitName+'.pas';
  181. end;
  182. if HasOption('w','webidlversion') then
  183. begin
  184. A:=GetOptionValue('w','webidlversion');
  185. I:=GetEnumValue(TypeInfo(TWebIDLVersion),A);
  186. if (I<>-1) then
  187. FWebIDLToPas.WebIDLVersion:=TWebIDLVersion(I)
  188. else
  189. E('Invalid webidl version: "'+A+'"');
  190. end;
  191. FWebIDLToPas.ExtraUnits:=GetOptionValue('x','extra');
  192. FWebIDLToPas.Execute;
  193. // stop program loop
  194. Terminate;
  195. end;
  196. procedure TWebIDLToPasApplication.InitWebIDLToPas;
  197. begin
  198. case OutputFormat of
  199. wifWasmJob:
  200. FWebIDLToPas:=TWebIDLToPasWasmJob.Create(Self);
  201. else
  202. FWebIDLToPas:=TWebIDLToPas2js.Create(Self);
  203. end;
  204. FWebIDLToPas.OnLog:=@DoConvertLog;
  205. FWebIDLToPas.ClassPrefix:='TJS';
  206. FWebIDLToPas.ClassSuffix:='';
  207. FWebIDLToPas.KeywordSuffix:='_';
  208. FWebIDLToPas.KeywordPrefix:='';
  209. end;
  210. constructor TWebIDLToPasApplication.Create(TheOwner: TComponent);
  211. begin
  212. inherited Create(TheOwner);
  213. StopOnException:=True;
  214. end;
  215. destructor TWebIDLToPasApplication.Destroy;
  216. begin
  217. FreeAndNil(FWebIDLToPas);
  218. inherited Destroy;
  219. end;
  220. procedure TWebIDLToPasApplication.WriteHelp(const Msg: string);
  221. begin
  222. {AllowWriteln}
  223. if (Msg<>'') then
  224. Writeln(StdErr,'Error : ',Msg);
  225. writeln(StdErr,'Usage: ', ExeName, ' [options]');
  226. Writeln(StdErr,'Where option is one or more of');
  227. Writeln(StdErr,'-h --help this help text');
  228. Writeln(StdErr,'-c --constexternal Write consts as external const (no value)');
  229. Writeln(StdErr,'-d --dicttoclass[=Parent] Write dictionaries as classes');
  230. Writeln(StdErr,'-e --expandunionargs Add overloads for all Union typed function arguments');
  231. Writeln(StdErr,'-f --outputformat=[pas2js|wasmjob] Output format, default ',WebIDLToPasFormatNames[OutputFormat]);
  232. Writeln(StdErr,'-i --input=FileName input webidl file');
  233. Writeln(StdErr,'-m --implementation=Filename include file as implementation');
  234. Writeln(StdErr,'-n --include=Filename include file at end of interface');
  235. Writeln(StdErr,'-o --output=FileName output file. Defaults to unit name with .pas extension appended.');
  236. Writeln(StdErr,'-p --optionsinheader add options to header of generated file');
  237. Writeln(StdErr,'-t --typealiases=alias A comma separated list of type aliases in Alias=Name form');
  238. Writeln(StdErr,' use @filename to load the aliases from file.');
  239. Writeln(StdErr,'-u --unitname=Name name for unit. Defaults to input file without extension.');
  240. Writeln(StdErr,'-v --verbose Output some diagnostic information');
  241. Writeln(StdErr,'-w --webidlversion=V Set web IDL version. Allowed values: v1 or v2');
  242. Writeln(StdErr,'-x --extra=units Extra units to put in uses clause (comma separated list)');
  243. ExitCode:=Ord(Msg<>'');
  244. {AllowWriteln-}
  245. end;
  246. var
  247. Application: TWebIDLToPasApplication;
  248. begin
  249. Application:=TWebIDLToPasApplication.Create(nil);
  250. Application.Title:='WebIDL To Pascal converter Application';
  251. Application.Run;
  252. Application.Free;
  253. end.