fpcompil.pas 35 KB

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