fpcompil.pas 38 KB

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