fpcompil.pas 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295
  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. GetKeyEvent(LEvent);
  264. if (LEvent.What=evKeyDown) and (LEvent.KeyCode=kbEsc) then
  265. break;
  266. SearchBackTrace;
  267. InsertInMessages(' Fatal:',v_Fatal or v_lineinfo,true);
  268. InsertInMessages(' Error:',v_Error or v_lineinfo,true);
  269. InsertInMessages(' Warning:',v_Warning or v_lineinfo,false);
  270. InsertInMessages(' Note:',v_Note or v_lineinfo,false);
  271. InsertInMessages(' Info:',v_Info or v_lineinfo,false);
  272. InsertInMessages(' Hint:',v_Hint or v_lineinfo,false);
  273. end;
  274. if DisplayCompilerWindow then
  275. begin
  276. if not CompilerMessageWindow^.GetState(sfVisible) then
  277. CompilerMessageWindow^.Show;
  278. CompilerMessageWindow^.MakeFirst;
  279. CompilerMessageWindow^.MsgLB^.SelectFirstError;
  280. end;
  281. CompilerMessageWindow^.UnLock;
  282. PopStatus;
  283. end;
  284. {*****************************************************************************
  285. TCompilerMessage
  286. *****************************************************************************}
  287. function TCompilerMessage.GetText(MaxLen: Sw_Integer): String;
  288. var
  289. ClassS: string[20];
  290. S: string;
  291. begin
  292. case TClass and V_LevelMask of
  293. V_Fatal : ClassS:=msg_class_Fatal;
  294. V_Error : ClassS:=msg_class_Error;
  295. V_Normal : ClassS:=msg_class_Normal;
  296. V_Warning : ClassS:=msg_class_Warning;
  297. V_Note : ClassS:=msg_class_Note;
  298. V_Hint : ClassS:=msg_class_Hint;
  299. {$ifdef VERBOSETXT}
  300. V_Conditional : ClassS:=msg_class_conditional;
  301. V_Info : ClassS:=msg_class_info;
  302. V_Status : ClassS:=msg_class_status;
  303. V_Used : ClassS:=msg_class_used;
  304. V_Tried : ClassS:=msg_class_tried;
  305. V_Debug : ClassS:=msg_class_debug;
  306. else
  307. ClassS:='???';
  308. {$endif}
  309. else
  310. ClassS:='';
  311. end;
  312. if ClassS<>'' then
  313. ClassS:=RExpand(ClassS,0)+': ';
  314. if assigned(Module) and
  315. ((TClass and V_LineInfo)=V_LineInfo) then
  316. begin
  317. if Row>0 then
  318. begin
  319. if Col>0 then
  320. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+','+IntToStr(Col)+') '+ClassS
  321. else
  322. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+') '+ClassS;
  323. end
  324. else
  325. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+') '+ClassS
  326. end
  327. else
  328. S:=ClassS;
  329. if assigned(Text) then
  330. S:=S+Text^;
  331. if length(S)>MaxLen then
  332. S:=copy(S,1,MaxLen-2)+'..';
  333. GetText:=S;
  334. end;
  335. {*****************************************************************************
  336. TCompilerMessageListBox
  337. *****************************************************************************}
  338. function TCompilerMessageListBox.GetPalette: PPalette;
  339. const
  340. P: string[length(CBrowserListBox)] = CBrowserListBox;
  341. begin
  342. GetPalette:=PPalette(@P);
  343. end;
  344. procedure TCompilerMessageListBox.SelectFirstError;
  345. function IsError(P : PCompilerMessage) : boolean;
  346. begin
  347. IsError:=(P^.TClass and (V_Fatal or V_Error))<>0;
  348. end;
  349. var
  350. P : PCompilerMessage;
  351. begin
  352. P:=List^.FirstThat(@IsError);
  353. If Assigned(P) then
  354. Begin
  355. FocusItem(List^.IndexOf(P));
  356. DrawView;
  357. End;
  358. end;
  359. {*****************************************************************************
  360. TCompilerMessageWindow
  361. *****************************************************************************}
  362. constructor TCompilerMessageWindow.Init;
  363. var R: TRect;
  364. HSB,VSB: PScrollBar;
  365. begin
  366. Desktop^.GetExtent(R);
  367. R.A.Y:=R.B.Y-7;
  368. inherited Init(R,dialog_compilermessages,{SearchFreeWindowNo}wnNoNumber);
  369. HelpCtx:=hcCompilerMessagesWindow;
  370. AutoNumber:=true;
  371. HSB:=StandardScrollBar(sbHorizontal+sbHandleKeyboard);
  372. HSB^.GrowMode:=gfGrowLoY+gfGrowHiX+gfGrowHiY;
  373. Insert(HSB);
  374. VSB:=StandardScrollBar(sbVertical+sbHandleKeyboard);
  375. VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  376. Insert(VSB);
  377. GetExtent(R);
  378. R.Grow(-1,-1);
  379. New(MsgLB, Init(R, HSB, VSB));
  380. MsgLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  381. Insert(MsgLB);
  382. CompilerMessageWindow:=@self;
  383. end;
  384. procedure TCompilerMessageWindow.AddMessage(AClass: longint;const Msg, Module: string; Line, Column: longint);
  385. begin
  386. if (AClass and V_LineInfo)<>V_LineInfo then
  387. Line:=0;
  388. MsgLB^.AddItem(New(PCompilerMessage,Init(AClass, Msg, MsgLB^.AddModuleName(Module), Line, Column)));
  389. if (@Self=CompilerMessageWindow) and ((AClass = V_fatal) or (AClass = V_Error)) then
  390. begin
  391. if not GetState(sfVisible) then
  392. Show;
  393. if Desktop^.First<>PView(CompilerMessageWindow) then
  394. MakeFirst;
  395. end;
  396. end;
  397. procedure TCompilerMessageWindow.ClearMessages;
  398. begin
  399. MsgLB^.Clear;
  400. ReDraw;
  401. end;
  402. {procedure TCompilerMessageWindow.Updateinfo;
  403. begin
  404. if CompileShowed then
  405. begin
  406. InfoST^.SetText(
  407. RExpand(' Main file : '#1#$7f+Copy(SmartPath(MainFile),1,39),40)+#2+
  408. 'Total lines : '#1#$7e+IntToStr(Status.CompiledLines)+#2#13+
  409. RExpand(' Target : '#1#$7f+KillTilde(TargetSwitches^.ItemName(TargetSwitches^.GetCurrSel)),40)+#2+
  410. 'Total errors : '#1#$7e+IntToStr(Status.ErrorCount)
  411. );
  412. if status.currentline>0 then
  413. CurrST^.SetText(' Status: '#1#$7e+status.currentsource+'('+IntToStr(status.currentline)+')'#2)
  414. else
  415. CurrST^.SetText(' Status: '#1#$7e+status.currentsource+#2);
  416. end;
  417. ReDraw;
  418. end;}
  419. procedure TCompilerMessageWindow.HandleEvent(var Event: TEvent);
  420. begin
  421. case Event.What of
  422. evBroadcast :
  423. case Event.Command of
  424. cmListFocusChanged :
  425. if Event.InfoPtr=MsgLB then
  426. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  427. end;
  428. end;
  429. inherited HandleEvent(Event);
  430. end;
  431. procedure TCompilerMessageWindow.SizeLimits(var Min, Max: TPoint);
  432. begin
  433. inherited SizeLimits(Min,Max);
  434. Min.X:=20;
  435. Min.Y:=4;
  436. end;
  437. procedure TCompilerMessageWindow.Close;
  438. begin
  439. Hide;
  440. end;
  441. function TCompilerMessageWindow.GetPalette: PPalette;
  442. const
  443. S : string[length(CBrowserWindow)] = CBrowserWindow;
  444. begin
  445. GetPalette:=PPalette(@S);
  446. end;
  447. constructor TCompilerMessageWindow.Load(var S: TStream);
  448. begin
  449. inherited Load(S);
  450. GetSubViewPtr(S,MsgLB);
  451. end;
  452. procedure TCompilerMessageWindow.Store(var S: TStream);
  453. begin
  454. if MsgLB^.List=nil then
  455. MsgLB^.NewList(New(PCollection, Init(100,100)));
  456. inherited Store(S);
  457. PutSubViewPtr(S,MsgLB);
  458. end;
  459. procedure TCompilerMessageWindow.UpdateCommands;
  460. var Active: boolean;
  461. begin
  462. Active:=GetState(sfActive);
  463. SetCmdState(CompileCmds,Active);
  464. Message(Application,evBroadcast,cmCommandSetChanged,nil);
  465. end;
  466. procedure TCompilerMessageWindow.SetState(AState: Word; Enable: Boolean);
  467. var OldState: word;
  468. begin
  469. OldState:=State;
  470. inherited SetState(AState,Enable);
  471. if ((AState and sfActive)<>0) and (((OldState xor State) and sfActive)<>0) then
  472. UpdateCommands;
  473. end;
  474. destructor TCompilerMessageWindow.Done;
  475. begin
  476. CompilerMessageWindow:=nil;
  477. inherited Done;
  478. end;
  479. {****************************************************************************
  480. CompilerStatusDialog
  481. ****************************************************************************}
  482. function getrealtime : real;
  483. var
  484. {$IFDEF USE_SYSUTILS}
  485. h,m,s,s1000 : word;
  486. {$ELSE USE_SYSUTILS}
  487. h,m,s,s100 : word;
  488. {$ENDIF USE_SYSUTILS}
  489. begin
  490. {$IFDEF USE_SYSUTILS}
  491. DecodeTime(Time,h,m,s,s1000);
  492. getrealtime:=h*3600.0+m*60.0+s+s1000/1000.0;
  493. {$ELSE USE_SYSUTILS}
  494. gettime(h,m,s,s100);
  495. getrealtime:=h*3600.0+m*60.0+s+s100/100.0;
  496. {$ENDIF USE_SYSUTILS}
  497. end;
  498. constructor TCompilerStatusDialog.Init;
  499. var R: TRect;
  500. begin
  501. R.Assign(0,0,56,11);
  502. ClearFormatParams; AddFormatParamStr(KillTilde(SwitchesModeName[SwitchesMode]));
  503. inherited Init(R, FormatStrF(dialog_compilingwithmode, FormatParams));
  504. starttime:=getrealtime;
  505. GetExtent(R); R.B.Y:=11;
  506. R.Grow(-3,-2);
  507. New(ST, Init(R, ''));
  508. Insert(ST);
  509. GetExtent(R); R.B.Y:=11;
  510. R.Grow(-1,-1); R.A.Y:=R.B.Y-1;
  511. New(KeyST, Init(R, '', Blue*16+White+longint($80+Blue*16+White)*256,true));
  512. Insert(KeyST);
  513. { Reset Status infos see bug 1585 }
  514. Fillchar(Status,SizeOf(Status),#0);
  515. end;
  516. destructor TCompilerStatusDialog.Done;
  517. begin
  518. if @Self=CompilerStatusDialog then
  519. CompilerStatusDialog:=nil;
  520. Inherited Done;
  521. end;
  522. procedure TCompilerStatusDialog.SetStartTime(r : real);
  523. begin
  524. starttime:=r;
  525. end;
  526. procedure TCompilerStatusDialog.Update;
  527. var
  528. StatusS,KeyS: string;
  529. hstatus : TFPCHeapStatus;
  530. r : real;
  531. const
  532. MaxFileNameSize = 46;
  533. begin
  534. case CompilationPhase of
  535. cpCompiling :
  536. begin
  537. ClearFormatParams;
  538. if Upcase(Status.currentmodulestate)='COMPILE' then
  539. begin
  540. AddFormatParamStr(ShrinkPath(SmartPath(Status.Currentsourcepath+Status.CurrentSource),
  541. MaxFileNameSize - Length(msg_compilingfile)));
  542. StatusS:=FormatStrF(msg_compilingfile,FormatParams);
  543. end
  544. else
  545. begin
  546. if Status.CurrentSource='' then
  547. StatusS:=''
  548. else
  549. begin
  550. StatusS:=ShrinkPath(SmartPath(DirAndNameOf(Status.Currentsourcepath+Status.CurrentSource)),
  551. MaxFileNameSize-Length(msg_loadingunit));
  552. AddFormatParamStr(StatusS);
  553. StatusS:=FormatStrF(msg_loadingunit,FormatParams);
  554. end;
  555. end;
  556. KeyS:=msg_hint_pressesctocancel;
  557. end;
  558. cpLinking :
  559. begin
  560. ClearFormatParams;
  561. AddFormatParamStr(ShrinkPath(ExeFile,
  562. MaxFileNameSize-Length(msg_linkingfile)));
  563. StatusS:=FormatStrF(msg_linkingfile,FormatParams);
  564. KeyS:=msg_hint_pleasewait;
  565. end;
  566. cpDone :
  567. begin
  568. StatusS:=msg_compiledone;
  569. KeyS:=msg_hint_compilesuccessfulpressenter;
  570. end;
  571. cpFailed :
  572. begin
  573. StatusS:=msg_failedtocompile;
  574. KeyS:=msg_hint_compilefailed;
  575. end;
  576. cpAborted :
  577. begin
  578. StatusS:=msg_compilationaborted;
  579. KeyS:=msg_hint_compileaborted;
  580. end;
  581. end;
  582. ClearFormatParams;
  583. AddFormatParamStr(ShrinkPath(SmartPath(MainFile),
  584. MaxFileNameSize-Length('Main file: %s')));
  585. AddFormatParamStr(StatusS);
  586. AddFormatParamStr(KillTilde(TargetSwitches^.ItemName(TargetSwitches^.GetCurrSel)));
  587. AddFormatParamInt(Status.CurrentLine);
  588. AddFormatParamInt(Status.CompiledLines);
  589. hstatus:=GetFPCHeapStatus;
  590. AddFormatParamInt(hstatus.CurrHeapUsed div 1024);
  591. AddFormatParamInt(hstatus.CurrHeapSize div 1024);
  592. AddFormatParamInt(Status.ErrorCount);
  593. r:=getrealtime;
  594. AddFormatParamInt(trunc(r-starttime));
  595. AddFormatParamInt(trunc(frac(r-starttime)*10));
  596. ST^.SetText(
  597. FormatStrF(
  598. 'Main file: %s'#13+
  599. '%s'+#13#13+
  600. 'Target: %s'#13+
  601. 'Line number: %6d '+'Total lines: %6d'+#13+
  602. 'Used memory: %6dK '+'Allocated memory: %6dK'#13+
  603. 'Total errors:%6d '+'Compile time: %8d.%1ds',
  604. FormatParams)
  605. );
  606. KeyST^.SetText(^C+KeyS);
  607. end;
  608. {****************************************************************************
  609. Compiler Hooks
  610. ****************************************************************************}
  611. const
  612. lasttime : real = 0;
  613. function CompilerStatus: boolean;
  614. var
  615. event : tevent;
  616. begin
  617. GetKeyEvent(Event);
  618. if (Event.What=evKeyDown) and (Event.KeyCode=kbEsc) then
  619. begin
  620. CompilationPhase:=cpAborted;
  621. { update info messages }
  622. if assigned(CompilerStatusDialog) then
  623. begin
  624. {$ifdef redircompiler}
  625. RedirDisableAll;
  626. {$endif}
  627. CompilerStatusDialog^.Update;
  628. {$ifdef redircompiler}
  629. RedirEnableAll;
  630. {$endif}
  631. end;
  632. CompilerStatus:=true;
  633. exit;
  634. end;
  635. { only display line info every 100 lines, ofcourse all other messages
  636. will be displayed directly }
  637. if (getrealtime-lasttime>=CompilerStatusUpdateDelay) or (status.compiledlines=1) then
  638. begin
  639. lasttime:=getrealtime;
  640. { update info messages }
  641. {$ifdef redircompiler}
  642. RedirDisableAll;
  643. {$endif}
  644. if assigned(CompilerStatusDialog) then
  645. CompilerStatusDialog^.Update;
  646. {$ifdef redircompiler}
  647. RedirEnableAll;
  648. {$endif}
  649. { update memory usage }
  650. { HeapView^.Update; }
  651. end;
  652. CompilerStatus:=false;
  653. end;
  654. Function CompilerGetNamedFileTime(const filename : string) : Longint;
  655. var t: longint;
  656. W: PSourceWindow;
  657. begin
  658. W:=EditorWindowFile(FExpand(filename));
  659. if Assigned(W) and (W^.Editor^.GetModified) then
  660. t:=Now
  661. else
  662. t:=def_getnamedfiletime(filename);
  663. CompilerGetNamedFileTime:=t;
  664. end;
  665. function CompilerOpenInputFile(const filename: string): tinputfile;
  666. var f: tinputfile;
  667. W: PSourceWindow;
  668. begin
  669. if assigned(CompilingHiddenFile) and
  670. (NameandExtof(filename)=CompilingHiddenFile^.Editor^.Filename) then
  671. W:=CompilingHiddenFile
  672. else
  673. W:=EditorWindowFile(FExpand(filename));
  674. if Assigned(W) and (W^.Editor^.GetModified) then
  675. f:=TFPInputFile.Create(W^.Editor)
  676. else
  677. f:=def_openinputfile(filename);
  678. if assigned(W) then
  679. W^.Editor^.CompileStamp:=CompileStamp;
  680. CompilerOpenInputFile:=f;
  681. end;
  682. function CompilerComment(Level:Longint; const s:ansistring):boolean;
  683. begin
  684. CompilerComment:=false;
  685. if (status.verbosity and Level)<>0 then
  686. begin
  687. {$ifdef redircompiler}
  688. RedirDisableAll;
  689. {$endif}
  690. if not CompilerMessageWindow^.GetState(sfVisible) then
  691. CompilerMessageWindow^.Show;
  692. if Desktop^.First<>PView(CompilerMessageWindow) then
  693. CompilerMessageWindow^.MakeFirst;
  694. CompilerMessageWindow^.AddMessage(Level,S,status.currentsourcepath+status.currentsource,
  695. status.currentline,status.currentcolumn);
  696. { update info messages }
  697. if assigned(CompilerStatusDialog) then
  698. CompilerStatusDialog^.Update;
  699. {$ifdef redircompiler}
  700. RedirEnableAll;
  701. {$endif}
  702. { update memory usage }
  703. { HeapView^.Update; }
  704. end;
  705. end;
  706. {****************************************************************************
  707. DoCompile
  708. ****************************************************************************}
  709. { This function must return '' if
  710. "Options|Directories|Exe and PPU directory" is empty }
  711. function GetExePath: string;
  712. var Path: string;
  713. I: Sw_integer;
  714. begin
  715. Path:='';
  716. if DirectorySwitches<>nil then
  717. with DirectorySwitches^ do
  718. for I:=0 to ItemCount-1 do
  719. begin
  720. if ItemParam(I)='-FE' then
  721. begin
  722. Path:=GetStringItem(I);
  723. Break;
  724. end;
  725. end;
  726. if Path<>'' then
  727. GetExePath:=CompleteDir(FExpand(Path))
  728. else
  729. GetExePath:='';
  730. end;
  731. function GetMainFile(Mode: TCompileMode): string;
  732. var FileName: string;
  733. P : PSourceWindow;
  734. begin
  735. if assigned(CompilingHiddenFile) then
  736. P:=CompilingHiddenFile
  737. else
  738. P:=Message(Desktop,evBroadcast,cmSearchWindow,nil);
  739. if (PrimaryFileMain='') and (P=nil) then
  740. FileName:='' { nothing to compile }
  741. else
  742. begin
  743. if (PrimaryFileMain<>'') and (Mode<>cCompile) then
  744. FileName:=PrimaryFileMain
  745. else if assigned(P) then
  746. begin
  747. FileName:=P^.Editor^.FileName;
  748. if FileName='' then
  749. begin
  750. P^.Editor^.SaveAsk(true);
  751. FileName:=P^.Editor^.FileName;
  752. end;
  753. end
  754. else
  755. FileName:='';
  756. end;
  757. {$ifdef Unix}
  758. If (FileName<>'') then
  759. FileName:=FExpand(FileName);
  760. {$else}
  761. If (FileName<>'') then
  762. FileName:=FixFileName(FExpand(FileName));
  763. {$endif}
  764. GetMainFile:=FileName;
  765. end;
  766. procedure ResetErrorMessages;
  767. procedure ResetErrorLine(P: PView);
  768. begin
  769. if assigned(P) and
  770. (TypeOf(P^)=TypeOf(TSourceWindow)) then
  771. PSourceWindow(P)^.Editor^.SetErrorMessage('');
  772. end;
  773. begin
  774. Desktop^.ForEach(@ResetErrorLine);
  775. end;
  776. procedure DoCompile(Mode: TCompileMode);
  777. function IsExitEvent(E: TEvent): boolean;
  778. begin
  779. { following suggestion by Harsha Senanayake }
  780. IsExitEvent:=(E.What=evKeyDown);
  781. end;
  782. function GetTargetExeExt : string;
  783. begin
  784. GetTargetExeExt:=target_info.exeext;
  785. end;
  786. var
  787. s,FileName: string;
  788. ErrFile : Text;
  789. MustRestartDebugger : boolean;
  790. Error,LinkErrorCount : longint;
  791. E : TEvent;
  792. DummyView: PView;
  793. PPasFile : string[64];
  794. begin
  795. AskRecompileIfModifiedFlag:=true;
  796. { Get FileName }
  797. FileName:=GetMainFile(Mode);
  798. if FileName='' then
  799. begin
  800. ErrorBox(msg_nothingtocompile,nil);
  801. Exit;
  802. end else
  803. { THis is not longer necessary as unsaved files are loaded from a memorystream,
  804. and with the file as primaryfile set it is already incompatible with itself
  805. if FileName='*' then
  806. begin
  807. ErrorBox(msg_cantcompileunsavedfile,nil);
  808. Exit;
  809. end; }
  810. PushStatus('Beginning compilation...');
  811. { Show Compiler Messages Window }
  812. { if not CompilerMessageWindow^.GetState(sfVisible) then
  813. CompilerMessageWindow^.Show;
  814. CompilerMessageWindow^.MakeFirst;}
  815. CompilerMessageWindow^.ClearMessages;
  816. { Tell why we compile }
  817. NeedRecompile(Mode,true);
  818. MainFile:=FileName;
  819. SetStatus('Writing switches to file...');
  820. WriteSwitches(SwitchesPath);
  821. { leaving open browsers leads to crashes !! (PM) }
  822. SetStatus('Preparing symbol info...');
  823. CloseAllBrowsers;
  824. if ((DesktopFileFlags and dfSymbolInformation)<>0) then
  825. WriteSymbolsFile(BrowserName);
  826. { MainFile:=FixFileName(FExpand(FileName));}
  827. SetStatus('Preparing to compile...'+NameOf(MainFile));
  828. { Reset }
  829. CtrlBreakHit:=false;
  830. { Create Compiler Status Dialog }
  831. CompilationPhase:=cpCompiling;
  832. if not assigned(CompilingHiddenFile) then
  833. begin
  834. New(CompilerStatusDialog, Init);
  835. CompilerStatusDialog^.SetStartTime(getrealtime);
  836. CompilerStatusDialog^.SetState(sfModal,true);
  837. { disable window closing }
  838. CompilerStatusDialog^.Flags:=CompilerStatusDialog^.Flags and not wfclose;
  839. Application^.Insert(CompilerStatusDialog);
  840. CompilerStatusDialog^.Update;
  841. end;
  842. { Restore dir that could be changed during debugging }
  843. {$I-}
  844. ChDir(StartUpDir);
  845. {$I+}
  846. EatIO;
  847. { hook compiler output }
  848. do_status:=@CompilerStatus;
  849. do_comment:=@CompilerComment;
  850. do_openinputfile:=@CompilerOpenInputFile;
  851. do_getnamedfiletime:=@CompilerGetNamedFileTime;
  852. do_initsymbolinfo:=@InitBrowserCol;
  853. do_donesymbolinfo:=@DoneBrowserCol;
  854. do_extractsymbolinfo:=@CreateBrowserCol;
  855. { Compile ! }
  856. {$ifdef redircompiler}
  857. ChangeRedirOut(FPOutFileName,false);
  858. ChangeRedirError(FPErrFileName,false);
  859. {$endif}
  860. { insert "" around name so that spaces are allowed }
  861. { only supported in compiler after 2000/01/14 PM }
  862. if pos(' ',FileName)>0 then
  863. FileName:='"'+FileName+'"';
  864. if mode=cBuild then
  865. FileName:='-B '+FileName;
  866. { tokens are created and distroed by compiler.compile !! PM }
  867. DoneTokens;
  868. PPasFile:='ppas'+source_info.scriptext;
  869. WUtils.DeleteFile(GetExePath+PpasFile);
  870. SetStatus('Compiling...');
  871. inc(CompileStamp);
  872. ResetErrorMessages;
  873. {$ifndef NODEBUG}
  874. MustRestartDebugger:=false;
  875. if assigned(Debugger) then
  876. if Debugger^.HasExe then
  877. begin
  878. Debugger^.Reset;
  879. MustRestartDebugger:=true;
  880. end;
  881. {$endif NODEBUG}
  882. try
  883. FpIntF.Compile(FileName,SwitchesPath);
  884. except
  885. on ECompilerAbort do
  886. CompilerMessageWindow^.AddMessage(V_error,'Error during compilation','',0,0);
  887. on E:Exception do
  888. CompilerMessageWindow^.AddMessage(V_error,E.Message+' during compilation','',0,0);
  889. end;
  890. SetStatus('Finished compiling...');
  891. { Retrieve created exefile }
  892. If GetEXEPath<>'' then
  893. EXEFile:=FixFileName(GetEXEPath+NameOf(MainFile)+GetTargetExeExt)
  894. else
  895. EXEFile:=DirOf(MainFile)+NameOf(MainFile)+GetTargetExeExt;
  896. DefaultReplacements(ExeFile);
  897. { tokens are created and distroyed by compiler.compile !! PM }
  898. InitTokens;
  899. if LinkAfter and
  900. ExistsFile(GetExePath+PpasFile) and
  901. (CompilationPhase<>cpAborted) and
  902. (status.errorCount=0) then
  903. begin
  904. CompilationPhase:=cpLinking;
  905. if assigned(CompilerStatusDialog) then
  906. CompilerStatusDialog^.Update;
  907. SetStatus('Assembling and/or linking...');
  908. {$ifndef redircompiler}
  909. { At least here we want to catch output
  910. of batch file PM }
  911. ChangeRedirOut(FPOutFileName,false);
  912. ChangeRedirError(FPErrFileName,false);
  913. {$endif}
  914. {$ifdef Unix}
  915. error:=0;
  916. If Shell(GetExePath+PpasFile)=-1 Then
  917. Error:=fpgeterrno;
  918. {$else}
  919. DosExecute(GetEnv('COMSPEC'),'/C '+GetExePath+PpasFile);
  920. Error:=DosError;
  921. {$endif}
  922. SetStatus('Finished linking...');
  923. RestoreRedirOut;
  924. RestoreRedirError;
  925. if Error<>0 then
  926. Inc(status.errorCount);
  927. if Status.IsExe and not Status.IsLibrary and not ExistsFile(EXEFile) then
  928. begin
  929. Inc(status.errorCount);
  930. ClearFormatParams; AddFormatParamStr(ExeFile);
  931. CompilerMessageWindow^.AddMessage(V_error,FormatStrF(msg_couldnotcreatefile,FormatParams),'',0,0);
  932. {$I-}
  933. Assign(ErrFile,FPErrFileName);
  934. Reset(ErrFile);
  935. if EatIO<>0 then
  936. ErrorBox(FormatStrStr(msg_cantopenfile,FPErrFileName),nil)
  937. else
  938. begin
  939. LinkErrorCount:=0;
  940. While not eof(ErrFile) and (LinkErrorCount<25) do
  941. begin
  942. readln(ErrFile,s);
  943. CompilerMessageWindow^.AddMessage(V_error,s,'',0,0);
  944. inc(LinkErrorCount);
  945. end;
  946. if not eof(ErrFile) then
  947. begin
  948. ClearFormatParams; AddFormatParamStr(FPErrFileName);
  949. CompilerMessageWindow^.AddMessage(V_error,
  950. FormatStrF(msg_therearemoreerrorsinfile,FormatParams),'',0,0);
  951. end;
  952. Close(ErrFile);
  953. end;
  954. EatIO;
  955. {$I+}
  956. end
  957. else if error=0 then
  958. WUtils.DeleteFile(GetExePath+PpasFile);
  959. end;
  960. {$ifdef redircompiler}
  961. RestoreRedirOut;
  962. RestoreRedirError;
  963. {$endif}
  964. PopStatus;
  965. { Set end status }
  966. if not (CompilationPhase in [cpAborted,cpFailed]) then
  967. if (status.errorCount=0) then
  968. begin
  969. CompilationPhase:=cpDone;
  970. LastCompileTime := cardinal(Now);
  971. end
  972. else
  973. CompilationPhase:=cpFailed;
  974. { Show end status }
  975. { reenable window closing }
  976. if assigned(CompilerStatusDialog) then
  977. begin
  978. CompilerStatusDialog^.Flags:=CompilerStatusDialog^.Flags or wfclose;
  979. CompilerStatusDialog^.Update;
  980. CompilerStatusDialog^.ReDraw;
  981. CompilerStatusDialog^.SetState(sfModal,false);
  982. if ((CompilationPhase in [cpAborted,cpDone,cpFailed]) or (ShowStatusOnError))
  983. and ((Mode<>cRun) or (CompilationPhase<>cpDone)) then
  984. repeat
  985. CompilerStatusDialog^.GetEvent(E);
  986. if IsExitEvent(E)=false then
  987. CompilerStatusDialog^.HandleEvent(E);
  988. until IsExitEvent(E) or not assigned(CompilerStatusDialog);
  989. {if IsExitEvent(E) then
  990. Application^.PutEvent(E);}
  991. if assigned(CompilerStatusDialog) then
  992. begin
  993. Application^.Delete(CompilerStatusDialog);
  994. Dispose(CompilerStatusDialog, Done);
  995. end;
  996. end;
  997. CompilerStatusDialog:=nil;
  998. { end compilation returns true if the messagewindow should be removed }
  999. if CompilationPhase=cpDone then
  1000. begin
  1001. CompilerMessageWindow^.Hide;
  1002. { This is the last compiled main file }
  1003. PrevMainFile:=MainFile;
  1004. MainHasDebugInfo:=DebugInfoSwitches^.GetCurrSelParam<>'-';
  1005. end;
  1006. { Update the app }
  1007. Message(Application,evCommand,cmUpdate,nil);
  1008. DummyView:=Desktop^.First;
  1009. while (DummyView<>nil) and (DummyView^.GetState(sfVisible)=false) do
  1010. begin
  1011. DummyView:=DummyView^.NextView;
  1012. end;
  1013. with DummyView^ do
  1014. if GetState(sfVisible) then
  1015. begin
  1016. SetState(sfSelected,false);
  1017. SetState(sfSelected,true);
  1018. end;
  1019. if Assigned(CompilerMessageWindow) then
  1020. with CompilerMessageWindow^ do
  1021. begin
  1022. if GetState(sfVisible) then
  1023. begin
  1024. SetState(sfSelected,false);
  1025. SetState(sfSelected,true);
  1026. end;
  1027. if (status.errorCount>0) then
  1028. MsgLB^.SelectFirstError;
  1029. end;
  1030. { ^^^ we need this trick to reactivate the desktop }
  1031. EditorModified:=false;
  1032. {$ifndef NODEBUG}
  1033. if MustRestartDebugger then
  1034. InitDebugger;
  1035. {$endif NODEBUG}
  1036. { In case we have something that the compiler touched }
  1037. AskToReloadAllModifiedFiles;
  1038. { Try to read Browser info in again if compilation failure !! }
  1039. if Not Assigned(Modules) and (CompilationPhase<>cpDone) and
  1040. ((DesktopFileFlags and dfSymbolInformation)<>0) then
  1041. ReadSymbolsFile(BrowserName);
  1042. if UseAllUnitsInCodeComplete and not assigned(CompilingHiddenFile) then
  1043. AddAvailableUnitsToCodeComplete(false);
  1044. end;
  1045. function NeedRecompile(Mode :TCompileMode; verbose : boolean): boolean;
  1046. var Need: boolean;
  1047. I: sw_integer;
  1048. SF: PSourceFile;
  1049. SourceTime,PPUTime,ObjTime: longint;
  1050. W: PSourceWindow;
  1051. begin
  1052. if Assigned(SourceFiles)=false then
  1053. Need:={(EditorModified=true)}true
  1054. else
  1055. begin
  1056. Need:=(PrevMainFile<>GetMainFile(Mode)) and (PrevMainFile<>'');
  1057. if Need then
  1058. begin
  1059. if verbose then
  1060. begin
  1061. ClearFormatParams; AddFormatParamStr(GetMainFile(Mode));
  1062. CompilerMessageWindow^.AddMessage(V_info,
  1063. FormatStrF(msg_firstcompilationof,FormatParams),
  1064. '',0,0);
  1065. end;
  1066. end
  1067. else
  1068. for I:=0 to SourceFiles^.Count-1 do
  1069. begin
  1070. SF:=SourceFiles^.At(I);
  1071. SourceTime:=wutils.GetFileTime(SF^.GetSourceFileName);
  1072. PPUTime:=wutils.GetFileTime(SF^.GetPPUFileName);
  1073. ObjTime:=wutils.GetFileTime(SF^.GetObjFileName);
  1074. { writeln('S: ',SF^.GetSourceFileName,' - ',SourceTime);
  1075. writeln('P: ',SF^.GetPPUFileName,' - ',PPUTime);
  1076. writeln('O: ',SF^.GetObjFileName,' - ',ObjTime);
  1077. writeln('------');}
  1078. { some units don't generate object files }
  1079. W:=EditorWindowFile(SF^.GetSourceFileName);
  1080. if (SourceTime<>-1) then
  1081. if ((SourceTime>PPUTime) or
  1082. ((SourceTime>ObjTime) and
  1083. (ObjTime<>-1))) or
  1084. (assigned(W) and (W^.Editor^.CompileStamp<0)) then
  1085. begin
  1086. Need:=true;
  1087. if verbose then
  1088. begin
  1089. ClearFormatParams; AddFormatParamStr(SF^.GetSourceFileName);
  1090. CompilerMessageWindow^.AddMessage(V_info,
  1091. FormatStrF(msg_recompilingbecauseof,FormatParams),
  1092. SF^.GetSourceFileName,1,1);
  1093. end;
  1094. Break;
  1095. end;
  1096. end;
  1097. { writeln('Need?', Need); system.readln;}
  1098. end;
  1099. NeedRecompile:=Need;
  1100. end;
  1101. constructor TFPInputFile.Create(AEditor: PFileEditor);
  1102. begin
  1103. if not Assigned(AEditor) then Fail;
  1104. if inherited Create(AEditor^.FileName)=nil then
  1105. Fail;
  1106. Editor:=AEditor;
  1107. end;
  1108. function TFPInputFile.fileopen(const filename: string): boolean;
  1109. var OK: boolean;
  1110. begin
  1111. S:=New(PMemoryStream, Init(0,0));
  1112. OK:=Assigned(S) and (S^.Status=stOK);
  1113. if OK then OK:=Editor^.SaveToStream(S);
  1114. if OK then
  1115. S^.Seek(0)
  1116. else
  1117. begin
  1118. if Assigned(S) then Dispose(S, Done);
  1119. S:=nil;
  1120. end;
  1121. fileopen:=OK;
  1122. end;
  1123. function TFPInputFile.fileseek(pos: longint): boolean;
  1124. var OK: boolean;
  1125. begin
  1126. OK:=assigned(S);
  1127. if OK then
  1128. begin
  1129. S^.Reset;
  1130. S^.Seek(pos);
  1131. OK:=(S^.Status=stOK);
  1132. end;
  1133. fileseek:=OK;
  1134. end;
  1135. function TFPInputFile.fileread(var databuf; maxsize: longint): longint;
  1136. var
  1137. size: longint;
  1138. begin
  1139. if not assigned(S) then size:=0 else
  1140. begin
  1141. size:=min(maxsize,(S^.GetSize-S^.GetPos));
  1142. S^.Read(databuf,size);
  1143. if S^.Status<>stOK then size:=0;
  1144. end;
  1145. fileread:=size;
  1146. end;
  1147. function TFPInputFile.fileeof: boolean;
  1148. var EOF: boolean;
  1149. begin
  1150. EOF:=not assigned(S);
  1151. if not EOF then
  1152. EOF:=(S^.Status<>stOK) or (S^.GetPos=S^.GetSize);
  1153. fileeof:=EOF;
  1154. end;
  1155. function TFPInputFile.fileclose: boolean;
  1156. var OK: boolean;
  1157. begin
  1158. OK:=assigned(S);
  1159. if OK then
  1160. begin
  1161. S^.Reset;
  1162. Dispose(S, Done);
  1163. S:=nil;
  1164. OK:=true;
  1165. end;
  1166. fileclose:=OK;
  1167. end;
  1168. procedure tfpinputfile.filegettime;
  1169. var
  1170. dt : datetime;
  1171. hsec,wday : word;
  1172. begin
  1173. { current time }
  1174. dos.getdate(dt.year,dt.month,dt.day,wday);
  1175. dos.gettime(dt.hour,dt.min,dt.sec,hsec);
  1176. packtime(dt,filetime);
  1177. end;
  1178. procedure RegisterFPCompile;
  1179. begin
  1180. {$ifndef NOOBJREG}
  1181. RegisterType(RCompilerMessageListBox);
  1182. RegisterType(RCompilerMessageWindow);
  1183. {$endif}
  1184. end;
  1185. end.