fpcompil.pas 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. Compiler call routines for the IDE
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$i globdir.inc}
  13. unit FPCompile;
  14. interface
  15. { don't redir under linux, because all stdout (also from the ide!) will
  16. then be redired (PFV) }
  17. { this should work now correctly because
  18. RedirDisableAll and RedirEnableAll function are added in fpredir (PM) }
  19. { $define VERBOSETXT}
  20. uses
  21. Objects,
  22. Drivers,Views,Dialogs,
  23. WViews,
  24. FPSymbol,
  25. FPViews;
  26. type
  27. TCompileMode = (cBuild,cMake,cCompile,cRun);
  28. type
  29. PCompilerMessage = ^TCompilerMessage;
  30. TCompilerMessage = object(TMessageItem)
  31. function GetText(MaxLen: Sw_Integer): String; virtual;
  32. end;
  33. PCompilerMessageListBox = ^TCompilerMessageListBox;
  34. TCompilerMessageListBox = object(TMessageListBox)
  35. function GetPalette: PPalette; virtual;
  36. end;
  37. PCompilerMessageWindow = ^TCompilerMessageWindow;
  38. TCompilerMessageWindow = object(TFPWindow)
  39. constructor Init;
  40. procedure HandleEvent(var Event: TEvent); virtual;
  41. function GetPalette: PPalette; virtual;
  42. procedure Close;virtual;
  43. destructor Done; virtual;
  44. procedure SizeLimits(var Min, Max: TPoint); virtual;
  45. procedure AddMessage(AClass: longint;const Msg, Module: string; Line, Column: longint);
  46. procedure ClearMessages;
  47. constructor Load(var S: TStream);
  48. procedure Store(var S: TStream);
  49. private
  50. {CompileShowed : boolean;}
  51. Mode : TCompileMode;
  52. MsgLB : PCompilerMessageListBox;
  53. {CurrST,
  54. InfoST : PColorStaticText;}
  55. end;
  56. PCompilerStatusDialog = ^TCompilerStatusDialog;
  57. TCompilerStatusDialog = object(TCenterDialog)
  58. ST : PAdvancedStaticText;
  59. KeyST : PColorStaticText;
  60. constructor Init;
  61. procedure Update;
  62. end;
  63. const
  64. CompilerMessageWindow : PCompilerMessageWindow = nil;
  65. CompilerStatusDialog : PCompilerStatusDialog = nil;
  66. procedure DoCompile(Mode: TCompileMode);
  67. function NeedRecompile: boolean;
  68. procedure RegisterFPCompile;
  69. implementation
  70. uses
  71. {$ifdef linux}
  72. Linux,
  73. {$endif}
  74. Dos,Video,
  75. App,Commands,tokens,
  76. CompHook, Compiler, systems, browcol,
  77. WUtils,WEditor,
  78. FPRedir,FPDesk,
  79. FPIde,FPConst,FPVars,FPUtils,FPIntf,FPSwitch;
  80. {$ifndef NOOBJREG}
  81. const
  82. RCompilerMessageListBox: TStreamRec = (
  83. ObjType: 1211;
  84. VmtLink: Ofs(TypeOf(TCompilerMessageListBox)^);
  85. Load: @TCompilerMessageListBox.Load;
  86. Store: @TCompilerMessageListBox.Store
  87. );
  88. RCompilerMessageWindow: TStreamRec = (
  89. ObjType: 1212;
  90. VmtLink: Ofs(TypeOf(TCompilerMessageWindow)^);
  91. Load: @TCompilerMessageWindow.Load;
  92. Store: @TCompilerMessageWindow.Store
  93. );
  94. {$endif}
  95. {*****************************************************************************
  96. TCompilerMessage
  97. *****************************************************************************}
  98. function TCompilerMessage.GetText(MaxLen: Sw_Integer): String;
  99. var
  100. ClassS: string[20];
  101. S: string;
  102. begin
  103. if TClass=
  104. V_Fatal then ClassS:='Fatal' else if TClass =
  105. V_Error then ClassS:='Error' else if TClass =
  106. V_Normal then ClassS:='' else if TClass =
  107. V_Warning then ClassS:='Warning' else if TClass =
  108. V_Note then ClassS:='Note' else if TClass =
  109. V_Hint then ClassS:='Hint'
  110. {$ifdef VERBOSETXT}
  111. else if TClass =
  112. V_Macro then ClassS:='Macro' else if TClass =
  113. V_Procedure then ClassS:='Procedure' else if TClass =
  114. V_Conditional then ClassS:='Conditional' else if TClass =
  115. V_Info then ClassS:='Info' else if TClass =
  116. V_Status then ClassS:='Status' else if TClass =
  117. V_Used then ClassS:='Used' else if TClass =
  118. V_Tried then ClassS:='Tried' else if TClass =
  119. V_Debug then ClassS:='Debug'
  120. else
  121. ClassS:='???';
  122. {$else}
  123. else
  124. ClassS:='';
  125. {$endif}
  126. if ClassS<>'' then
  127. ClassS:=RExpand(ClassS,0)+': ';
  128. if assigned(Module) and
  129. (TClass<=V_ShowFile)
  130. {and (status.currentsource<>'') and (status.currentline>0)} then
  131. begin
  132. if Row>0 then
  133. begin
  134. if Col>0 then
  135. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+','+IntToStr(Col)+') '+ClassS
  136. else
  137. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+') '+ClassS;
  138. end
  139. else
  140. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+') '+ClassS
  141. end
  142. else
  143. S:=ClassS;
  144. if assigned(Text) then
  145. S:=S+Text^;
  146. if length(S)>MaxLen then
  147. S:=copy(S,1,MaxLen-2)+'..';
  148. GetText:=S;
  149. end;
  150. {*****************************************************************************
  151. TCompilerMessageListBox
  152. *****************************************************************************}
  153. function TCompilerMessageListBox.GetPalette: PPalette;
  154. const
  155. P: string[length(CBrowserListBox)] = CBrowserListBox;
  156. begin
  157. GetPalette:=@P;
  158. end;
  159. {*****************************************************************************
  160. TCompilerMessageWindow
  161. *****************************************************************************}
  162. constructor TCompilerMessageWindow.Init;
  163. var R: TRect;
  164. HSB,VSB: PScrollBar;
  165. begin
  166. Desktop^.GetExtent(R);
  167. R.A.Y:=R.B.Y-7;
  168. inherited Init(R,'Compiler Messages',{SearchFreeWindowNo}wnNoNumber);
  169. HelpCtx:=hcMessagesWindow;
  170. AutoNumber:=true;
  171. HSB:=StandardScrollBar(sbHorizontal+sbHandleKeyboard);
  172. HSB^.GrowMode:=gfGrowLoY+gfGrowHiX+gfGrowHiY;
  173. Insert(HSB);
  174. VSB:=StandardScrollBar(sbVertical+sbHandleKeyboard);
  175. VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  176. Insert(VSB);
  177. GetExtent(R);
  178. R.Grow(-1,-1);
  179. New(MsgLB, Init(R, HSB, VSB));
  180. MsgLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  181. Insert(MsgLB);
  182. CompilerMessageWindow:=@self;
  183. end;
  184. procedure TCompilerMessageWindow.AddMessage(AClass: longint;const Msg, Module: string; Line, Column: longint);
  185. begin
  186. if AClass>=V_Info then
  187. Line:=0;
  188. MsgLB^.AddItem(New(PCompilerMessage,Init(AClass, Msg, MsgLB^.AddModuleName(Module), Line, Column)));
  189. end;
  190. procedure TCompilerMessageWindow.ClearMessages;
  191. begin
  192. MsgLB^.Clear;
  193. ReDraw;
  194. end;
  195. {procedure TCompilerMessageWindow.Updateinfo;
  196. begin
  197. if CompileShowed then
  198. begin
  199. InfoST^.SetText(
  200. RExpand(' Main file : '#1#$7f+Copy(SmartPath(MainFile),1,39),40)+#2+
  201. 'Total lines : '#1#$7e+IntToStr(Status.CompiledLines)+#2#13+
  202. RExpand(' Target : '#1#$7f+KillTilde(TargetSwitches^.ItemName(TargetSwitches^.GetCurrSel)),40)+#2+
  203. 'Total errors : '#1#$7e+IntToStr(Status.ErrorCount)
  204. );
  205. if status.currentline>0 then
  206. CurrST^.SetText(' Status: '#1#$7e+status.currentsource+'('+IntToStr(status.currentline)+')'#2)
  207. else
  208. CurrST^.SetText(' Status: '#1#$7e+status.currentsource+#2);
  209. end;
  210. ReDraw;
  211. end;}
  212. procedure TCompilerMessageWindow.HandleEvent(var Event: TEvent);
  213. begin
  214. case Event.What of
  215. evBroadcast :
  216. case Event.Command of
  217. cmListFocusChanged :
  218. if Event.InfoPtr=MsgLB then
  219. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  220. end;
  221. end;
  222. inherited HandleEvent(Event);
  223. end;
  224. procedure TCompilerMessageWindow.SizeLimits(var Min, Max: TPoint);
  225. begin
  226. inherited SizeLimits(Min,Max);
  227. Min.X:=20;
  228. Min.Y:=4;
  229. end;
  230. procedure TCompilerMessageWindow.Close;
  231. begin
  232. Hide;
  233. end;
  234. function TCompilerMessageWindow.GetPalette: PPalette;
  235. const
  236. S : string[length(CBrowserWindow)] = CBrowserWindow;
  237. begin
  238. GetPalette:=@S;
  239. end;
  240. constructor TCompilerMessageWindow.Load(var S: TStream);
  241. begin
  242. inherited Load(S);
  243. GetSubViewPtr(S,MsgLB);
  244. end;
  245. procedure TCompilerMessageWindow.Store(var S: TStream);
  246. begin
  247. if MsgLB^.List=nil then
  248. MsgLB^.NewList(New(PCollection, Init(100,100)));
  249. inherited Store(S);
  250. PutSubViewPtr(S,MsgLB);
  251. end;
  252. destructor TCompilerMessageWindow.Done;
  253. begin
  254. CompilerMessageWindow:=nil;
  255. inherited Done;
  256. end;
  257. {****************************************************************************
  258. CompilerStatusDialog
  259. ****************************************************************************}
  260. constructor TCompilerStatusDialog.Init;
  261. var R: TRect;
  262. begin
  263. R.Assign(0,0,50,11);
  264. inherited Init(R, 'Compiling');
  265. GetExtent(R); R.B.Y:=11;
  266. R.Grow(-3,-2);
  267. New(ST, Init(R, ''));
  268. Insert(ST);
  269. GetExtent(R); R.B.Y:=11;
  270. R.Grow(-1,-1); R.A.Y:=R.B.Y-1;
  271. New(KeyST, Init(R, '', Blue*16+White+longint($80+Blue*16+White)*256));
  272. Insert(KeyST);
  273. end;
  274. procedure TCompilerStatusDialog.Update;
  275. const
  276. CtrlBS = 'Press ESC to cancel';
  277. SuccessS = 'Compile successful: ~Press Enter~';
  278. FailS = 'Compile failed';
  279. AbortS = 'Compile aborted';
  280. var
  281. StatusS,KeyS: string;
  282. begin
  283. {$ifdef TEMPHEAP}
  284. switch_to_base_heap;
  285. {$endif TEMPHEAP}
  286. case CompilationPhase of
  287. cpCompiling :
  288. begin
  289. StatusS:='Compiling '+SmartPath(Status.CurrentSource);
  290. KeyS:=CtrlBS;
  291. end;
  292. cpLinking :
  293. begin
  294. StatusS:='Linking '+ExeFile;
  295. KeyS:=CtrlBS;
  296. end;
  297. cpDone :
  298. begin
  299. StatusS:='Done.';
  300. KeyS:=SuccessS;
  301. end;
  302. cpFailed :
  303. begin
  304. StatusS:='Failed to compile...';
  305. KeyS:=FailS;
  306. end;
  307. cpAborted :
  308. begin
  309. StatusS:='Compilation aborted...';
  310. KeyS:=AbortS;
  311. end;
  312. end;
  313. ST^.SetText(
  314. 'Main file: '+SmartPath(MainFile)+#13+
  315. StatusS+#13#13+
  316. 'Target: '+LExpand(KillTilde(TargetSwitches^.ItemName(TargetSwitches^.GetCurrSel)),12)+' '+
  317. 'Line number: '+IntToStrL(Status.CurrentLine,7)+#13+
  318. 'Free memory: '+IntToStrL(MemAvail div 1024,6)+'K'+ ' '+
  319. 'Total lines: '+IntToStrL(Status.CompiledLines,7)+#13+
  320. 'Total errors: '+IntToStrL(Status.ErrorCount,5)
  321. );
  322. KeyST^.SetText(^C+KeyS);
  323. {$ifdef TEMPHEAP}
  324. switch_to_temp_heap;
  325. {$endif TEMPHEAP}
  326. end;
  327. {****************************************************************************
  328. Compiler Hooks
  329. ****************************************************************************}
  330. function CompilerStatus: boolean; {$ifndef FPC}far;{$endif}
  331. var
  332. event : tevent;
  333. begin
  334. GetKeyEvent(Event);
  335. if (Event.What=evKeyDown) and (Event.KeyCode=kbEsc) then
  336. begin
  337. CompilationPhase:=cpAborted;
  338. { update info messages }
  339. if assigned(CompilerStatusDialog) then
  340. begin
  341. {$ifdef redircompiler}
  342. RedirDisableAll;
  343. {$endif}
  344. CompilerStatusDialog^.Update;
  345. {$ifdef redircompiler}
  346. RedirEnableAll;
  347. {$endif}
  348. end;
  349. CompilerStatus:=true;
  350. exit;
  351. end;
  352. { only display line info every 100 lines, ofcourse all other messages
  353. will be displayed directly }
  354. if (status.currentline mod 100=0) then
  355. begin
  356. { update info messages }
  357. {$ifdef redircompiler}
  358. RedirDisableAll;
  359. {$endif}
  360. if assigned(CompilerStatusDialog) then
  361. CompilerStatusDialog^.Update;
  362. {$ifdef redircompiler}
  363. RedirEnableAll;
  364. {$endif}
  365. { update memory usage }
  366. { HeapView^.Update; }
  367. end;
  368. CompilerStatus:=false;
  369. end;
  370. procedure CompilerStop; {$ifndef FPC}far;{$endif}
  371. begin
  372. end;
  373. function CompilerComment(Level:Longint; const s:string):boolean; {$ifndef FPC}far;{$endif}
  374. begin
  375. {$ifdef TEMPHEAP}
  376. switch_to_base_heap;
  377. {$endif TEMPHEAP}
  378. CompilerComment:=false;
  379. {$ifndef DEV}
  380. if (status.verbosity and Level)=Level then
  381. {$endif}
  382. begin
  383. {$ifdef redircompiler}
  384. RedirDisableAll;
  385. {$endif}
  386. CompilerMessageWindow^.AddMessage(Level,S,status.currentsourcepath+status.currentsource,
  387. status.currentline,status.currentcolumn);
  388. { update info messages }
  389. if assigned(CompilerStatusDialog) then
  390. CompilerStatusDialog^.Update;
  391. {$ifdef DEBUG}
  392. {$ifndef NODEBUG}
  393. def_gdb_stop(level);
  394. {$endif}
  395. {$endif DEBUG}
  396. {$ifdef redircompiler}
  397. RedirEnableAll;
  398. {$endif}
  399. { update memory usage }
  400. { HeapView^.Update; }
  401. end;
  402. {$ifdef TEMPHEAP}
  403. switch_to_temp_heap;
  404. {$endif TEMPHEAP}
  405. end;
  406. {****************************************************************************
  407. DoCompile
  408. ****************************************************************************}
  409. function GetExePath: string;
  410. var Path: string;
  411. I: Sw_integer;
  412. begin
  413. Path:='.'+DirSep;
  414. if DirectorySwitches<>nil then
  415. with DirectorySwitches^ do
  416. for I:=0 to ItemCount-1 do
  417. begin
  418. if Pos('EXE',KillTilde(ItemName(I)))>0 then
  419. begin Path:=GetStringItem(I); Break; end;
  420. end;
  421. GetExePath:=CompleteDir(FExpand(Path));
  422. end;
  423. function GetMainFile: string;
  424. var FileName: string;
  425. P : PSourceWindow;
  426. begin
  427. P:=Message(Desktop,evBroadcast,cmSearchWindow,nil);
  428. if (PrimaryFileMain='') and (P=nil) then
  429. FileName:='' { nothing to compile }
  430. else
  431. begin
  432. if PrimaryFileMain<>'' then
  433. FileName:=PrimaryFileMain
  434. else
  435. begin
  436. if P^.Editor^.Modified and (not P^.Editor^.Save) then
  437. FileName:='*' { file not saved }
  438. else
  439. FileName:=P^.Editor^.FileName;
  440. end;
  441. end;
  442. FileName:=FixFileName(FExpand(FileName));
  443. GetMainFile:=FileName;
  444. end;
  445. procedure DoCompile(Mode: TCompileMode);
  446. function IsExitEvent(E: TEvent): boolean;
  447. begin
  448. IsExitEvent:=(E.What=evKeyDown) and
  449. ((E.KeyCode=kbEnter) or (E.KeyCode=kbEsc)) or
  450. ((E.What=evCommand) and (E.command=cmClose));
  451. end;
  452. var
  453. s,FileName: string;
  454. ErrFile : Text;
  455. Error,LinkErrorCount : longint;
  456. E : TEvent;
  457. const
  458. PpasFile = 'ppas';
  459. begin
  460. { Get FileName }
  461. FileName:=GetMainFile;
  462. if FileName='' then
  463. begin
  464. ErrorBox('Oooops, nothing to compile.',nil);
  465. Exit;
  466. end else
  467. if FileName='*' then
  468. begin
  469. ErrorBox('Can''t compile unsaved file.',nil);
  470. Exit;
  471. end;
  472. PrevMainFile:=MainFile;
  473. MainFile:=FileName;
  474. WriteSwitches(SwitchesPath);
  475. { leaving open browsers leads to crashes !! (PM) }
  476. CloseAllBrowsers;
  477. if ((DesktopFileFlags and dfSymbolInformation)<>0) then
  478. WriteSymbolsFile(BrowserName);
  479. { MainFile:=FixFileName(FExpand(FileName));}
  480. If GetEXEPath<>'' then
  481. EXEFile:=FixFileName(GetEXEPath+NameOf(MainFile)+ExeExt)
  482. else
  483. EXEFile:=DirOf(MainFile)+NameOf(MainFile)+ExeExt;
  484. { Reset }
  485. CtrlBreakHit:=false;
  486. { Show Compiler Messages Window }
  487. if not CompilerMessageWindow^.GetState(sfVisible) then
  488. CompilerMessageWindow^.Show;
  489. CompilerMessageWindow^.MakeFirst;
  490. CompilerMessageWindow^.ClearMessages;
  491. { Create Compiler Status Dialog }
  492. CompilationPhase:=cpCompiling;
  493. New(CompilerStatusDialog, Init);
  494. CompilerStatusDialog^.SetState(sfModal,true);
  495. Application^.Insert(CompilerStatusDialog);
  496. CompilerStatusDialog^.Update;
  497. { hook compiler output }
  498. {$ifdef TP}
  499. do_status:=CompilerStatus;
  500. do_stop:=CompilerStop;
  501. do_comment:=CompilerComment;
  502. {$else not TP}
  503. do_status:=@CompilerStatus;
  504. do_stop:=@CompilerStop;
  505. do_comment:=@CompilerComment;
  506. {$endif TP}
  507. { Compile ! }
  508. {$ifdef redircompiler}
  509. ChangeRedirOut(FPOutFileName,false);
  510. ChangeRedirError(FPErrFileName,false);
  511. {$endif}
  512. {$ifdef TEMPHEAP}
  513. split_heap;
  514. switch_to_temp_heap;
  515. {$endif TEMPHEAP}
  516. { insert "" around name so that spaces are allowed }
  517. { only supported in compiler after 2000/01/14 PM }
  518. if pos(' ',FileName)>0 then
  519. FileName:='"'+FileName+'"';
  520. if mode=cBuild then
  521. FileName:='-B '+FileName;
  522. { tokens are created and distroed by compiler.compile !! PM }
  523. DoneTokens;
  524. FpIntF.Compile(FileName);
  525. { tokens are created and distroed by compiler.compile !! PM }
  526. InitTokens;
  527. if LinkAfter and IsExe and
  528. (CompilationPhase<>cpAborted) and
  529. (status.errorCount=0) then
  530. begin
  531. CompilationPhase:=cpLinking;
  532. CompilerStatusDialog^.Update;
  533. {$ifndef redircompiler}
  534. { At least here we want to catch output
  535. of batch file PM }
  536. ChangeRedirOut(FPOutFileName,false);
  537. ChangeRedirError(FPErrFileName,false);
  538. {$endif}
  539. {$ifdef linux}
  540. Shell(GetExePath+PpasFile+source_os.scriptext);
  541. Error:=LinuxError;
  542. {$else}
  543. DosExecute(GetEnv('COMSPEC'),'/C '+GetExePath+PpasFile+source_os.scriptext);
  544. Error:=DosError;
  545. {$endif}
  546. {$ifndef redircompiler}
  547. RestoreRedirOut;
  548. RestoreRedirError;
  549. {$endif}
  550. if Error<>0 then
  551. Inc(status.errorCount);
  552. if not ExistsFile(EXEFile) then
  553. begin
  554. Inc(status.errorCount);
  555. CompilerMessageWindow^.AddMessage(V_error,'could not create '+ExeFile,'',0,0);
  556. Assign(ErrFile,FPErrFileName);
  557. Reset(ErrFile);
  558. LinkErrorCount:=0;
  559. While not eof(ErrFile) and (LinkErrorCount<25) do
  560. begin
  561. readln(ErrFile,s);
  562. CompilerMessageWindow^.AddMessage(V_error,s,'',0,0);
  563. inc(LinkErrorCount);
  564. end;
  565. if not eof(ErrFile) then
  566. CompilerMessageWindow^.AddMessage(V_error,
  567. 'There are more errors in file '+FPErrFileName,'',0,0);
  568. Close(ErrFile);
  569. end;
  570. end;
  571. {$ifdef TEMPHEAP}
  572. switch_to_base_heap;
  573. {$endif TEMPHEAP}
  574. {$ifdef redircompiler}
  575. RestoreRedirOut;
  576. RestoreRedirError;
  577. {$endif}
  578. { Set end status }
  579. if CompilationPhase<>cpAborted then
  580. if (status.errorCount=0) then
  581. CompilationPhase:=cpDone
  582. else
  583. CompilationPhase:=cpFailed;
  584. { Show end status }
  585. CompilerStatusDialog^.Update;
  586. CompilerStatusDialog^.SetState(sfModal,false);
  587. if ((CompilationPhase in[cpAborted,cpDone,cpFailed]) or (ShowStatusOnError)) and (Mode<>cRun) then
  588. repeat
  589. CompilerStatusDialog^.GetEvent(E);
  590. if IsExitEvent(E)=false then
  591. CompilerStatusDialog^.HandleEvent(E);
  592. until IsExitEvent(E);
  593. Application^.Delete(CompilerStatusDialog);
  594. Dispose(CompilerStatusDialog, Done);
  595. CompilerStatusDialog:=nil;
  596. { endcompilation returns true if the messagewindow should be removed }
  597. if CompilationPhase=cpDone then
  598. CompilerMessageWindow^.Hide;
  599. { Update the app }
  600. Message(Application,evCommand,cmUpdate,nil);
  601. {$ifdef TEMPHEAP}
  602. releasetempheap;
  603. unsplit_heap;
  604. {$endif TEMPHEAP}
  605. if Assigned(CompilerMessageWindow) then
  606. with CompilerMessageWindow^ do
  607. if GetState(sfVisible) then
  608. begin
  609. SetState(sfSelected,false);
  610. SetState(sfSelected,true);
  611. end;
  612. { ^^^ we need this trick to reactivate the desktop }
  613. EditorModified:=false;
  614. { Try to read Browser info in again if compilation failure !! }
  615. if Not Assigned(Modules) and
  616. ((DesktopFileFlags and dfSymbolInformation)<>0) then
  617. ReadSymbolsFile(BrowserName);
  618. end;
  619. function NeedRecompile: boolean;
  620. var Need: boolean;
  621. I: sw_integer;
  622. SF: PSourceFile;
  623. SourceTime,PPUTime,ObjTime: longint;
  624. begin
  625. if Assigned(SourceFiles)=false then
  626. Need:={(EditorModified=true)}true
  627. else
  628. begin
  629. Need:=(PrevMainFile<>GetMainFile) and (PrevMainFile<>'');
  630. if Need=false then
  631. for I:=0 to SourceFiles^.Count-1 do
  632. begin
  633. SF:=SourceFiles^.At(I);
  634. SourceTime:=GetFileTime(SF^.GetSourceFileName);
  635. PPUTime:=GetFileTime(SF^.GetPPUFileName);
  636. ObjTime:=GetFileTime(SF^.GetObjFileName);
  637. { writeln('S: ',SF^.GetSourceFileName,' - ',SourceTime);
  638. writeln('P: ',SF^.GetPPUFileName,' - ',PPUTime);
  639. writeln('O: ',SF^.GetObjFileName,' - ',ObjTime);
  640. writeln('------');}
  641. { some units don't generate object files }
  642. if (SourceTime<>-1) then
  643. if (SourceTime>PPUTime) or
  644. ((SourceTime>ObjTime) and
  645. (ObjTime<>-1)) then
  646. begin
  647. Need:=true;
  648. Break;
  649. end;
  650. end;
  651. { writeln('Need?', Need); system.readln;}
  652. end;
  653. NeedRecompile:=Need;
  654. end;
  655. procedure RegisterFPCompile;
  656. begin
  657. {$ifndef NOOBJREG}
  658. RegisterType(RCompilerMessageListBox);
  659. RegisterType(RCompilerMessageWindow);
  660. {$endif}
  661. end;
  662. end.
  663. {
  664. $Log$
  665. Revision 1.49 2000-01-25 00:26:35 pierre
  666. + Browser info saving
  667. Revision 1.48 2000/01/14 15:38:28 pierre
  668. + support for long filenames with spaces for compilation
  669. * avoid too long linker error output
  670. Revision 1.47 2000/01/03 11:38:33 michael
  671. Changes from Gabor
  672. Revision 1.46 1999/12/01 17:08:19 pierre
  673. * GetFileTime moved to wutils unit
  674. Revision 1.45 1999/11/22 15:58:40 pierre
  675. * fix for web bug 633
  676. Revision 1.44 1999/11/21 01:44:34 pierre
  677. + Use def_gdb_stop for easy GDB debugging
  678. Revision 1.43 1999/11/18 13:49:56 pierre
  679. + use IsExe var to know if we need to call ppas
  680. Revision 1.42 1999/11/10 17:20:41 pierre
  681. * Use fpredir.dosexecute
  682. Revision 1.41 1999/10/25 16:34:19 pierre
  683. * some units have no object files
  684. led to wrong NeedRecompile result
  685. Revision 1.40 1999/09/20 15:36:38 pierre
  686. * adapted to new tokens unit
  687. Revision 1.39 1999/09/16 14:34:57 pierre
  688. + TBreakpoint and TWatch registering
  689. + WatchesCollection and BreakpointsCollection stored in desk file
  690. * Syntax highlighting was broken
  691. Revision 1.38 1999/09/13 16:24:43 peter
  692. + clock
  693. * backspace unident like tp7
  694. Revision 1.37 1999/09/09 14:19:16 pierre
  695. * status should not be present in TCompilerMessage.GetText
  696. Revision 1.36 1999/09/07 11:32:13 pierre
  697. * fix for Linux ./ prepended to ppas.sh
  698. * Build add '-B' option
  699. * if linkAfter is set, get errors from linker
  700. by redirecting files
  701. Revision 1.35 1999/08/22 22:27:30 pierre
  702. * not ppas call on compile failure
  703. Revision 1.34 1999/08/16 18:25:13 peter
  704. * Adjusting the selection when the editor didn't contain any line.
  705. * Reserved word recognition redesigned, but this didn't affect the overall
  706. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  707. The syntax scanner loop is a bit slow but the main problem is the
  708. recognition of special symbols. Switching off symbol processing boosts
  709. the performance up to ca. 200%...
  710. * The editor didn't allow copying (for ex to clipboard) of a single character
  711. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  712. * Compiler Messages window (actually the whole desktop) did not act on any
  713. keypress when compilation failed and thus the window remained visible
  714. + Message windows are now closed upon pressing Esc
  715. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  716. only when neccessary
  717. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  718. + LineSelect (Ctrl+K+L) implemented
  719. * The IDE had problems closing help windows before saving the desktop
  720. Revision 1.33 1999/08/03 20:22:26 peter
  721. + TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
  722. + Desktop saving should work now
  723. - History saved
  724. - Clipboard content saved
  725. - Desktop saved
  726. - Symbol info saved
  727. * syntax-highlight bug fixed, which compared special keywords case sensitive
  728. (for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
  729. * with 'whole words only' set, the editor didn't found occourences of the
  730. searched text, if the text appeared previously in the same line, but didn't
  731. satisfied the 'whole-word' condition
  732. * ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
  733. (ie. the beginning of the selection)
  734. * when started typing in a new line, but not at the start (X=0) of it,
  735. the editor inserted the text one character more to left as it should...
  736. * TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
  737. * Shift shouldn't cause so much trouble in TCodeEditor now...
  738. * Syntax highlight had problems recognizing a special symbol if it was
  739. prefixed by another symbol character in the source text
  740. * Auto-save also occours at Dos shell, Tool execution, etc. now...
  741. Revision 1.32 1999/07/12 13:14:13 pierre
  742. * LineEnd bug corrected, now goes end of text even if selected
  743. + Until Return for debugger
  744. + Code for Quit inside GDB Window
  745. Revision 1.31 1999/06/28 19:32:17 peter
  746. * fixes from gabor
  747. Revision 1.30 1999/06/28 15:59:04 pierre
  748. * View Linking stage if external linking
  749. Revision 1.29 1999/06/28 12:39:14 pierre
  750. + close all browsers before compiling
  751. Revision 1.28 1999/06/21 23:42:16 pierre
  752. + LinkAfter and Esc to abort support added
  753. Revision 1.27 1999/05/22 13:44:29 peter
  754. * fixed couple of bugs
  755. Revision 1.26 1999/05/02 14:29:35 peter
  756. * fixed typo disableredir -> redirdisable
  757. Revision 1.25 1999/04/29 22:58:09 pierre
  758. + disabling of redirction in compiler dialogs
  759. Revision 1.24 1999/04/29 09:36:11 peter
  760. * fixed hotkeys with Compiler switches
  761. * fixed compiler status dialog
  762. * Run shows again the output
  763. Revision 1.23 1999/04/07 21:55:43 peter
  764. + object support for browser
  765. * html help fixes
  766. * more desktop saving things
  767. * NODEBUG directive to exclude debugger
  768. Revision 1.22 1999/04/01 10:27:07 pierre
  769. + file(line) in start of message added
  770. Revision 1.21 1999/04/01 10:15:17 pierre
  771. * CurrSt,InfoSt and LineSt were not disposed correctly in done
  772. * TComiplerMessage destructor first calls SetCompileShow(false)
  773. to get proper cleaning up
  774. Revision 1.20 1999/03/23 16:16:38 peter
  775. * linux fixes
  776. Revision 1.19 1999/03/19 16:04:27 peter
  777. * new compiler dialog
  778. Revision 1.18 1999/03/16 12:38:07 peter
  779. * tools macro fixes
  780. + tph writer
  781. + first things for resource files
  782. Revision 1.17 1999/03/12 01:13:56 peter
  783. * flag if trytoopen should look for other extensions
  784. + browser tab in the tools-compiler
  785. Revision 1.16 1999/03/07 23:00:47 pierre
  786. * Fix for path of executable
  787. Revision 1.15 1999/03/01 15:41:50 peter
  788. + Added dummy entries for functions not yet implemented
  789. * MenuBar didn't update itself automatically on command-set changes
  790. * Fixed Debugging/Profiling options dialog
  791. * TCodeEditor converts spaces to tabs at save only if efUseTabChars is
  792. set
  793. * efBackSpaceUnindents works correctly
  794. + 'Messages' window implemented
  795. + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
  796. + Added TP message-filter support (for ex. you can call GREP thru
  797. GREP2MSG and view the result in the messages window - just like in TP)
  798. * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
  799. so topic search didn't work...
  800. * In FPHELP.PAS there were still context-variables defined as word instead
  801. of THelpCtx
  802. * StdStatusKeys() was missing from the statusdef for help windows
  803. + Topic-title for index-table can be specified when adding a HTML-files
  804. Revision 1.14 1999/02/22 12:46:56 peter
  805. * small fixes for linux and grep
  806. Revision 1.13 1999/02/22 11:51:33 peter
  807. * browser updates from gabor
  808. Revision 1.12 1999/02/22 11:29:36 pierre
  809. + added col info in MessageItem
  810. + grep uses HighLightExts and should work for linux
  811. Revision 1.11 1999/02/08 09:31:00 florian
  812. + some split heap stuff, in $ifdef TEMPHEAP
  813. Revision 1.10 1999/02/05 13:51:39 peter
  814. * unit name of FPSwitches -> FPSwitch which is easier to use
  815. * some fixes for tp7 compiling
  816. Revision 1.9 1999/02/05 13:06:28 pierre
  817. * allow cmClose for Compilation Dialog box
  818. Revision 1.8 1999/02/04 13:32:01 pierre
  819. * Several things added (I cannot commit them independently !)
  820. + added TBreakpoint and TBreakpointCollection
  821. + added cmResetDebugger,cmGrep,CmToggleBreakpoint
  822. + Breakpoint list in INIFile
  823. * Select items now also depend of SwitchMode
  824. * Reading of option '-g' was not possible !
  825. + added search for -Fu args pathes in TryToOpen
  826. + added code for automatic opening of FileDialog
  827. if source not found
  828. Revision 1.7 1999/01/21 11:54:11 peter
  829. + tools menu
  830. + speedsearch in symbolbrowser
  831. * working run command
  832. Revision 1.6 1999/01/15 16:12:43 peter
  833. * fixed crash after compile
  834. Revision 1.5 1999/01/14 21:42:19 peter
  835. * source tracking from Gabor
  836. Revision 1.4 1999/01/12 14:29:32 peter
  837. + Implemented still missing 'switch' entries in Options menu
  838. + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
  839. ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as
  840. ASCII chars and inserted directly in the text.
  841. + Added symbol browser
  842. * splitted fp.pas to fpide.pas
  843. Revision 1.3 1999/01/04 11:49:42 peter
  844. * 'Use tab characters' now works correctly
  845. + Syntax highlight now acts on File|Save As...
  846. + Added a new class to syntax highlight: 'hex numbers'.
  847. * There was something very wrong with the palette managment. Now fixed.
  848. + Added output directory (-FE<xxx>) support to 'Directories' dialog...
  849. * Fixed some possible bugs in Running/Compiling, and the compilation/run
  850. process revised
  851. Revision 1.2 1998/12/28 15:47:42 peter
  852. + Added user screen support, display & window
  853. + Implemented Editor,Mouse Options dialog
  854. + Added location of .INI and .CFG file
  855. + Option (INI) file managment implemented (see bottom of Options Menu)
  856. + Switches updated
  857. + Run program
  858. Revision 1.3 1998/12/22 10:39:40 peter
  859. + options are now written/read
  860. + find and replace routines
  861. }