pas2jslib.pp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. library pas2jslib;
  2. {$mode objfpc}
  3. {$H+}
  4. uses
  5. SysUtils, Classes, FPPJsSrcMap, Pas2jsFileCache, Pas2jsCompiler;
  6. { ---------------------------------------------------------------------
  7. Compiler descendant, usable in library
  8. ---------------------------------------------------------------------}
  9. Const
  10. DefaultReadBufferSize = 32*1024; // 32kb buffer
  11. Type
  12. TLibLogCallBack = Procedure (Data : Pointer; Msg : PAnsiChar; MsgLen : Integer); stdcall;
  13. TWriteJSCallBack = Procedure (Data : Pointer;
  14. AFileName: PAnsiChar; AFileNameLen : Integer;
  15. AFileData : PAnsiChar; AFileDataLen: Int32); stdcall;
  16. TReadPasCallBack = Procedure (Data : Pointer;
  17. AFileName: PAnsiChar; AFileNameLen : Integer;
  18. AFileData : PAnsiChar; Var AFileDataLen: Int32); stdcall;
  19. { TLibraryPas2JSCompiler }
  20. TLibraryPas2JSCompiler = Class(TPas2JSCompiler)
  21. private
  22. FLastError: String;
  23. FLastErrorClass: String;
  24. FOnLibLogCallBack: TLibLogCallBack;
  25. FOnLibLogData: Pointer;
  26. FOnReadPasData: Pointer;
  27. FOnReadPasFile: TReadPasCallBack;
  28. FOnWriteJSCallBack: TWriteJSCallBack;
  29. FOnWriteJSData: Pointer;
  30. FReadBufferLen: Cardinal;
  31. Protected
  32. Function DoWriteJSFile(const DestFilename: String; aWriter: TPas2JSMapper): Boolean; override;
  33. Procedure GetLastError(AError : PAnsiChar; Var AErrorLength : Longint;
  34. AErrorClass : PAnsiChar; Var AErrorClassLength : Longint);
  35. Function ReadFile(aFilename: string; var aSource: string): boolean; virtual;
  36. Public
  37. Constructor Create; override;
  38. Procedure DoLibraryLog(Sender : TObject; Const Msg : String);
  39. Function LibraryRun(ACompilerExe, AWorkingDir : PAnsiChar; CommandLine : PPAnsiChar; DoReset : Boolean) :Boolean; stdcall;
  40. Property LastError : String Read FLastError Write FLastError;
  41. Property LastErrorClass : String Read FLastErrorClass Write FLastErrorClass;
  42. Property OnLibLogCallBack : TLibLogCallBack Read FOnLibLogCallBack Write FOnLibLogCallBack;
  43. Property OnLibLogData : Pointer Read FOnLibLogData Write FOnLibLogData;
  44. Property OnWriteJSCallBack : TWriteJSCallBack Read FOnWriteJSCallBack Write FOnWriteJSCallBack;
  45. Property OnWriteJSData : Pointer Read FOnWriteJSData Write FOnWriteJSData;
  46. Property OnReadPasFile : TReadPasCallBack Read FOnReadPasFile Write FOnReadPasFile;
  47. Property OnReadPasData : Pointer Read FOnReadPasData Write FOnReadPasData;
  48. Property ReadBufferLen : Cardinal Read FReadBufferLen Write FReadBufferLen;
  49. end;
  50. { TLibraryPas2JSCompiler }
  51. function TLibraryPas2JSCompiler.DoWriteJSFile(const DestFilename: String; aWriter: TPas2JSMapper): Boolean;
  52. Var
  53. Src : string;
  54. begin
  55. Result:=Assigned(OnWriteJSCallBack);
  56. if Result then
  57. try
  58. Src:=aWriter.AsAnsistring;
  59. OnWriteJSCallBack(OnWriteJSData,PAnsiChar(DestFileName),Length(DestFileName),PAnsiChar(Src),Length(Src));
  60. except
  61. Result:=False;
  62. end;
  63. end;
  64. procedure TLibraryPas2JSCompiler.GetLastError(AError: PAnsiChar;
  65. Var AErrorLength: Longint; AErrorClass: PAnsiChar;
  66. Var AErrorClassLength: Longint);
  67. Var
  68. L : Integer;
  69. begin
  70. L:=Length(LastError);
  71. if (L>AErrorLength) then
  72. L:=AErrorLength;
  73. if (L>0) then
  74. Move(FLastError[1],AError^,L);
  75. L:=Length(LastErrorClass);
  76. if L>AErrorClassLength then
  77. L:=AErrorClassLength;
  78. if (L>0) then
  79. Move(FLastErrorClass[1],AErrorClass^,L);
  80. end;
  81. function TLibraryPas2JSCompiler.ReadFile(aFilename: string; var aSource: string): boolean;
  82. Var
  83. Buf : Array of AnsiChar;
  84. S : TStringStream;
  85. BytesRead : Cardinal;
  86. begin
  87. if Not Assigned(OnReadPasFile) then
  88. Exit(False);
  89. S:=nil;
  90. try
  91. if ReadBufferLen=0 then
  92. ReadBufferLen:=DefaultReadBufferSize;
  93. SetLength(Buf,ReadBufferLen);
  94. S:=TStringStream.Create(''{$IF FPC_FULLVERSION>=30101},CP_ACP{$ENDIF});
  95. Repeat
  96. BytesRead:=ReadBufferLen;
  97. FOnReadPasFile(OnReadPasData,PAnsiChar(aFileName),Length(aFileName),@Buf[0],BytesRead);
  98. If BytesRead>0 then
  99. S.Write(Buf[0],BytesRead);
  100. Until (BytesRead<ReadBufferLen);
  101. Result:=S.Size<>0;
  102. if Result then
  103. aSource:=S.DataString;
  104. finally
  105. SetLength(Buf,0);
  106. S.Free;
  107. end;
  108. end;
  109. constructor TLibraryPas2JSCompiler.Create;
  110. begin
  111. inherited Create;
  112. Log.OnLog:=@DoLibraryLog;
  113. FileCache.OnReadFile:=@ReadFile;
  114. FReadBufferLen:=DefaultReadBufferSize;
  115. end;
  116. procedure TLibraryPas2JSCompiler.DoLibraryLog(Sender: TObject; const Msg: String);
  117. begin
  118. if Assigned(FOnLibLogCallBack) then
  119. FOnLibLogCallBack(FOnLibLogData,PAnsiChar(Msg),Length(Msg))
  120. else if isConsole then
  121. Writeln(Msg);
  122. end;
  123. function TLibraryPas2JSCompiler.LibraryRun(ACompilerExe, AWorkingDir: PAnsiChar;
  124. CommandLine: PPAnsiChar; DoReset: Boolean): Boolean; stdcall;
  125. Var
  126. C,W : AnsiString;
  127. CmdLine : TStrings;
  128. PP : PPAnsiChar;
  129. begin
  130. Result:=False;
  131. C:=ACompilerExe;
  132. W:=AWorkingDir;
  133. CmdLine:=TStringList.Create;
  134. try
  135. PP:=CommandLine;
  136. While (PP^<>Nil) do
  137. begin
  138. CmdLine.Add(pp^);
  139. Inc(PP);
  140. end;
  141. try
  142. Run(C,W,CmdLine,DoReset);
  143. Result:=(ExitCode=0);
  144. if Not Result then
  145. begin
  146. LastError:=Format('Compiler exited with exit code %d',[ExitCode]);
  147. LastErrorClass:=ECompilerTerminate.ClassName;
  148. end;
  149. except
  150. On E : Exception do
  151. begin
  152. LastError:=E.Message;
  153. LastErrorClass:=E.ClassName;
  154. end;
  155. end;
  156. finally
  157. CmdLine.free;
  158. end;
  159. end;
  160. { ---------------------------------------------------------------------
  161. Flat interface
  162. ---------------------------------------------------------------------}
  163. Type
  164. PPas2JSCompiler = Pointer;
  165. PStubCreator = Pointer;
  166. Procedure SetPas2JSWriteJSCallBack(P : PPas2JSCompiler; ACallBack : TWriteJSCallBack;
  167. CallBackData : Pointer); stdcall;
  168. begin
  169. TLibraryPas2JSCompiler(P).OnWriteJSCallBack:=ACallBack;
  170. TLibraryPas2JSCompiler(P).OnWriteJSData:=CallBackData;
  171. end;
  172. Procedure SetPas2JSCompilerLogCallBack(P : PPas2JSCompiler; ACallBack : TLibLogCallBack;
  173. CallBackData : Pointer); stdcall;
  174. begin
  175. TLibraryPas2JSCompiler(P).OnLibLogCallBack:=ACallBack;
  176. TLibraryPas2JSCompiler(P).OnLibLogData:=CallBackData;
  177. end;
  178. Procedure SetPas2JSReadPasCallBack(P : PPas2JSCompiler; ACallBack : TReadPasCallBack; CallBackData : Pointer; ABufferSize : Cardinal); stdcall;
  179. begin
  180. TLibraryPas2JSCompiler(P).OnReadPasData:=CallBackData;
  181. TLibraryPas2JSCompiler(P).OnReadPasFile:=ACallback;
  182. if (ABufferSize=0) then
  183. ABufferSize:=DefaultReadBufferSize;
  184. TLibraryPas2JSCompiler(P).ReadBufferLen:=ABufferSize;
  185. end;
  186. Function RunPas2JSCompiler(P : PPas2JSCompiler; ACompilerExe, AWorkingDir : PAnsiChar;
  187. CommandLine : PPAnsiChar; DoReset : Boolean) : Boolean; stdcall;
  188. begin
  189. Result:=TLibraryPas2JSCompiler(P).LibraryRun(ACompilerExe,AWorkingDir,CommandLine,DoReset)
  190. end;
  191. Procedure FreePas2JSCompiler(P : PPas2JSCompiler); stdcall;
  192. begin
  193. TLibraryPas2JSCompiler(P).Free;
  194. end;
  195. Function GetPas2JSCompiler : PPas2JSCompiler; stdcall;
  196. begin
  197. Result:=TLibraryPas2JSCompiler.Create;
  198. end;
  199. Procedure GetPas2JSCompilerLastError(P : PPas2JSCompiler; AError : PAnsiChar;
  200. Var AErrorLength : Longint; AErrorClass : PAnsiChar; Var AErrorClassLength : Longint); stdcall;
  201. begin
  202. TLibraryPas2JSCompiler(P).GetLastError(AError,AErrorLength,AErrorClass,AErrorClassLength);
  203. end;
  204. exports
  205. GetPas2JSCompiler,
  206. FreePas2JSCompiler,
  207. RunPas2JSCompiler,
  208. SetPas2JSReadPasCallBack,
  209. SetPas2JSWriteJSCallBack,
  210. SetPas2JSCompilerLogCallBack,
  211. GetPas2JSCompilerLastError;
  212. end.