fpcompil.pas 37 KB

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