fpcompil.pas 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Compiler call routines for the IDE
  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. {$i globdir.inc}
  12. unit FPCompil;
  13. {2.0 compatibility}
  14. {$ifdef VER2_0}
  15. {$macro on}
  16. {$define resourcestring := const}
  17. {$endif}
  18. interface
  19. { don't redir under linux, because all stdout (also from the ide!) will
  20. then be redired (PFV) }
  21. { this should work now correctly because
  22. RedirDisableAll and RedirEnableAll function are added in fpredir (PM) }
  23. { $define VERBOSETXT}
  24. {$mode objfpc}
  25. uses
  26. { We need to include the exceptions from SysUtils, but the types from
  27. Objects need to be used. Keep the order SysUtils,Objects }
  28. SysUtils,
  29. Objects,
  30. FInput,
  31. Drivers,Views,Dialogs,
  32. WUtils,WViews,WCEdit,
  33. FPSymbol,
  34. FPViews;
  35. type
  36. TCompileMode = (cBuild,cMake,cCompile,cRun);
  37. type
  38. PCompilerMessage = ^TCompilerMessage;
  39. TCompilerMessage = object(TMessageItem)
  40. function GetText(MaxLen: Sw_Integer): String; virtual;
  41. end;
  42. PCompilerMessageListBox = ^TCompilerMessageListBox;
  43. TCompilerMessageListBox = object(TMessageListBox)
  44. function GetPalette: PPalette; virtual;
  45. procedure SelectFirstError;
  46. end;
  47. PCompilerMessageWindow = ^TCompilerMessageWindow;
  48. TCompilerMessageWindow = object(TFPWindow)
  49. constructor Init;
  50. procedure HandleEvent(var Event: TEvent); virtual;
  51. function GetPalette: PPalette; virtual;
  52. procedure Close;virtual;
  53. destructor Done; virtual;
  54. procedure SizeLimits(var Min, Max: TPoint); virtual;
  55. procedure AddMessage(AClass: longint;const Msg, Module: string; Line, Column: longint);
  56. procedure ClearMessages;
  57. constructor Load(var S: TStream);
  58. procedure Store(var S: TStream);
  59. procedure SetState(AState: Word; Enable: Boolean); virtual;
  60. procedure UpdateCommands; virtual;
  61. private
  62. {CompileShowed : boolean;}
  63. {Mode : TCompileMode;}
  64. MsgLB : PCompilerMessageListBox;
  65. {CurrST,
  66. InfoST : PColorStaticText;}
  67. end;
  68. PCompilerStatusDialog = ^TCompilerStatusDialog;
  69. TCompilerStatusDialog = object(TCenterDialog)
  70. ST : PAdvancedStaticText;
  71. KeyST : PColorStaticText;
  72. starttime : real;
  73. constructor Init;
  74. destructor Done;virtual;
  75. procedure Update;
  76. procedure SetStartTime(r : real);
  77. end;
  78. TFPInputFile = class(tinputfile)
  79. constructor Create(AEditor: PFileEditor);
  80. protected
  81. function fileopen(const filename: string): boolean; override;
  82. function fileseek(pos: longint): boolean; override;
  83. function fileread(var databuf; maxsize: longint): longint; override;
  84. function fileeof: boolean; override;
  85. function fileclose: boolean; override;
  86. procedure filegettime; override;
  87. private
  88. Editor: PFileEditor;
  89. S: PStream;
  90. end;
  91. const
  92. CompilerMessageWindow : PCompilerMessageWindow = nil;
  93. CompilerStatusDialog : PCompilerStatusDialog = nil;
  94. CompileStamp : longint = 0;
  95. RestartingDebugger : boolean = false;
  96. procedure DoCompile(Mode: TCompileMode);
  97. function NeedRecompile(Mode :TCompileMode; verbose : boolean): boolean;
  98. procedure ParseUserScreen;
  99. procedure RegisterFPCompile;
  100. const
  101. CompilingHiddenFile : PSourceWindow = nil;
  102. implementation
  103. uses
  104. {$ifdef Unix}
  105. Unix, BaseUnix,
  106. {$endif}
  107. {$ifdef go32v2}
  108. dpmiexcp,
  109. {$endif}
  110. {$ifdef Windows}
  111. {$ifdef HasSignal}
  112. signals,
  113. {$endif}
  114. {$endif}
  115. { $ifdef HasSignal}
  116. fpcatch,
  117. { $endif HasSignal}
  118. Dos,
  119. Video,
  120. globals,
  121. StdDlg,App,tokens,
  122. FVConsts,
  123. CompHook, Compiler, systems, browcol,
  124. WEditor,
  125. FPRedir,FPDesk,
  126. FPUsrScr,FPHelp,
  127. {$ifndef NODEBUG}FPDebug,{$endif}
  128. FPConst,FPVars,FPUtils,
  129. FPCodCmp,FPIntf,FPSwitch;
  130. {$ifndef NOOBJREG}
  131. const
  132. RCompilerMessageListBox: TStreamRec = (
  133. ObjType: 1211;
  134. VmtLink: Ofs(TypeOf(TCompilerMessageListBox)^);
  135. Load: @TCompilerMessageListBox.Load;
  136. Store: @TCompilerMessageListBox.Store
  137. );
  138. RCompilerMessageWindow: TStreamRec = (
  139. ObjType: 1212;
  140. VmtLink: Ofs(TypeOf(TCompilerMessageWindow)^);
  141. Load: @TCompilerMessageWindow.Load;
  142. Store: @TCompilerMessageWindow.Store
  143. );
  144. {$endif}
  145. {$ifdef useresstrings}
  146. resourcestring
  147. {$else}
  148. const
  149. {$endif}
  150. dialog_compilermessages = 'Compiler Messages';
  151. dialog_compilingwithmode = 'Compiling (%s mode)';
  152. { Compiler message classes }
  153. msg_class_normal = '';
  154. msg_class_fatal = 'Fatal';
  155. msg_class_error = 'Error';
  156. msg_class_warning = 'Warning';
  157. msg_class_note = 'Note';
  158. msg_class_hint = 'Hint';
  159. msg_class_macro = 'Macro';
  160. msg_class_procedure= 'Procedure';
  161. msg_class_conditional = 'Conditional';
  162. msg_class_info = 'Info';
  163. msg_class_status = 'Status';
  164. msg_class_used = 'Used';
  165. msg_class_tried = 'Tried';
  166. msg_class_debug = 'Debug';
  167. { Compile status dialog texts }
  168. msg_compilingfile = 'Compiling %s';
  169. msg_loadingunit = 'Loading %s unit';
  170. msg_linkingfile = 'Linking %s';
  171. msg_compiledone = 'Done.';
  172. msg_failedtocompile = 'Failed to compile...';
  173. msg_compilationaborted = 'Compilation aborted...';
  174. msg_nothingtocompile = 'Oooops, nothing to compile.';
  175. msg_cantcompileunsavedfile = 'Can''t compile unsaved file.';
  176. msg_couldnotcreatefile = 'could not create %s';
  177. msg_therearemoreerrorsinfile = 'There are more errors in file %s';
  178. msg_firstcompilationof = 'First compilation of %s';
  179. msg_recompilingbecauseof = 'Recompiling because of %s';
  180. msg_errorinexternalcompilation = 'Error in external compilation';
  181. msg_iostatusis = 'IOStatus = %d';
  182. msg_executeresultis = 'ExecuteResult = %d';
  183. { Status hints during compilation }
  184. msg_hint_pressesctocancel = 'Press ESC to cancel';
  185. msg_hint_compilesuccessfulpressenter = 'Compile successful: ~Press any key~';
  186. msg_hint_compilefailed = 'Compile failed';
  187. msg_hint_compileaborted = 'Compile aborted';
  188. msg_hint_pleasewait = 'Please wait...';
  189. msg_cantopenfile = 'Can''t open %s';
  190. procedure ParseUserScreen;
  191. var
  192. Y,YMax : longint;
  193. LEvent : TEvent;
  194. Text,Attr : String;
  195. DisplayCompilerWindow : boolean;
  196. cc: integer;
  197. procedure SearchBackTrace;
  198. var AText,ModuleName,st : String;
  199. row : longint;
  200. begin
  201. if pos(' $',Text)=1 then
  202. begin
  203. AText:=Text;
  204. Delete(Text,1,11);
  205. While pos(' ',Text)=1 do
  206. Delete(Text,1,1);
  207. if pos('of ',Text)>0 then
  208. begin
  209. ModuleName:=Copy(Text,pos('of ',Text)+3,255);
  210. While ModuleName[Length(ModuleName)]=' ' do
  211. Delete(ModuleName,Length(ModuleName),1);
  212. end
  213. else
  214. ModuleName:='';
  215. if pos('line ',Text)>0 then
  216. begin
  217. Text:=Copy(Text,Pos('line ',Text)+5,255);
  218. st:=Copy(Text,1,Pos(' ',Text)-1);
  219. Val(st,row,cc);
  220. end
  221. else
  222. row:=0;
  223. CompilerMessageWindow^.AddMessage(V_Fatal or v_lineinfo,AText
  224. ,ModuleName,row,1);
  225. DisplayCompilerWindow:=true;
  226. end;
  227. end;
  228. procedure InsertInMessages(Const TypeStr : String;_Type : longint;EnableDisplay : boolean);
  229. var p,p2,col,row : longint;
  230. St,ModuleName : string;
  231. begin
  232. p:=pos(TypeStr,Text);
  233. p2:=Pos('(',Text);
  234. if (p>0) and (p2>0) and (p2<p) then
  235. begin
  236. ModuleName:=Copy(Text,1,p2-1);
  237. st:=Copy(Text,p2+1,255);
  238. Val(Copy(st,1,pos(',',st)-1),row,cc);
  239. st:=Copy(st,Pos(',',st)+1,255);
  240. Val(Copy(st,1,pos(')',st)-1),col,cc);
  241. CompilerMessageWindow^.AddMessage(_type,Copy(Text,pos(':',Text)+1,255)
  242. ,ModuleName,row,col);
  243. If EnableDisplay then
  244. DisplayCompilerWindow:=true;
  245. end;
  246. end;
  247. begin
  248. if not assigned(UserScreen) then
  249. exit;
  250. DisplayCompilerWindow:=false;
  251. YMax:=UserScreen^.GetHeight;
  252. PushStatus('Parsing User Screen');
  253. CompilerMessageWindow^.Lock;
  254. for Y:=0 to YMax do
  255. begin
  256. UserScreen^.GetLine(Y,Text,Attr);
  257. if (y mod 10) = 0 then
  258. begin
  259. CompilerMessageWindow^.Unlock;
  260. SetStatus('Parsing User Screen line '+IntToStr(y)+'/'+IntToStr(YMax));
  261. CompilerMessageWindow^.Lock;
  262. end;
  263. {$ifndef symobi}
  264. { on Symobi this will block :( }
  265. GetKeyEvent(LEvent);
  266. if (LEvent.What=evKeyDown) and (LEvent.KeyCode=kbEsc) then
  267. break;
  268. {$endif}
  269. SearchBackTrace;
  270. InsertInMessages(' Fatal:',v_Fatal or v_lineinfo,true);
  271. InsertInMessages(' Error:',v_Error or v_lineinfo,true);
  272. InsertInMessages(' Warning:',v_Warning or v_lineinfo,false);
  273. InsertInMessages(' Note:',v_Note or v_lineinfo,false);
  274. InsertInMessages(' Info:',v_Info or v_lineinfo,false);
  275. InsertInMessages(' Hint:',v_Hint or v_lineinfo,false);
  276. end;
  277. if DisplayCompilerWindow then
  278. begin
  279. if not CompilerMessageWindow^.GetState(sfVisible) then
  280. CompilerMessageWindow^.Show;
  281. CompilerMessageWindow^.MakeFirst;
  282. CompilerMessageWindow^.MsgLB^.SelectFirstError;
  283. end;
  284. CompilerMessageWindow^.UnLock;
  285. PopStatus;
  286. end;
  287. {*****************************************************************************
  288. TCompilerMessage
  289. *****************************************************************************}
  290. function TCompilerMessage.GetText(MaxLen: Sw_Integer): String;
  291. var
  292. ClassS: string[20];
  293. S: string;
  294. begin
  295. case TClass and V_LevelMask of
  296. V_Fatal : ClassS:=msg_class_Fatal;
  297. V_Error : ClassS:=msg_class_Error;
  298. V_Normal : ClassS:=msg_class_Normal;
  299. V_Warning : ClassS:=msg_class_Warning;
  300. V_Note : ClassS:=msg_class_Note;
  301. V_Hint : ClassS:=msg_class_Hint;
  302. {$ifdef VERBOSETXT}
  303. V_Conditional : ClassS:=msg_class_conditional;
  304. V_Info : ClassS:=msg_class_info;
  305. V_Status : ClassS:=msg_class_status;
  306. V_Used : ClassS:=msg_class_used;
  307. V_Tried : ClassS:=msg_class_tried;
  308. V_Debug : ClassS:=msg_class_debug;
  309. else
  310. ClassS:='???';
  311. {$endif}
  312. else
  313. ClassS:='';
  314. end;
  315. if ClassS<>'' then
  316. ClassS:=RExpand(ClassS,0)+': ';
  317. if assigned(Module) and
  318. ((TClass and V_LineInfo)=V_LineInfo) then
  319. begin
  320. if Row>0 then
  321. begin
  322. if Col>0 then
  323. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+','+IntToStr(Col)+') '+ClassS
  324. else
  325. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+') '+ClassS;
  326. end
  327. else
  328. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+') '+ClassS
  329. end
  330. else
  331. S:=ClassS;
  332. if assigned(Text) then
  333. S:=S+Text^;
  334. if length(S)>MaxLen then
  335. S:=copy(S,1,MaxLen-2)+'..';
  336. GetText:=S;
  337. end;
  338. {*****************************************************************************
  339. TCompilerMessageListBox
  340. *****************************************************************************}
  341. function TCompilerMessageListBox.GetPalette: PPalette;
  342. const
  343. P: string[length(CBrowserListBox)] = CBrowserListBox;
  344. begin
  345. GetPalette:=PPalette(@P);
  346. end;
  347. procedure TCompilerMessageListBox.SelectFirstError;
  348. function IsError(P : PCompilerMessage) : boolean;
  349. begin
  350. IsError:=(P^.TClass and (V_Fatal or V_Error))<>0;
  351. end;
  352. var
  353. P : PCompilerMessage;
  354. begin
  355. P:=List^.FirstThat(@IsError);
  356. If Assigned(P) then
  357. Begin
  358. FocusItem(List^.IndexOf(P));
  359. DrawView;
  360. End;
  361. end;
  362. {*****************************************************************************
  363. TCompilerMessageWindow
  364. *****************************************************************************}
  365. constructor TCompilerMessageWindow.Init;
  366. var R: TRect;
  367. HSB,VSB: PScrollBar;
  368. begin
  369. Desktop^.GetExtent(R);
  370. R.A.Y:=R.B.Y-7;
  371. inherited Init(R,dialog_compilermessages,{SearchFreeWindowNo}wnNoNumber);
  372. HelpCtx:=hcCompilerMessagesWindow;
  373. AutoNumber:=true;
  374. HSB:=StandardScrollBar(sbHorizontal+sbHandleKeyboard);
  375. HSB^.GrowMode:=gfGrowLoY+gfGrowHiX+gfGrowHiY;
  376. Insert(HSB);
  377. VSB:=StandardScrollBar(sbVertical+sbHandleKeyboard);
  378. VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  379. Insert(VSB);
  380. GetExtent(R);
  381. R.Grow(-1,-1);
  382. New(MsgLB, Init(R, HSB, VSB));
  383. MsgLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  384. Insert(MsgLB);
  385. CompilerMessageWindow:=@self;
  386. end;
  387. procedure TCompilerMessageWindow.AddMessage(AClass: longint;const Msg, Module: string; Line, Column: longint);
  388. begin
  389. if (AClass and V_LineInfo)<>V_LineInfo then
  390. Line:=0;
  391. MsgLB^.AddItem(New(PCompilerMessage,Init(AClass, Msg, MsgLB^.AddModuleName(Module), Line, Column)));
  392. if (@Self=CompilerMessageWindow) and ((AClass = V_fatal) or (AClass = V_Error)) then
  393. begin
  394. if not GetState(sfVisible) then
  395. Show;
  396. if Desktop^.First<>PView(CompilerMessageWindow) then
  397. MakeFirst;
  398. end;
  399. end;
  400. procedure TCompilerMessageWindow.ClearMessages;
  401. begin
  402. MsgLB^.Clear;
  403. ReDraw;
  404. end;
  405. {procedure TCompilerMessageWindow.Updateinfo;
  406. begin
  407. if CompileShowed then
  408. begin
  409. InfoST^.SetText(
  410. RExpand(' Main file : '#1#$7f+Copy(SmartPath(MainFile),1,39),40)+#2+
  411. 'Total lines : '#1#$7e+IntToStr(Status.CompiledLines)+#2#13+
  412. RExpand(' Target : '#1#$7f+KillTilde(TargetSwitches^.ItemName(TargetSwitches^.GetCurrSel)),40)+#2+
  413. 'Total errors : '#1#$7e+IntToStr(Status.ErrorCount)
  414. );
  415. if status.currentline>0 then
  416. CurrST^.SetText(' Status: '#1#$7e+status.currentsource+'('+IntToStr(status.currentline)+')'#2)
  417. else
  418. CurrST^.SetText(' Status: '#1#$7e+status.currentsource+#2);
  419. end;
  420. ReDraw;
  421. end;}
  422. procedure TCompilerMessageWindow.HandleEvent(var Event: TEvent);
  423. begin
  424. case Event.What of
  425. evBroadcast :
  426. case Event.Command of
  427. cmListFocusChanged :
  428. if Event.InfoPtr=MsgLB then
  429. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  430. end;
  431. end;
  432. inherited HandleEvent(Event);
  433. end;
  434. procedure TCompilerMessageWindow.SizeLimits(var Min, Max: TPoint);
  435. begin
  436. inherited SizeLimits(Min,Max);
  437. Min.X:=20;
  438. Min.Y:=4;
  439. end;
  440. procedure TCompilerMessageWindow.Close;
  441. begin
  442. Hide;
  443. end;
  444. function TCompilerMessageWindow.GetPalette: PPalette;
  445. const
  446. S : string[length(CBrowserWindow)] = CBrowserWindow;
  447. begin
  448. GetPalette:=PPalette(@S);
  449. end;
  450. constructor TCompilerMessageWindow.Load(var S: TStream);
  451. begin
  452. inherited Load(S);
  453. GetSubViewPtr(S,MsgLB);
  454. end;
  455. procedure TCompilerMessageWindow.Store(var S: TStream);
  456. begin
  457. if MsgLB^.List=nil then
  458. MsgLB^.NewList(New(PCollection, Init(100,100)));
  459. inherited Store(S);
  460. PutSubViewPtr(S,MsgLB);
  461. end;
  462. procedure TCompilerMessageWindow.UpdateCommands;
  463. var Active: boolean;
  464. begin
  465. Active:=GetState(sfActive);
  466. SetCmdState(CompileCmds,Active);
  467. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  468. end;
  469. procedure TCompilerMessageWindow.SetState(AState: Word; Enable: Boolean);
  470. var OldState: word;
  471. begin
  472. OldState:=State;
  473. inherited SetState(AState,Enable);
  474. if ((AState and sfActive)<>0) and (((OldState xor State) and sfActive)<>0) then
  475. UpdateCommands;
  476. end;
  477. destructor TCompilerMessageWindow.Done;
  478. begin
  479. CompilerMessageWindow:=nil;
  480. inherited Done;
  481. end;
  482. {****************************************************************************
  483. CompilerStatusDialog
  484. ****************************************************************************}
  485. function getrealtime : real;
  486. var
  487. {$IFDEF USE_SYSUTILS}
  488. h,m,s,s1000 : word;
  489. {$ELSE USE_SYSUTILS}
  490. h,m,s,s100 : word;
  491. {$ENDIF USE_SYSUTILS}
  492. begin
  493. {$IFDEF USE_SYSUTILS}
  494. DecodeTime(Time,h,m,s,s1000);
  495. getrealtime:=h*3600.0+m*60.0+s+s1000/1000.0;
  496. {$ELSE USE_SYSUTILS}
  497. gettime(h,m,s,s100);
  498. getrealtime:=h*3600.0+m*60.0+s+s100/100.0;
  499. {$ENDIF USE_SYSUTILS}
  500. end;
  501. constructor TCompilerStatusDialog.Init;
  502. var R: TRect;
  503. begin
  504. R.Assign(0,0,56,11);
  505. ClearFormatParams; AddFormatParamStr(KillTilde(SwitchesModeName[SwitchesMode]));
  506. inherited Init(R, FormatStrF(dialog_compilingwithmode, FormatParams));
  507. starttime:=getrealtime;
  508. GetExtent(R); R.B.Y:=11;
  509. R.Grow(-3,-2);
  510. New(ST, Init(R, ''));
  511. Insert(ST);
  512. GetExtent(R); R.B.Y:=11;
  513. R.Grow(-1,-1); R.A.Y:=R.B.Y-1;
  514. New(KeyST, Init(R, '', Blue*16+White+longint($80+Blue*16+White)*256,true));
  515. Insert(KeyST);
  516. { Reset Status infos see bug 1585 }
  517. Fillchar(Status,SizeOf(Status),#0);
  518. end;
  519. destructor TCompilerStatusDialog.Done;
  520. begin
  521. if @Self=CompilerStatusDialog then
  522. CompilerStatusDialog:=nil;
  523. Inherited Done;
  524. end;
  525. procedure TCompilerStatusDialog.SetStartTime(r : real);
  526. begin
  527. starttime:=r;
  528. end;
  529. procedure TCompilerStatusDialog.Update;
  530. var
  531. StatusS,KeyS: string;
  532. hstatus : TFPCHeapStatus;
  533. r : real;
  534. const
  535. MaxFileNameSize = 46;
  536. begin
  537. case CompilationPhase of
  538. cpCompiling :
  539. begin
  540. ClearFormatParams;
  541. if Upcase(Status.currentmodulestate)='COMPILE' then
  542. begin
  543. AddFormatParamStr(ShrinkPath(SmartPath(Status.Currentsourcepath+Status.CurrentSource),
  544. MaxFileNameSize - Length(msg_compilingfile)));
  545. StatusS:=FormatStrF(msg_compilingfile,FormatParams);
  546. end
  547. else
  548. begin
  549. if Status.CurrentSource='' then
  550. StatusS:=''
  551. else
  552. begin
  553. StatusS:=ShrinkPath(SmartPath(DirAndNameOf(Status.Currentsourcepath+Status.CurrentSource)),
  554. MaxFileNameSize-Length(msg_loadingunit));
  555. AddFormatParamStr(StatusS);
  556. StatusS:=FormatStrF(msg_loadingunit,FormatParams);
  557. end;
  558. end;
  559. KeyS:=msg_hint_pressesctocancel;
  560. end;
  561. cpLinking :
  562. begin
  563. ClearFormatParams;
  564. AddFormatParamStr(ShrinkPath(ExeFile,
  565. MaxFileNameSize-Length(msg_linkingfile)));
  566. StatusS:=FormatStrF(msg_linkingfile,FormatParams);
  567. KeyS:=msg_hint_pleasewait;
  568. end;
  569. cpDone :
  570. begin
  571. StatusS:=msg_compiledone;
  572. KeyS:=msg_hint_compilesuccessfulpressenter;
  573. end;
  574. cpFailed :
  575. begin
  576. StatusS:=msg_failedtocompile;
  577. KeyS:=msg_hint_compilefailed;
  578. end;
  579. cpAborted :
  580. begin
  581. StatusS:=msg_compilationaborted;
  582. KeyS:=msg_hint_compileaborted;
  583. end;
  584. end;
  585. ClearFormatParams;
  586. AddFormatParamStr(ShrinkPath(SmartPath(MainFile),
  587. MaxFileNameSize-Length('Main file: %s')));
  588. AddFormatParamStr(StatusS);
  589. AddFormatParamStr(KillTilde(TargetSwitches^.ItemName(TargetSwitches^.GetCurrSel)));
  590. AddFormatParamInt(Status.CurrentLine);
  591. AddFormatParamInt(Status.CompiledLines);
  592. hstatus:=GetFPCHeapStatus;
  593. AddFormatParamInt(hstatus.CurrHeapUsed div 1024);
  594. AddFormatParamInt(hstatus.CurrHeapSize div 1024);
  595. AddFormatParamInt(Status.ErrorCount);
  596. r:=getrealtime;
  597. AddFormatParamInt(trunc(r-starttime));
  598. AddFormatParamInt(trunc(frac(r-starttime)*10));
  599. ST^.SetText(
  600. FormatStrF(
  601. 'Main file: %s'#13+
  602. '%s'+#13#13+
  603. 'Target: %s'#13+
  604. 'Line number: %6d '+'Total lines: %6d'+#13+
  605. 'Used memory: %6dK '+'Allocated memory: %6dK'#13+
  606. 'Total errors:%6d '+'Compile time: %8d.%1ds',
  607. FormatParams)
  608. );
  609. KeyST^.SetText(^C+KeyS);
  610. end;
  611. {****************************************************************************
  612. Compiler Hooks
  613. ****************************************************************************}
  614. const
  615. lasttime : real = 0;
  616. function CompilerStatus: boolean;
  617. var
  618. event : tevent;
  619. begin
  620. GetKeyEvent(Event);
  621. if (Event.What=evKeyDown) and (Event.KeyCode=kbEsc) then
  622. begin
  623. CompilationPhase:=cpAborted;
  624. { update info messages }
  625. if assigned(CompilerStatusDialog) then
  626. begin
  627. {$ifdef redircompiler}
  628. RedirDisableAll;
  629. {$endif}
  630. CompilerStatusDialog^.Update;
  631. {$ifdef redircompiler}
  632. RedirEnableAll;
  633. {$endif}
  634. end;
  635. CompilerStatus:=true;
  636. exit;
  637. end;
  638. { only display line info every 100 lines, ofcourse all other messages
  639. will be displayed directly }
  640. if (getrealtime-lasttime>=CompilerStatusUpdateDelay) or (status.compiledlines=1) then
  641. begin
  642. lasttime:=getrealtime;
  643. { update info messages }
  644. {$ifdef redircompiler}
  645. RedirDisableAll;
  646. {$endif}
  647. if assigned(CompilerStatusDialog) then
  648. CompilerStatusDialog^.Update;
  649. {$ifdef redircompiler}
  650. RedirEnableAll;
  651. {$endif}
  652. { update memory usage }
  653. { HeapView^.Update; }
  654. end;
  655. CompilerStatus:=false;
  656. end;
  657. Function CompilerGetNamedFileTime(const filename : string) : Longint;
  658. var t: longint;
  659. W: PSourceWindow;
  660. begin
  661. W:=EditorWindowFile(FExpand(filename));
  662. if Assigned(W) and (W^.Editor^.GetModified) then
  663. t:=Now
  664. else
  665. t:=def_getnamedfiletime(filename);
  666. CompilerGetNamedFileTime:=t;
  667. end;
  668. function CompilerOpenInputFile(const filename: string): tinputfile;
  669. var f: tinputfile;
  670. W: PSourceWindow;
  671. begin
  672. if assigned(CompilingHiddenFile) and
  673. (NameandExtof(filename)=CompilingHiddenFile^.Editor^.Filename) then
  674. W:=CompilingHiddenFile
  675. else
  676. W:=EditorWindowFile(FExpand(filename));
  677. if Assigned(W) and (W^.Editor^.GetModified) then
  678. f:=TFPInputFile.Create(W^.Editor)
  679. else
  680. f:=def_openinputfile(filename);
  681. if assigned(W) then
  682. W^.Editor^.CompileStamp:=CompileStamp;
  683. CompilerOpenInputFile:=f;
  684. end;
  685. function CompilerComment(Level:Longint; const s:ansistring):boolean;
  686. begin
  687. CompilerComment:=false;
  688. if (status.verbosity and Level)<>0 then
  689. begin
  690. {$ifdef redircompiler}
  691. RedirDisableAll;
  692. {$endif}
  693. if not CompilerMessageWindow^.GetState(sfVisible) then
  694. CompilerMessageWindow^.Show;
  695. if Desktop^.First<>PView(CompilerMessageWindow) then
  696. CompilerMessageWindow^.MakeFirst;
  697. CompilerMessageWindow^.AddMessage(Level,S,status.currentsourcepath+status.currentsource,
  698. status.currentline,status.currentcolumn);
  699. { update info messages }
  700. if assigned(CompilerStatusDialog) then
  701. CompilerStatusDialog^.Update;
  702. {$ifdef redircompiler}
  703. RedirEnableAll;
  704. {$endif}
  705. { update memory usage }
  706. { HeapView^.Update; }
  707. end;
  708. end;
  709. {****************************************************************************
  710. DoCompile
  711. ****************************************************************************}
  712. { This function must return '' if
  713. "Options|Directories|Exe and PPU directory" is empty }
  714. function GetExePath: string;
  715. var Path: string;
  716. I: Sw_integer;
  717. begin
  718. Path:='';
  719. if DirectorySwitches<>nil then
  720. with DirectorySwitches^ do
  721. for I:=0 to ItemCount-1 do
  722. begin
  723. if ItemParam(I)='-FE' then
  724. begin
  725. Path:=GetStringItem(I);
  726. Break;
  727. end;
  728. end;
  729. if Path<>'' then
  730. GetExePath:=CompleteDir(FExpand(Path))
  731. else
  732. GetExePath:='';
  733. end;
  734. function GetMainFile(Mode: TCompileMode): string;
  735. var FileName: string;
  736. P : PSourceWindow;
  737. begin
  738. if assigned(CompilingHiddenFile) then
  739. P:=CompilingHiddenFile
  740. else
  741. P:=Message(Desktop,evBroadcast,cmSearchWindow,nil);
  742. if (PrimaryFileMain='') and (P=nil) then
  743. FileName:='' { nothing to compile }
  744. else
  745. begin
  746. if (PrimaryFileMain<>'') and (Mode<>cCompile) then
  747. FileName:=PrimaryFileMain
  748. else if assigned(P) then
  749. begin
  750. FileName:=P^.Editor^.FileName;
  751. if FileName='' then
  752. begin
  753. P^.Editor^.SaveAsk(true);
  754. FileName:=P^.Editor^.FileName;
  755. end;
  756. end
  757. else
  758. FileName:='';
  759. end;
  760. {$ifdef Unix}
  761. If (FileName<>'') then
  762. FileName:=FExpand(FileName);
  763. {$else}
  764. If (FileName<>'') then
  765. FileName:=FixFileName(FExpand(FileName));
  766. {$endif}
  767. GetMainFile:=FileName;
  768. end;
  769. procedure ResetErrorMessages;
  770. procedure ResetErrorLine(P: PView);
  771. begin
  772. if assigned(P) and
  773. (TypeOf(P^)=TypeOf(TSourceWindow)) then
  774. PSourceWindow(P)^.Editor^.SetErrorMessage('');
  775. end;
  776. begin
  777. Desktop^.ForEach(@ResetErrorLine);
  778. end;
  779. procedure DoCompile(Mode: TCompileMode);
  780. function IsExitEvent(E: TEvent): boolean;
  781. begin
  782. { following suggestion by Harsha Senanayake }
  783. IsExitEvent:=(E.What=evKeyDown);
  784. end;
  785. function GetTargetExeExt : string;
  786. begin
  787. GetTargetExeExt:=target_info.exeext;
  788. end;
  789. var
  790. s,FileName: string;
  791. ErrFile : Text;
  792. MustRestartDebugger : boolean;
  793. Error,LinkErrorCount : longint;
  794. E : TEvent;
  795. DummyView: PView;
  796. PPasFile : string[64];
  797. begin
  798. AskRecompileIfModifiedFlag:=true;
  799. { Get FileName }
  800. FileName:=GetMainFile(Mode);
  801. if FileName='' then
  802. begin
  803. ErrorBox(msg_nothingtocompile,nil);
  804. Exit;
  805. end else
  806. { THis is not longer necessary as unsaved files are loaded from a memorystream,
  807. and with the file as primaryfile set it is already incompatible with itself
  808. if FileName='*' then
  809. begin
  810. ErrorBox(msg_cantcompileunsavedfile,nil);
  811. Exit;
  812. end; }
  813. PushStatus('Beginning compilation...');
  814. { Show Compiler Messages Window }
  815. { if not CompilerMessageWindow^.GetState(sfVisible) then
  816. CompilerMessageWindow^.Show;
  817. CompilerMessageWindow^.MakeFirst;}
  818. CompilerMessageWindow^.ClearMessages;
  819. { Tell why we compile }
  820. NeedRecompile(Mode,true);
  821. MainFile:=FileName;
  822. SetStatus('Writing switches to file...');
  823. WriteSwitches(SwitchesPath);
  824. { leaving open browsers leads to crashes !! (PM) }
  825. SetStatus('Preparing symbol info...');
  826. CloseAllBrowsers;
  827. if ((DesktopFileFlags and dfSymbolInformation)<>0) then
  828. WriteSymbolsFile(BrowserName);
  829. { MainFile:=FixFileName(FExpand(FileName));}
  830. SetStatus('Preparing to compile...'+NameOf(MainFile));
  831. { Reset }
  832. CtrlBreakHit:=false;
  833. { Create Compiler Status Dialog }
  834. CompilationPhase:=cpCompiling;
  835. if not assigned(CompilingHiddenFile) then
  836. begin
  837. New(CompilerStatusDialog, Init);
  838. CompilerStatusDialog^.SetStartTime(getrealtime);
  839. CompilerStatusDialog^.SetState(sfModal,true);
  840. { disable window closing }
  841. CompilerStatusDialog^.Flags:=CompilerStatusDialog^.Flags and not wfclose;
  842. Application^.Insert(CompilerStatusDialog);
  843. CompilerStatusDialog^.Update;
  844. end;
  845. { Restore dir that could be changed during debugging }
  846. {$I-}
  847. ChDir(StartUpDir);
  848. {$I+}
  849. EatIO;
  850. { hook compiler output }
  851. do_status:=@CompilerStatus;
  852. do_comment:=@CompilerComment;
  853. do_openinputfile:=@CompilerOpenInputFile;
  854. do_getnamedfiletime:=@CompilerGetNamedFileTime;
  855. do_initsymbolinfo:=@InitBrowserCol;
  856. do_donesymbolinfo:=@DoneBrowserCol;
  857. do_extractsymbolinfo:=@CreateBrowserCol;
  858. { Compile ! }
  859. {$ifdef redircompiler}
  860. ChangeRedirOut(FPOutFileName,false);
  861. ChangeRedirError(FPErrFileName,false);
  862. {$endif}
  863. { insert "" around name so that spaces are allowed }
  864. { only supported in compiler after 2000/01/14 PM }
  865. if pos(' ',FileName)>0 then
  866. FileName:='"'+FileName+'"';
  867. if mode=cBuild then
  868. FileName:='-B '+FileName;
  869. { tokens are created and distroed by compiler.compile !! PM }
  870. DoneTokens;
  871. PPasFile:='ppas'+source_info.scriptext;
  872. WUtils.DeleteFile(GetExePath+PpasFile);
  873. SetStatus('Compiling...');
  874. inc(CompileStamp);
  875. ResetErrorMessages;
  876. {$ifndef NODEBUG}
  877. MustRestartDebugger:=false;
  878. if assigned(Debugger) then
  879. if Debugger^.HasExe then
  880. begin
  881. Debugger^.Reset;
  882. MustRestartDebugger:=true;
  883. end;
  884. {$endif NODEBUG}
  885. try
  886. FpIntF.Compile(FileName,SwitchesPath);
  887. except
  888. on ECompilerAbort do
  889. CompilerMessageWindow^.AddMessage(V_error,'Error during compilation','',0,0);
  890. on E:Exception do
  891. CompilerMessageWindow^.AddMessage(V_error,E.Message+' during compilation','',0,0);
  892. end;
  893. SetStatus('Finished compiling...');
  894. { Retrieve created exefile }
  895. If GetEXEPath<>'' then
  896. EXEFile:=FixFileName(GetEXEPath+NameOf(MainFile)+GetTargetExeExt)
  897. else
  898. EXEFile:=DirOf(MainFile)+NameOf(MainFile)+GetTargetExeExt;
  899. DefaultReplacements(ExeFile);
  900. { tokens are created and distroyed by compiler.compile !! PM }
  901. InitTokens;
  902. if LinkAfter and
  903. ExistsFile(GetExePath+PpasFile) and
  904. (CompilationPhase<>cpAborted) and
  905. (status.errorCount=0) then
  906. begin
  907. CompilationPhase:=cpLinking;
  908. if assigned(CompilerStatusDialog) then
  909. CompilerStatusDialog^.Update;
  910. SetStatus('Assembling and/or linking...');
  911. {$ifndef redircompiler}
  912. { At least here we want to catch output
  913. of batch file PM }
  914. ChangeRedirOut(FPOutFileName,false);
  915. ChangeRedirError(FPErrFileName,false);
  916. {$endif}
  917. {$ifdef Unix}
  918. error:=0;
  919. If Shell(GetExePath+PpasFile)=-1 Then
  920. Error:=fpgeterrno;
  921. {$else}
  922. DosExecute(GetEnv('COMSPEC'),'/C '+GetExePath+PpasFile);
  923. Error:=DosError;
  924. {$endif}
  925. SetStatus('Finished linking...');
  926. RestoreRedirOut;
  927. RestoreRedirError;
  928. if Error<>0 then
  929. Inc(status.errorCount);
  930. if Status.IsExe and not Status.IsLibrary and not ExistsFile(EXEFile) then
  931. begin
  932. Inc(status.errorCount);
  933. ClearFormatParams; AddFormatParamStr(ExeFile);
  934. CompilerMessageWindow^.AddMessage(V_error,FormatStrF(msg_couldnotcreatefile,FormatParams),'',0,0);
  935. {$I-}
  936. Assign(ErrFile,FPErrFileName);
  937. Reset(ErrFile);
  938. if EatIO<>0 then
  939. ErrorBox(FormatStrStr(msg_cantopenfile,FPErrFileName),nil)
  940. else
  941. begin
  942. LinkErrorCount:=0;
  943. While not eof(ErrFile) and (LinkErrorCount<25) do
  944. begin
  945. readln(ErrFile,s);
  946. CompilerMessageWindow^.AddMessage(V_error,s,'',0,0);
  947. inc(LinkErrorCount);
  948. end;
  949. if not eof(ErrFile) then
  950. begin
  951. ClearFormatParams; AddFormatParamStr(FPErrFileName);
  952. CompilerMessageWindow^.AddMessage(V_error,
  953. FormatStrF(msg_therearemoreerrorsinfile,FormatParams),'',0,0);
  954. end;
  955. Close(ErrFile);
  956. end;
  957. EatIO;
  958. {$I+}
  959. end
  960. else if error=0 then
  961. WUtils.DeleteFile(GetExePath+PpasFile);
  962. end;
  963. {$ifdef redircompiler}
  964. RestoreRedirOut;
  965. RestoreRedirError;
  966. {$endif}
  967. PopStatus;
  968. { Set end status }
  969. if not (CompilationPhase in [cpAborted,cpFailed]) then
  970. if (status.errorCount=0) then
  971. begin
  972. CompilationPhase:=cpDone;
  973. LastCompileTime := cardinal(Now);
  974. end
  975. else
  976. CompilationPhase:=cpFailed;
  977. { Show end status }
  978. { reenable window closing }
  979. if assigned(CompilerStatusDialog) then
  980. begin
  981. CompilerStatusDialog^.Flags:=CompilerStatusDialog^.Flags or wfclose;
  982. CompilerStatusDialog^.Update;
  983. CompilerStatusDialog^.ReDraw;
  984. CompilerStatusDialog^.SetState(sfModal,false);
  985. if ((CompilationPhase in [cpAborted,cpDone,cpFailed]) or (ShowStatusOnError))
  986. and ((Mode<>cRun) or (CompilationPhase<>cpDone)) then
  987. repeat
  988. CompilerStatusDialog^.GetEvent(E);
  989. if IsExitEvent(E)=false then
  990. CompilerStatusDialog^.HandleEvent(E);
  991. until IsExitEvent(E) or not assigned(CompilerStatusDialog);
  992. {if IsExitEvent(E) then
  993. Application^.PutEvent(E);}
  994. if assigned(CompilerStatusDialog) then
  995. begin
  996. Application^.Delete(CompilerStatusDialog);
  997. Dispose(CompilerStatusDialog, Done);
  998. end;
  999. end;
  1000. CompilerStatusDialog:=nil;
  1001. { end compilation returns true if the messagewindow should be removed }
  1002. if CompilationPhase=cpDone then
  1003. begin
  1004. CompilerMessageWindow^.Hide;
  1005. { This is the last compiled main file }
  1006. PrevMainFile:=MainFile;
  1007. MainHasDebugInfo:=DebugInfoSwitches^.GetCurrSelParam<>'-';
  1008. end;
  1009. { Update the app }
  1010. Message(Application,evCommand,cmUpdate,nil);
  1011. DummyView:=Desktop^.First;
  1012. while (DummyView<>nil) and (DummyView^.GetState(sfVisible)=false) do
  1013. begin
  1014. DummyView:=DummyView^.NextView;
  1015. end;
  1016. with DummyView^ do
  1017. if GetState(sfVisible) then
  1018. begin
  1019. SetState(sfSelected,false);
  1020. SetState(sfSelected,true);
  1021. end;
  1022. if Assigned(CompilerMessageWindow) then
  1023. with CompilerMessageWindow^ do
  1024. begin
  1025. if GetState(sfVisible) then
  1026. begin
  1027. SetState(sfSelected,false);
  1028. SetState(sfSelected,true);
  1029. end;
  1030. if (status.errorCount>0) then
  1031. MsgLB^.SelectFirstError;
  1032. end;
  1033. { ^^^ we need this trick to reactivate the desktop }
  1034. EditorModified:=false;
  1035. {$ifndef NODEBUG}
  1036. if MustRestartDebugger then
  1037. InitDebugger;
  1038. {$endif NODEBUG}
  1039. { In case we have something that the compiler touched }
  1040. AskToReloadAllModifiedFiles;
  1041. { Try to read Browser info in again if compilation failure !! }
  1042. if Not Assigned(Modules) and (CompilationPhase<>cpDone) and
  1043. ((DesktopFileFlags and dfSymbolInformation)<>0) then
  1044. ReadSymbolsFile(BrowserName);
  1045. if UseAllUnitsInCodeComplete and not assigned(CompilingHiddenFile) then
  1046. AddAvailableUnitsToCodeComplete(false);
  1047. end;
  1048. function NeedRecompile(Mode :TCompileMode; verbose : boolean): boolean;
  1049. var Need: boolean;
  1050. I: sw_integer;
  1051. SF: PSourceFile;
  1052. SourceTime,PPUTime,ObjTime: longint;
  1053. W: PSourceWindow;
  1054. begin
  1055. if Assigned(SourceFiles)=false then
  1056. Need:={(EditorModified=true)}true
  1057. else
  1058. begin
  1059. Need:=(PrevMainFile<>GetMainFile(Mode)) and (PrevMainFile<>'');
  1060. if Need then
  1061. begin
  1062. if verbose then
  1063. begin
  1064. ClearFormatParams; AddFormatParamStr(GetMainFile(Mode));
  1065. CompilerMessageWindow^.AddMessage(V_info,
  1066. FormatStrF(msg_firstcompilationof,FormatParams),
  1067. '',0,0);
  1068. end;
  1069. end
  1070. else
  1071. for I:=0 to SourceFiles^.Count-1 do
  1072. begin
  1073. SF:=SourceFiles^.At(I);
  1074. SourceTime:=wutils.GetFileTime(SF^.GetSourceFileName);
  1075. PPUTime:=wutils.GetFileTime(SF^.GetPPUFileName);
  1076. ObjTime:=wutils.GetFileTime(SF^.GetObjFileName);
  1077. { writeln('S: ',SF^.GetSourceFileName,' - ',SourceTime);
  1078. writeln('P: ',SF^.GetPPUFileName,' - ',PPUTime);
  1079. writeln('O: ',SF^.GetObjFileName,' - ',ObjTime);
  1080. writeln('------');}
  1081. { some units don't generate object files }
  1082. W:=EditorWindowFile(SF^.GetSourceFileName);
  1083. if (SourceTime<>-1) then
  1084. if ((SourceTime>PPUTime) or
  1085. ((SourceTime>ObjTime) and
  1086. (ObjTime<>-1))) or
  1087. (assigned(W) and (W^.Editor^.CompileStamp<0)) then
  1088. begin
  1089. Need:=true;
  1090. if verbose then
  1091. begin
  1092. ClearFormatParams; AddFormatParamStr(SF^.GetSourceFileName);
  1093. CompilerMessageWindow^.AddMessage(V_info,
  1094. FormatStrF(msg_recompilingbecauseof,FormatParams),
  1095. SF^.GetSourceFileName,1,1);
  1096. end;
  1097. Break;
  1098. end;
  1099. end;
  1100. { writeln('Need?', Need); system.readln;}
  1101. end;
  1102. NeedRecompile:=Need;
  1103. end;
  1104. constructor TFPInputFile.Create(AEditor: PFileEditor);
  1105. begin
  1106. if not Assigned(AEditor) then Fail;
  1107. if inherited Create(AEditor^.FileName)=nil then
  1108. Fail;
  1109. Editor:=AEditor;
  1110. end;
  1111. function TFPInputFile.fileopen(const filename: string): boolean;
  1112. var OK: boolean;
  1113. begin
  1114. S:=New(PMemoryStream, Init(0,0));
  1115. OK:=Assigned(S) and (S^.Status=stOK);
  1116. if OK then OK:=Editor^.SaveToStream(S);
  1117. if OK then
  1118. S^.Seek(0)
  1119. else
  1120. begin
  1121. if Assigned(S) then Dispose(S, Done);
  1122. S:=nil;
  1123. end;
  1124. fileopen:=OK;
  1125. end;
  1126. function TFPInputFile.fileseek(pos: longint): boolean;
  1127. var OK: boolean;
  1128. begin
  1129. OK:=assigned(S);
  1130. if OK then
  1131. begin
  1132. S^.Reset;
  1133. S^.Seek(pos);
  1134. OK:=(S^.Status=stOK);
  1135. end;
  1136. fileseek:=OK;
  1137. end;
  1138. function TFPInputFile.fileread(var databuf; maxsize: longint): longint;
  1139. var
  1140. size: longint;
  1141. begin
  1142. if not assigned(S) then size:=0 else
  1143. begin
  1144. size:=min(maxsize,(S^.GetSize-S^.GetPos));
  1145. S^.Read(databuf,size);
  1146. if S^.Status<>stOK then size:=0;
  1147. end;
  1148. fileread:=size;
  1149. end;
  1150. function TFPInputFile.fileeof: boolean;
  1151. var EOF: boolean;
  1152. begin
  1153. EOF:=not assigned(S);
  1154. if not EOF then
  1155. EOF:=(S^.Status<>stOK) or (S^.GetPos=S^.GetSize);
  1156. fileeof:=EOF;
  1157. end;
  1158. function TFPInputFile.fileclose: boolean;
  1159. var OK: boolean;
  1160. begin
  1161. OK:=assigned(S);
  1162. if OK then
  1163. begin
  1164. S^.Reset;
  1165. Dispose(S, Done);
  1166. S:=nil;
  1167. OK:=true;
  1168. end;
  1169. fileclose:=OK;
  1170. end;
  1171. procedure tfpinputfile.filegettime;
  1172. var
  1173. dt : datetime;
  1174. hsec,wday : word;
  1175. begin
  1176. { current time }
  1177. dos.getdate(dt.year,dt.month,dt.day,wday);
  1178. dos.gettime(dt.hour,dt.min,dt.sec,hsec);
  1179. packtime(dt,filetime);
  1180. end;
  1181. procedure RegisterFPCompile;
  1182. begin
  1183. {$ifndef NOOBJREG}
  1184. RegisterType(RCompilerMessageListBox);
  1185. RegisterType(RCompilerMessageWindow);
  1186. {$endif}
  1187. end;
  1188. end.