fpcompil.pas 30 KB

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