fpcompil.pas 37 KB

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