fpcompil.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  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. unit FPCompile;
  13. interface
  14. { don't redir under linux, because all stdout (also from the ide!) will
  15. then be redired (PFV) }
  16. {$ifndef debug}
  17. {$ifndef linux}
  18. {$define redircompiler}
  19. {$endif}
  20. {$endif}
  21. { $define VERBOSETXT}
  22. uses
  23. Objects,
  24. Drivers,Views,Dialogs,
  25. WViews,
  26. FPViews;
  27. type
  28. TCompileMode = (cBuild,cMake,cCompile,cRun);
  29. {$ifndef OLDCOMP}
  30. type
  31. PCompilerMessage = ^TCompilerMessage;
  32. TCompilerMessage = object(TMessageItem)
  33. function GetText(MaxLen: Sw_Integer): String; virtual;
  34. end;
  35. PCompilerMessageListBox = ^TCompilerMessageListBox;
  36. TCompilerMessageListBox = object(TMessageListBox)
  37. function GetPalette: PPalette; virtual;
  38. end;
  39. PCompilerMessageWindow = ^TCompilerMessageWindow;
  40. TCompilerMessageWindow = object(TFPWindow)
  41. constructor Init;
  42. procedure Updateinfo;
  43. procedure HandleEvent(var Event: TEvent); virtual;
  44. function GetPalette: PPalette; virtual;
  45. procedure Close;virtual;
  46. procedure Zoom;virtual;
  47. destructor Done; virtual;
  48. procedure AddMessage(AClass: longint;const Msg, Module: string; Line, Column: longint);
  49. procedure ClearMessages;
  50. procedure SetCompileMode(Amode:TCompileMode);
  51. procedure SetCompileShow(b:boolean);
  52. procedure StartCompilation;
  53. function EndCompilation:boolean;
  54. constructor Load(var S: TStream);
  55. procedure Store(var S: TStream);
  56. private
  57. CompileShowed : boolean;
  58. Mode : TCompileMode;
  59. MsgLB : PCompilerMessageListBox;
  60. CurrST,
  61. InfoST : PColorStaticText;
  62. LineST : PStaticText;
  63. end;
  64. const
  65. CompilerMessageWindow : PCompilerMessageWindow = nil;
  66. {$else}
  67. type
  68. PCompileStatusDialog = ^TCompileStatusDialog;
  69. TCompileStatusDialog = object(TCenterDialog)
  70. ST : PAdvancedStaticText;
  71. KeyST : PColorStaticText;
  72. constructor Init;
  73. procedure Update;
  74. private
  75. MsgLB: PMessageListBox;
  76. end;
  77. const
  78. SD: PCompileStatusDialog = nil;
  79. {$endif}
  80. procedure DoCompile(Mode: TCompileMode);
  81. procedure RegisterFPCompile;
  82. implementation
  83. uses
  84. Dos,Video,
  85. App,Commands,
  86. CompHook,
  87. WUtils,WEditor,
  88. {$ifdef redircompiler}
  89. FPRedir,
  90. {$endif}
  91. FPConst,FPVars,FPUtils,FPIntf,FPSwitch;
  92. {$ifndef OLDCOMP}
  93. const
  94. RCompilerMessageListBox: TStreamRec = (
  95. ObjType: 1211;
  96. VmtLink: Ofs(TypeOf(TCompilerMessageListBox)^);
  97. Load: @TCompilerMessageListBox.Load;
  98. Store: @TCompilerMessageListBox.Store
  99. );
  100. RCompilerMessageWindow: TStreamRec = (
  101. ObjType: 1212;
  102. VmtLink: Ofs(TypeOf(TCompilerMessageWindow)^);
  103. Load: @TCompilerMessageWindow.Load;
  104. Store: @TCompilerMessageWindow.Store
  105. );
  106. {$else}
  107. {$endif}
  108. const
  109. LastStatusUpdate : longint = 0;
  110. {$ifndef OLDCOMP}
  111. {*****************************************************************************
  112. TCompilerMessage
  113. *****************************************************************************}
  114. function TCompilerMessage.GetText(MaxLen: Sw_Integer): String;
  115. var
  116. ClassS: string[20];
  117. S: string;
  118. begin
  119. if TClass=
  120. V_Fatal then ClassS:='Fatal' else if TClass =
  121. V_Error then ClassS:='Error' else if TClass =
  122. V_Normal then ClassS:='' else if TClass =
  123. V_Warning then ClassS:='Warning' else if TClass =
  124. V_Note then ClassS:='Note' else if TClass =
  125. V_Hint then ClassS:='Hint'
  126. {$ifdef VERBOSETXT}
  127. else if TClass =
  128. V_Macro then ClassS:='Macro' else if TClass =
  129. V_Procedure then ClassS:='Procedure' else if TClass =
  130. V_Conditional then ClassS:='Conditional' else if TClass =
  131. V_Info then ClassS:='Info' else if TClass =
  132. V_Status then ClassS:='Status' else if TClass =
  133. V_Used then ClassS:='Used' else if TClass =
  134. V_Tried then ClassS:='Tried' else if TClass =
  135. V_Debug then ClassS:='Debug'
  136. else
  137. ClassS:='???';
  138. {$else}
  139. else
  140. ClassS:='';
  141. {$endif}
  142. if ClassS<>'' then
  143. ClassS:=RExpand(ClassS,0)+': ';
  144. if assigned(Module) and
  145. (TClass<=V_ShowFile) and (status.currentsource<>'') and (status.currentline>0) then
  146. begin
  147. if Row>0 then
  148. begin
  149. if Col>0 then
  150. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+','+IntToStr(Col)+') '+ClassS
  151. else
  152. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+') '+ClassS;
  153. end
  154. else
  155. S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+') '+ClassS
  156. end
  157. else
  158. S:=ClassS;
  159. if assigned(Text) then
  160. S:=S+Text^;
  161. if length(S)>MaxLen then
  162. S:=copy(S,1,MaxLen-2)+'..';
  163. GetText:=S;
  164. end;
  165. {*****************************************************************************
  166. TCompilerMessageListBox
  167. *****************************************************************************}
  168. function TCompilerMessageListBox.GetPalette: PPalette;
  169. const
  170. P: string[length(CBrowserListBox)] = CBrowserListBox;
  171. begin
  172. GetPalette:=@P;
  173. end;
  174. {*****************************************************************************
  175. TCompilerMessageWindow
  176. *****************************************************************************}
  177. constructor TCompilerMessageWindow.Init;
  178. var R: TRect;
  179. HSB,VSB: PScrollBar;
  180. begin
  181. Desktop^.GetExtent(R);
  182. R.A.Y:=R.B.Y-7;
  183. inherited Init(R,'Compiler Messages',SearchFreeWindowNo);
  184. HelpCtx:=hcMessagesWindow;
  185. HSB:=StandardScrollBar(sbHorizontal+sbHandleKeyboard);
  186. Insert(HSB);
  187. VSB:=StandardScrollBar(sbVertical+sbHandleKeyboard);
  188. Insert(VSB);
  189. GetExtent(R);
  190. R.Grow(-1,-1);
  191. New(MsgLB, Init(R, HSB, VSB));
  192. Insert(MsgLB);
  193. Updateinfo;
  194. CompilerMessageWindow:=@self;
  195. end;
  196. procedure TCompilerMessageWindow.AddMessage(AClass: longint;const Msg, Module: string; Line, Column: longint);
  197. begin
  198. if AClass>=V_Info then
  199. Line:=0;
  200. MsgLB^.AddItem(New(PCompilerMessage,Init(AClass, Msg, MsgLB^.AddModuleName(Module), Line, Column)));
  201. end;
  202. procedure TCompilerMessageWindow.ClearMessages;
  203. begin
  204. MsgLB^.Clear;
  205. ReDraw;
  206. end;
  207. procedure TCompilerMessageWindow.Updateinfo;
  208. begin
  209. if CompileShowed then
  210. begin
  211. InfoST^.SetText(
  212. RExpand(' Main file : '#1#$7f+Copy(SmartPath(MainFile),1,39),40)+#2+
  213. 'Total lines : '#1#$7e+IntToStr(Status.CompiledLines)+#2#13+
  214. RExpand(' Target : '#1#$7f+KillTilde(TargetSwitches^.ItemName(TargetSwitches^.GetCurrSel)),40)+#2+
  215. 'Total errors : '#1#$7e+IntToStr(Status.ErrorCount)
  216. );
  217. if status.currentline>0 then
  218. CurrST^.SetText(' Status: '#1#$7e+status.currentsource+'('+IntToStr(status.currentline)+')'#2)
  219. else
  220. CurrST^.SetText(' Status: '#1#$7e+status.currentsource+#2);
  221. end;
  222. ReDraw;
  223. end;
  224. procedure TCompilerMessageWindow.SetCompileMode(Amode:TCompileMode);
  225. begin
  226. mode:=Amode;
  227. end;
  228. procedure TCompilerMessageWindow.SetCompileShow(b:boolean);
  229. var
  230. r : TRect;
  231. c : word;
  232. begin
  233. r.a:=Origin;
  234. r.b:=Size;
  235. if b then
  236. begin
  237. if CompileShowed then
  238. exit;
  239. dec(r.a.y,4);
  240. inc(r.b.x,r.a.x);
  241. inc(r.b.y,r.a.y+4);
  242. ChangeBounds(r);
  243. { shrink msg listbox }
  244. GetExtent(R);
  245. R.Grow(-1,-1);
  246. dec(R.b.y,5);
  247. MsgLB^.ChangeBounds(r);
  248. { insert line and infost }
  249. C:=((Desktop^.GetColor(32+6) and $f0) or White)*256+Desktop^.GetColor(32+6);
  250. GetExtent(R);
  251. R.Grow(-1,-1);
  252. inc(R.a.y,5);
  253. r.b.y:=r.a.y+1;
  254. New(LineST, Init(R, CharStr('Ä', MaxViewWidth)));
  255. LineST^.GrowMode:=gfGrowHiX;
  256. Insert(LineST);
  257. inc(r.a.x);
  258. dec(r.b.x);
  259. inc(r.a.y);
  260. r.b.y:=r.a.y+2;
  261. New(InfoST, Init(R,'', C));
  262. InfoST^.GrowMode:=gfGrowHiX;
  263. InfoST^.DontWrap:=true;
  264. Insert(InfoST);
  265. inc(r.a.y,2);
  266. r.b.y:=r.a.y+1;
  267. New(CurrST, Init(R,'', C));
  268. CurrST^.GrowMode:=gfGrowHiX;
  269. Insert(CurrST);
  270. end
  271. else
  272. begin
  273. if not CompileShowed then
  274. exit;
  275. inc(r.a.y,4);
  276. inc(r.b.x,r.a.x);
  277. inc(r.b.y,r.a.y-4);
  278. ChangeBounds(r);
  279. { remove infost and line }
  280. Dispose(CurrSt,Done);
  281. CurrSt:=nil;
  282. Dispose(InfoSt,Done);
  283. InfoSt:=nil;
  284. Dispose(LineSt,Done);
  285. LineSt:=nil;
  286. end;
  287. CompileShowed:=b;
  288. { update all windows }
  289. Message(Application,evCommand,cmUpdate,nil);
  290. end;
  291. procedure TCompilerMessageWindow.StartCompilation;
  292. begin
  293. SetCompileShow(true);
  294. Updateinfo;
  295. end;
  296. function TCompilerMessageWindow.EndCompilation:boolean;
  297. var
  298. doevent,
  299. closewin : boolean;
  300. E : TEvent;
  301. begin
  302. { be sure that we have the latest info displayed, fake the currentsource
  303. and currentline to display the result }
  304. status.currentline:=0;
  305. if status.errorcount=0 then
  306. status.currentsource:='Compilation Succesfull'
  307. else
  308. status.currentsource:='Compilation Failed';
  309. Updateinfo;
  310. doevent:=false;
  311. closewin:=(status.errorcount=0);
  312. if (status.errorcount>0) or (Mode<>cRun) then
  313. begin
  314. repeat
  315. GetEvent(E);
  316. case E.what of
  317. evKeyDown :
  318. begin
  319. { only exit when not navigating trough the errors }
  320. case E.Keycode of
  321. kbEsc :
  322. begin
  323. closewin:=true;
  324. break;
  325. end;
  326. kbSpaceBar :
  327. begin
  328. closewin:=false;
  329. doevent:=true;
  330. break;
  331. end;
  332. kbUp,
  333. kbDown,
  334. kbPgUp,
  335. kbPgDn,
  336. kbHome,
  337. kbEnd : ;
  338. else
  339. break;
  340. end;
  341. end;
  342. evCommand :
  343. begin
  344. case E.command of
  345. cmQuit,
  346. cmClose,
  347. cmMsgGotoSource,
  348. cmMsgTrackSource :
  349. begin
  350. closewin:=false;
  351. doevent:=true;
  352. break;
  353. end;
  354. end;
  355. end;
  356. end;
  357. HandleEvent(E);
  358. until false;
  359. SetCompileShow(false);
  360. { Handle the Source tracking after the window has shrunk }
  361. if doevent then
  362. HandleEvent(E);
  363. end;
  364. EndCompilation:=closewin;
  365. end;
  366. procedure TCompilerMessageWindow.HandleEvent(var Event: TEvent);
  367. begin
  368. case Event.What of
  369. evBroadcast :
  370. case Event.Command of
  371. cmListFocusChanged :
  372. if Event.InfoPtr=MsgLB then
  373. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  374. end;
  375. end;
  376. inherited HandleEvent(Event);
  377. end;
  378. procedure TCompilerMessageWindow.Close;
  379. begin
  380. Hide;
  381. end;
  382. procedure TCompilerMessageWindow.Zoom;
  383. begin
  384. SetCompileShow(false);
  385. inherited Zoom;
  386. end;
  387. function TCompilerMessageWindow.GetPalette: PPalette;
  388. const
  389. S : string[length(CBrowserWindow)] = CBrowserWindow;
  390. begin
  391. GetPalette:=@S;
  392. end;
  393. constructor TCompilerMessageWindow.Load(var S: TStream);
  394. begin
  395. inherited Load(S);
  396. S.Read(CompileShowed,SizeOf(CompileShowed));
  397. S.Read(Mode,SizeOf(Mode));
  398. GetSubViewPtr(S,MsgLB);
  399. GetSubViewPtr(S,CurrST);
  400. GetSubViewPtr(S,InfoST);
  401. GetSubViewPtr(S,LineST);
  402. UpdateInfo;
  403. end;
  404. procedure TCompilerMessageWindow.Store(var S: TStream);
  405. begin
  406. if MsgLB^.List=nil then
  407. MsgLB^.NewList(New(PCollection, Init(100,100)));
  408. inherited Store(S);
  409. S.Write(CompileShowed,SizeOf(CompileShowed));
  410. S.Write(Mode,SizeOf(Mode));
  411. PutSubViewPtr(S,MsgLB);
  412. PutSubViewPtr(S,CurrST);
  413. PutSubViewPtr(S,InfoST);
  414. PutSubViewPtr(S,LineST);
  415. end;
  416. destructor TCompilerMessageWindow.Done;
  417. begin
  418. SetCompileShow(false);
  419. CompilerMessageWindow:=nil;
  420. inherited Done;
  421. end;
  422. {****************************************************************************
  423. Compiler Hooks
  424. ****************************************************************************}
  425. function CompilerStatus: boolean; {$ifndef FPC}far;{$endif}
  426. begin
  427. { only display every 50 lines }
  428. if (status.currentline mod 50=0) then
  429. { ^^^ I don't think this is a good idea, since it could eventually
  430. come that we don't have a line number for seconds which is a multiple
  431. of 50... What was the problem with the GetDosTicks() solution? - BG }
  432. begin
  433. { update info messages }
  434. if assigned(CompilerMessageWindow) then
  435. CompilerMessageWindow^.updateinfo;
  436. { update memory usage }
  437. HeapView^.Update;
  438. end;
  439. CompilerStatus:=false;
  440. end;
  441. procedure CompilerStop; {$ifndef FPC}far;{$endif}
  442. begin
  443. end;
  444. function CompilerComment(Level:Longint; const s:string):boolean; {$ifndef FPC}far;{$endif}
  445. begin
  446. {$ifdef TEMPHEAP}
  447. switch_to_base_heap;
  448. {$endif TEMPHEAP}
  449. CompilerComment:=false;
  450. {$ifndef DEV}
  451. if (status.verbosity and Level)=Level then
  452. {$endif}
  453. begin
  454. CompilerMessageWindow^.AddMessage(Level,S,status.currentsourcepath+status.currentsource,
  455. status.currentline,status.currentcolumn);
  456. end;
  457. {$ifdef TEMPHEAP}
  458. switch_to_temp_heap;
  459. {$endif TEMPHEAP}
  460. end;
  461. {****************************************************************************
  462. DoCompile
  463. ****************************************************************************}
  464. function GetExePath: string;
  465. var Path: string;
  466. I: Sw_integer;
  467. begin
  468. Path:='.'+DirSep;
  469. if DirectorySwitches<>nil then
  470. with DirectorySwitches^ do
  471. for I:=0 to ItemCount-1 do
  472. begin
  473. if Pos('EXE',KillTilde(ItemName(I)))>0 then
  474. begin Path:=GetStringItem(I); Break; end;
  475. end;
  476. GetExePath:=CompleteDir(FExpand(Path));
  477. end;
  478. procedure DoCompile(Mode: TCompileMode);
  479. var
  480. P: PSourceWindow;
  481. FileName: string;
  482. begin
  483. { Get FileName }
  484. P:=Message(Desktop,evBroadcast,cmSearchWindow,nil);
  485. if (PrimaryFileMain='') and (P=nil) then
  486. begin
  487. ErrorBox('Oooops, nothing to compile.',nil);
  488. Exit;
  489. end;
  490. if PrimaryFileMain<>'' then
  491. FileName:=PrimaryFileMain
  492. else
  493. begin
  494. if P^.Editor^.Modified and (not P^.Editor^.Save) then
  495. begin
  496. ErrorBox('Can''t compile unsaved file.',nil);
  497. Exit;
  498. end;
  499. FileName:=P^.Editor^.FileName;
  500. end;
  501. WriteSwitches(SwitchesPath);
  502. MainFile:=FixFileName(FExpand(FileName));
  503. If GetEXEPath<>'' then
  504. EXEFile:=FixFileName(GetEXEPath+NameOf(MainFile)+ExeExt)
  505. else
  506. EXEFile:=DirOf(MainFile)+NameOf(MainFile)+ExeExt;
  507. { Reset }
  508. CtrlBreakHit:=false;
  509. { Show Compiler Info }
  510. if not CompilerMessageWindow^.GetState(sfVisible) then
  511. CompilerMessageWindow^.Show;
  512. CompilerMessageWindow^.MakeFirst;
  513. CompilerMessageWindow^.ClearMessages;
  514. CompilerMessageWindow^.SetCompileMode(Mode);
  515. CompilerMessageWindow^.StartCompilation;
  516. { hook compiler output }
  517. do_status:=CompilerStatus;
  518. do_stop:=CompilerStop;
  519. do_comment:=CompilerComment;
  520. {$ifdef redircompiler}
  521. ChangeRedirOut('fp$$$.out',false);
  522. ChangeRedirError('fp$$$.err',false);
  523. {$endif}
  524. {$ifdef TEMPHEAP}
  525. split_heap;
  526. switch_to_temp_heap;
  527. {$endif TEMPHEAP}
  528. Compile(FileName);
  529. {$ifdef TEMPHEAP}
  530. switch_to_base_heap;
  531. {$endif TEMPHEAP}
  532. {$ifdef redircompiler}
  533. RestoreRedirOut;
  534. RestoreRedirError;
  535. {$endif}
  536. { endcompilation returns true if the messagewindow should be removed }
  537. if CompilerMessageWindow^.EndCompilation then
  538. CompilerMessageWindow^.Hide;
  539. Message(Application,evCommand,cmUpdate,nil);
  540. {$ifdef TEMPHEAP}
  541. releasetempheap;
  542. unsplit_heap;
  543. {$endif TEMPHEAP}
  544. end;
  545. {$else OLDCOMP}
  546. constructor TCompileStatusDialog.Init;
  547. var R: TRect;
  548. begin
  549. R.Assign(0,0,50,11+7);
  550. inherited Init(R, 'Compiling');
  551. GetExtent(R); R.B.Y:=11;
  552. R.Grow(-3,-2);
  553. New(ST, Init(R, ''));
  554. Insert(ST);
  555. GetExtent(R); R.B.Y:=11;
  556. R.Grow(-1,-1); R.A.Y:=R.B.Y-1;
  557. New(KeyST, Init(R, '', Blue*16+White+longint($80+Blue*16+White)*256));
  558. Insert(KeyST);
  559. GetExtent(R); R.Grow(-1,-1); R.A.Y:=10;
  560. New(MsgLB, Init(R, nil, nil));
  561. Insert(MsgLB);
  562. end;
  563. procedure TCompileStatusDialog.Update;
  564. var StatusS,KeyS: string;
  565. const CtrlBS = 'Press Ctrl+Break to cancel';
  566. SuccessS = 'Compile successful: ~Press Enter~';
  567. FailS = 'Compile failed';
  568. begin
  569. {$ifdef TEMPHEAP}
  570. switch_to_base_heap;
  571. {$endif TEMPHEAP}
  572. case CompilationPhase of
  573. cpCompiling :
  574. begin
  575. StatusS:='Compiling '+Status.CurrentSource;
  576. KeyS:=CtrlBS;
  577. end;
  578. cpLinking :
  579. begin
  580. StatusS:='Linking...';
  581. KeyS:=CtrlBS;
  582. end;
  583. cpDone :
  584. begin
  585. StatusS:='Done.';
  586. KeyS:=SuccessS;
  587. end;
  588. cpFailed :
  589. begin
  590. StatusS:='Failed to compile...';
  591. KeyS:=FailS;
  592. end;
  593. end;
  594. ST^.SetText(
  595. 'Main file: '+SmartPath(MainFile)+#13+
  596. StatusS+#13#13+
  597. 'Target: '+LExpand(KillTilde(TargetSwitches^.ItemName(TargetSwitches^.GetCurrSel)),12)+' '+
  598. 'Line number: '+IntToStrL(Status.CurrentLine,7)+#13+
  599. 'Free memory: '+IntToStrL(MemAvail div 1024,6)+'K'+ ' '+
  600. 'Total lines: '+IntToStrL(Status.CompiledLines,7)+#13+
  601. 'Total errors: '+IntToStrL(Status.ErrorCount,5)
  602. );
  603. KeyST^.SetText(^C+KeyS);
  604. {$ifdef TEMPHEAP}
  605. switch_to_temp_heap;
  606. {$endif TEMPHEAP}
  607. end;
  608. {****************************************************************************
  609. Compiler Hooks
  610. ****************************************************************************}
  611. function CompilerStatus: boolean; {$ifndef FPC}far;{$endif}
  612. var TT: longint;
  613. begin
  614. TT:=GetDosTicks;
  615. if abs(TT-LastStatusUpdate)>=round(CompilerStatusUpdateDelay*18.2) then
  616. begin
  617. LastStatusUpdate:=TT;
  618. if SD<>nil then SD^.Update;
  619. end;
  620. CompilerStatus:=false;
  621. end;
  622. procedure CompilerStop; {$ifndef FPC}far;{$endif}
  623. begin
  624. end;
  625. function CompilerComment(Level:Longint; const s:string):boolean; {$ifndef FPC}far;{$endif}
  626. begin
  627. {$ifdef TEMPHEAP}
  628. switch_to_base_heap;
  629. {$endif TEMPHEAP}
  630. CompilerComment:=false;
  631. {$ifndef DEV}
  632. if (status.verbosity and Level)=Level then
  633. {$endif}
  634. begin
  635. ProgramInfoWindow^.AddMessage(Level,S,status.currentsourcepath+status.currentsource,
  636. status.currentline,status.currentcolumn);
  637. if SD<>nil then
  638. SD^.MsgLB^.AddItem(
  639. New(PMessageItem, Init(Level, S, SD^.MsgLB^.AddModuleName(SmartPath(status.currentmodule)),
  640. status.currentline,status.currentcolumn)));
  641. end;
  642. {$ifdef TEMPHEAP}
  643. switch_to_temp_heap;
  644. {$endif TEMPHEAP}
  645. end;
  646. {****************************************************************************
  647. DoCompile
  648. ****************************************************************************}
  649. function GetExePath: string;
  650. var Path: string;
  651. I: integer;
  652. begin
  653. Path:='.'+DirSep;
  654. if DirectorySwitches<>nil then
  655. with DirectorySwitches^ do
  656. for I:=0 to ItemCount-1 do
  657. begin
  658. if Pos('EXE',KillTilde(ItemName(I)))>0 then
  659. begin Path:=GetStringItem(I); Break; end;
  660. end;
  661. GetExePath:=CompleteDir(FExpand(Path));
  662. end;
  663. procedure DoCompile(Mode: TCompileMode);
  664. function IsExitEvent(E: TEvent): boolean;
  665. begin
  666. IsExitEvent:=(E.What=evKeyDown) and
  667. ((E.KeyCode=kbEnter) or (E.KeyCode=kbEsc)) or
  668. ((E.What=evCommand) and (E.command=cmClose));
  669. end;
  670. var
  671. P: PSourceWindow;
  672. FileName: string;
  673. E: TEvent;
  674. { WasVisible: boolean;}
  675. begin
  676. { Get FileName }
  677. P:=Message(Desktop,evBroadcast,cmSearchWindow,nil);
  678. if (PrimaryFileMain='') and (P=nil) then
  679. begin
  680. ErrorBox('Oooops, nothing to compile.',nil);
  681. Exit;
  682. end;
  683. if PrimaryFileMain<>'' then
  684. FileName:=PrimaryFileMain
  685. else
  686. begin
  687. if P^.Editor^.Modified and (not P^.Editor^.Save) then
  688. begin
  689. ErrorBox('Can''t compile unsaved file.',nil);
  690. Exit;
  691. end;
  692. FileName:=P^.Editor^.FileName;
  693. end;
  694. WriteSwitches(SwitchesPath);
  695. MainFile:=FixFileName(FExpand(FileName));
  696. If GetEXEPath<>'' then
  697. EXEFile:=FixFileName(GetEXEPath+NameOf(MainFile)+ExeExt)
  698. else
  699. EXEFile:=DirOf(MainFile)+NameOf(MainFile)+ExeExt;
  700. { Reset }
  701. CtrlBreakHit:=false;
  702. { Show Program Info }
  703. { WasVisible:=ProgramInfoWindow^.GetState(sfVisible);
  704. ProgramInfoWindow^.LogLB^.Clear;
  705. if WasVisible=false then
  706. ProgramInfoWindow^.Show;
  707. ProgramInfoWindow^.MakeFirst;}
  708. if Assigned(ProgramInfoWindow) then
  709. ProgramInfoWindow^.ClearMessages;
  710. CompilationPhase:=cpCompiling;
  711. New(SD, Init);
  712. SD^.SetState(sfModal,true);
  713. Application^.Insert(SD);
  714. SD^.Update;
  715. do_status:=CompilerStatus;
  716. do_stop:=CompilerStop;
  717. do_comment:=CompilerComment;
  718. {$ifdef redircompiler}
  719. ChangeRedirOut('fp$$$.out',false);
  720. ChangeRedirError('fp$$$.err',false);
  721. {$endif}
  722. {$ifdef TEMPHEAP}
  723. split_heap;
  724. switch_to_temp_heap;
  725. {$endif TEMPHEAP}
  726. Compile(FileName);
  727. {$ifdef TEMPHEAP}
  728. switch_to_base_heap;
  729. {$endif TEMPHEAP}
  730. {$ifdef redircompiler}
  731. RestoreRedirOut;
  732. RestoreRedirError;
  733. {$endif}
  734. if status.errorCount=0
  735. then CompilationPhase:=cpDone
  736. else CompilationPhase:=cpFailed;
  737. SD^.Update;
  738. SD^.SetState(sfModal,false);
  739. if ((CompilationPhase in[cpDone,cpFailed]) or (ShowStatusOnError)) and (Mode<>cRun) then
  740. repeat
  741. SD^.GetEvent(E);
  742. if IsExitEvent(E)=false then
  743. SD^.HandleEvent(E);
  744. until IsExitEvent(E);
  745. Application^.Delete(SD);
  746. Dispose(SD, Done); SD:=nil;
  747. { if (WasVisible=false) and (status.errorcount=0) then
  748. ProgramInfoWindow^.Hide;}
  749. Message(Application,evCommand,cmUpdate,nil);
  750. {$ifdef TEMPHEAP}
  751. releasetempheap;
  752. unsplit_heap;
  753. {$endif TEMPHEAP}
  754. end;
  755. {$endif}
  756. procedure RegisterFPCompile;
  757. begin
  758. {$ifndef OLDCOMP}
  759. RegisterType(RCompilerMessageListBox);
  760. RegisterType(RCompilerMessageWindow);
  761. {$else}
  762. {$endif}
  763. end;
  764. end.
  765. {
  766. $Log$
  767. Revision 1.23 1999-04-07 21:55:43 peter
  768. + object support for browser
  769. * html help fixes
  770. * more desktop saving things
  771. * NODEBUG directive to exclude debugger
  772. Revision 1.22 1999/04/01 10:27:07 pierre
  773. + file(line) in start of message added
  774. Revision 1.21 1999/04/01 10:15:17 pierre
  775. * CurrSt,InfoSt and LineSt were not disposed correctly in done
  776. * TComiplerMessage destructor first calls SetCompileShow(false)
  777. to get proper cleaning up
  778. Revision 1.20 1999/03/23 16:16:38 peter
  779. * linux fixes
  780. Revision 1.19 1999/03/19 16:04:27 peter
  781. * new compiler dialog
  782. Revision 1.18 1999/03/16 12:38:07 peter
  783. * tools macro fixes
  784. + tph writer
  785. + first things for resource files
  786. Revision 1.17 1999/03/12 01:13:56 peter
  787. * flag if trytoopen should look for other extensions
  788. + browser tab in the tools-compiler
  789. Revision 1.16 1999/03/07 23:00:47 pierre
  790. * Fix for path of executable
  791. Revision 1.15 1999/03/01 15:41:50 peter
  792. + Added dummy entries for functions not yet implemented
  793. * MenuBar didn't update itself automatically on command-set changes
  794. * Fixed Debugging/Profiling options dialog
  795. * TCodeEditor converts spaces to tabs at save only if efUseTabChars is
  796. set
  797. * efBackSpaceUnindents works correctly
  798. + 'Messages' window implemented
  799. + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
  800. + Added TP message-filter support (for ex. you can call GREP thru
  801. GREP2MSG and view the result in the messages window - just like in TP)
  802. * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
  803. so topic search didn't work...
  804. * In FPHELP.PAS there were still context-variables defined as word instead
  805. of THelpCtx
  806. * StdStatusKeys() was missing from the statusdef for help windows
  807. + Topic-title for index-table can be specified when adding a HTML-files
  808. Revision 1.14 1999/02/22 12:46:56 peter
  809. * small fixes for linux and grep
  810. Revision 1.13 1999/02/22 11:51:33 peter
  811. * browser updates from gabor
  812. Revision 1.12 1999/02/22 11:29:36 pierre
  813. + added col info in MessageItem
  814. + grep uses HighLightExts and should work for linux
  815. Revision 1.11 1999/02/08 09:31:00 florian
  816. + some split heap stuff, in $ifdef TEMPHEAP
  817. Revision 1.10 1999/02/05 13:51:39 peter
  818. * unit name of FPSwitches -> FPSwitch which is easier to use
  819. * some fixes for tp7 compiling
  820. Revision 1.9 1999/02/05 13:06:28 pierre
  821. * allow cmClose for Compilation Dialog box
  822. Revision 1.8 1999/02/04 13:32:01 pierre
  823. * Several things added (I cannot commit them independently !)
  824. + added TBreakpoint and TBreakpointCollection
  825. + added cmResetDebugger,cmGrep,CmToggleBreakpoint
  826. + Breakpoint list in INIFile
  827. * Select items now also depend of SwitchMode
  828. * Reading of option '-g' was not possible !
  829. + added search for -Fu args pathes in TryToOpen
  830. + added code for automatic opening of FileDialog
  831. if source not found
  832. Revision 1.7 1999/01/21 11:54:11 peter
  833. + tools menu
  834. + speedsearch in symbolbrowser
  835. * working run command
  836. Revision 1.6 1999/01/15 16:12:43 peter
  837. * fixed crash after compile
  838. Revision 1.5 1999/01/14 21:42:19 peter
  839. * source tracking from Gabor
  840. Revision 1.4 1999/01/12 14:29:32 peter
  841. + Implemented still missing 'switch' entries in Options menu
  842. + Pressing Ctrl-B sets ASCII mode in editor, after which keypresses (even
  843. ones with ASCII < 32 ; entered with Alt+<###>) are interpreted always as
  844. ASCII chars and inserted directly in the text.
  845. + Added symbol browser
  846. * splitted fp.pas to fpide.pas
  847. Revision 1.3 1999/01/04 11:49:42 peter
  848. * 'Use tab characters' now works correctly
  849. + Syntax highlight now acts on File|Save As...
  850. + Added a new class to syntax highlight: 'hex numbers'.
  851. * There was something very wrong with the palette managment. Now fixed.
  852. + Added output directory (-FE<xxx>) support to 'Directories' dialog...
  853. * Fixed some possible bugs in Running/Compiling, and the compilation/run
  854. process revised
  855. Revision 1.2 1998/12/28 15:47:42 peter
  856. + Added user screen support, display & window
  857. + Implemented Editor,Mouse Options dialog
  858. + Added location of .INI and .CFG file
  859. + Option (INI) file managment implemented (see bottom of Options Menu)
  860. + Switches updated
  861. + Run program
  862. Revision 1.3 1998/12/22 10:39:40 peter
  863. + options are now written/read
  864. + find and replace routines
  865. }