2
0

fpcompil.pas 37 KB

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