fpmrun.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. Run menu entries
  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. {$define MODIFIEDINDEBUG}
  13. function TIDEApp.AskRecompileIfModified:boolean;
  14. var
  15. PW,PPW : PSourceWindow;
  16. Checkmodifiededitor : boolean;
  17. begin
  18. AskRecompileIfModified:=false;
  19. {$ifdef MODIFIEDINDEBUG}
  20. if not AskRecompileIfModifiedFlag then
  21. exit;
  22. Checkmodifiededitor:=false;
  23. PW:=FirstEditorWindow;
  24. PPW:=PW;
  25. while assigned(PW) do
  26. begin
  27. If PW^.HelpCtx=hcSourceWindow then
  28. begin
  29. if pw^.editor^.getmodified then
  30. if pw^.editor^.core^.getmodifytime > LastCompileTime then
  31. begin
  32. Checkmodifiededitor:=true;
  33. break;
  34. end;
  35. end;
  36. PW:=PSourceWindow(PW^.next);
  37. While assigned(PW) and (PW<>PPW) and (PW^.HelpCtx<>hcSourceWindow) do
  38. PW:=PSourceWindow(PW^.next);
  39. If PW=PPW then
  40. break;
  41. end;
  42. if Checkmodifiededitor then
  43. begin
  44. if (MessageBox(#3+'You''ve edited a file, recompile the project?',nil,mfinformation+mfyesbutton+mfnobutton)=cmYes) then
  45. begin
  46. {$IFNDEF NODEBUG}
  47. if Assigned(Debugger) then
  48. begin
  49. if Debugger^.IsRunning then
  50. RestartingDebugger:=true;
  51. end;
  52. DoResetDebugger;
  53. {$ENDIF}
  54. DoRun;
  55. AskRecompileIfModified:=true;
  56. end
  57. else
  58. AskRecompileIfModifiedFlag:=false;
  59. end;
  60. {$endif MODIFIEDINDEBUG}
  61. end;
  62. procedure TIDEApp.DoStepOver;
  63. begin
  64. {$ifndef NODEBUG}
  65. if not assigned(Debugger) or Not Debugger^.HasExe then
  66. begin
  67. InitDebugger;
  68. if not assigned(Debugger) then
  69. begin
  70. NoDebugger;
  71. exit;
  72. end;
  73. end;
  74. if not Debugger^.IsRunning then
  75. Debugger^.StartTrace
  76. else
  77. begin
  78. if AskRecompileIfModified then
  79. exit;
  80. if InDisassemblyWindow then
  81. Debugger^.TraceNextI
  82. else
  83. Debugger^.TraceNext;
  84. end;
  85. {While (Debugger^.InvalidSourceLine and
  86. Debugger^.IsRunning and
  87. not Debugger^.error) do
  88. begin
  89. Inc(Debugger^.HiddenStepsCount);
  90. if InDisassemblyWindow then
  91. Debugger^.TraceNextI
  92. else
  93. Debugger^.TraceNext;
  94. end;}
  95. Debugger^.AnnotateError;
  96. {$else NODEBUG}
  97. NoDebugger;
  98. {$endif NODEBUG}
  99. end;
  100. procedure TIDEApp.DoTraceInto;
  101. begin
  102. {$ifndef NODEBUG}
  103. if not assigned(Debugger) or Not Debugger^.HasExe then
  104. begin
  105. InitDebugger;
  106. if not assigned(Debugger) then
  107. begin
  108. NoDebugger;
  109. exit;
  110. end;
  111. end;
  112. if not debugger^.IsRunning then
  113. Debugger^.StartTrace
  114. else
  115. begin
  116. if AskRecompileIfModified then
  117. exit;
  118. if InDisassemblyWindow then
  119. Debugger^.TraceStepI
  120. else
  121. Debugger^.TraceStep;
  122. end;
  123. { I think we should not try to go deeper !
  124. if the source is not found PM }
  125. { in disassembly windows we should FK }
  126. if not(InDisassemblyWindow) then
  127. begin
  128. While (Debugger^.InvalidSourceLine and
  129. Debugger^.IsRunning and
  130. not Debugger^.error) do
  131. begin
  132. Inc(Debugger^.HiddenStepsCount);
  133. Debugger^.TraceNext;
  134. end;
  135. end;
  136. Debugger^.AnnotateError;
  137. {$else NODEBUG}
  138. NoDebugger;
  139. {$endif NODEBUG}
  140. end;
  141. procedure TIDEApp.DoContUntilReturn;
  142. begin
  143. {$ifndef NODEBUG}
  144. if not assigned(Debugger) or Not Debugger^.HasExe then
  145. begin
  146. InitDebugger;
  147. if not assigned(Debugger) then
  148. begin
  149. NoDebugger;
  150. exit;
  151. end;
  152. end;
  153. if not debugger^.IsRunning then
  154. Debugger^.Run
  155. else
  156. begin
  157. if AskRecompileIfModified then
  158. exit;
  159. Debugger^.UntilReturn;
  160. end;
  161. Debugger^.AnnotateError;
  162. {$else NODEBUG}
  163. NoDebugger;
  164. {$endif NODEBUG}
  165. end;
  166. procedure TIDEApp.DoRun;
  167. var
  168. RunDirect : boolean;
  169. oldcurrdir : string;
  170. begin
  171. {$ifndef NODEBUG}
  172. if not assigned(Debugger) or not Debugger^.HasExe or not Debugger^.IsRunning then
  173. {$endif}
  174. begin
  175. if (not ExistsFile(ExeFile)) or (CompilationPhase<>cpDone) or
  176. NeedRecompile(cRun,false) then
  177. begin
  178. DoCompile(cRun);
  179. if CompilationPhase<>cpDone then
  180. Exit;
  181. if not Status.IsExe then
  182. begin
  183. ErrorBox(msg_cannotrununit,nil);
  184. Exit;
  185. end;
  186. if IsLibrary then
  187. begin
  188. ErrorBox(msg_cannotrunlibrary,nil);
  189. Exit;
  190. end;
  191. end;
  192. if (EXEFile='') then
  193. begin
  194. ErrorBox(msg_nothingtorun,nil);
  195. Exit;
  196. end;
  197. if not ExistsFile(ExeFile) then
  198. begin
  199. MsgParms[1].Ptr:=@EXEFile;
  200. ErrorBox(msg_invalidfilename,@MsgParms);
  201. Exit;
  202. end;
  203. RunDirect:=true;
  204. {$ifndef NODEBUG}
  205. { we use debugger if and only if there are active breakpoints
  206. AND the target is correct for debugging !! PM }
  207. if (ActiveBreakpoints or RestartingDebugger) and
  208. (target_info.shortname=source_info.shortname)
  209. then
  210. begin
  211. if not assigned(Debugger) or Not Debugger^.HasExe then
  212. InitDebugger;
  213. if assigned(Debugger) then
  214. begin
  215. if RestartingDebugger then
  216. begin
  217. RestartingDebugger:=false;
  218. Debugger^.StartTrace;
  219. end
  220. else
  221. Debugger^.Run;
  222. RunDirect:=false;
  223. end;
  224. end;
  225. {$endif ndef NODEBUG}
  226. if Not RunDirect then
  227. exit;
  228. {$I-}
  229. GetDir(0,oldcurrdir);
  230. chdir(GetRunDir);
  231. {$I+}
  232. EatIO;
  233. {$ifdef Unix}
  234. if (DebuggeeTTY<>'') then
  235. DoExecute(ExeFile,GetRunParameters,DebuggeeTTY,DebuggeeTTY,DebuggeeTTY,exNormal)
  236. else
  237. {$endif Unix}
  238. DoExecute(ExeFile,GetRunParameters,'','','',exNormal);
  239. {$I-}
  240. chdir(oldcurrdir);
  241. {$I+}
  242. EatIO;
  243. { In case we have something that the compiler touched }
  244. AskToReloadAllModifiedFiles;
  245. LastExitCode:=ExecuteResult;
  246. If IOStatus<>0 then
  247. begin
  248. MsgParms[1].Ptr:=@EXEFile;
  249. MsgParms[2].long:=IOStatus;
  250. InformationBox(msg_programnotrundoserroris,@MsgParms);
  251. end
  252. else If LastExitCode<>0 then
  253. begin
  254. MsgParms[1].Ptr:=@EXEFile;
  255. MsgParms[2].long:=LastExitCode;
  256. InformationBox(msg_programfileexitedwithexitcode,@MsgParms);
  257. end;
  258. end
  259. {$ifndef NODEBUG}
  260. else
  261. Debugger^.Continue
  262. {$endif}
  263. ;
  264. end;
  265. procedure TIDEApp.UpdateRunMenu(DebuggeeRunning : boolean);
  266. var MenuItem : PMenuItem;
  267. begin
  268. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmRun);
  269. if assigned(MenuItem) then
  270. begin
  271. If assigned(MenuItem^.Name) then
  272. DisposeStr(MenuItem^.Name);
  273. if DebuggeeRunning then
  274. MenuItem^.Name:=NewStr(menu_run_continue)
  275. else
  276. MenuItem^.Name:=NewStr(menu_run_run);
  277. end;
  278. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmResetDebugger);
  279. if assigned(MenuItem) then
  280. MenuItem^.Disabled:=not DebuggeeRunning;
  281. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmUntilReturn);
  282. if assigned(MenuItem) then
  283. MenuItem^.Disabled:=not DebuggeeRunning;
  284. end;
  285. procedure TIDEApp.RunDir;
  286. var
  287. s : DirStr;
  288. begin
  289. s:=GetRunDir;
  290. SelectDir(s,hidRunDir);
  291. SetRunDir(s);
  292. end;
  293. procedure TIDEApp.Parameters;
  294. var R,R2: TRect;
  295. D: PCenterDialog;
  296. IL: PEditorInputLine;
  297. begin
  298. R.Assign(0,0,round(ScreenWidth*54/80),4);
  299. New(D, Init(R, dialog_programparameters));
  300. with D^ do
  301. begin
  302. GetExtent(R); R.Grow(-2,-1); Inc(R.A.Y); R.B.Y:=R.A.Y+1;
  303. R2.Copy(R); R2.A.X:=16; Dec(R2.B.X,4);
  304. New(IL, Init(R2, 255));
  305. IL^.Data^:=GetRunParameters;
  306. Insert(IL);
  307. R2.Copy(R); R2.A.X:=R2.B.X-3; R2.B.X:=R2.A.X+3;
  308. Insert(New(PHistory, Init(R2, IL, hidRunParameters)));
  309. R2.Copy(R); R2.B.X:=16;
  310. Insert(New(PLabel, Init(R2, label_parameters_parameter, IL)));
  311. end;
  312. InsertButtons(D);
  313. IL^.Select;
  314. if Desktop^.ExecView(D)=cmOK then
  315. begin
  316. SetRunParameters(IL^.Data^);
  317. end;
  318. Dispose(D, Done);
  319. end;
  320. procedure TIDEApp.DoResetDebugger;
  321. begin
  322. {$ifndef NODEBUG}
  323. if assigned(Debugger) then
  324. DoneDebugger;
  325. UpdateScreen(true);
  326. {$else NODEBUG}
  327. NoDebugger;
  328. {$endif NODEBUG}
  329. end;
  330. procedure TIDEApp.DoContToCursor;
  331. {$ifndef NODEBUG}
  332. var
  333. W : PFPWindow;
  334. PDL : PDisasLine;
  335. S,FileName : string;
  336. P,CurY,LineNr : longint;
  337. {$endif}
  338. begin
  339. {$ifndef NODEBUG}
  340. if (DeskTop^.Current=nil) or
  341. ((TypeOf(DeskTop^.Current^)<>TypeOf(TSourceWindow)) and
  342. (TypeOf(DeskTop^.Current^)<>TypeOf(TDisassemblyWindow))) then
  343. Begin
  344. ErrorBox(msg_impossibletoreachcursor,nil);
  345. Exit;
  346. End;
  347. If not assigned(Debugger) or Not Debugger^.HasExe then
  348. begin
  349. InitDebugger;
  350. if not assigned(Debugger) then
  351. begin
  352. NoDebugger;
  353. exit;
  354. end;
  355. end;
  356. W:=PFPWindow(DeskTop^.Current);
  357. If assigned(W) then
  358. begin
  359. If TypeOf(W^)=TypeOf(TSourceWindow) then
  360. begin
  361. FileName:=PSourceWindow(W)^.Editor^.FileName;
  362. LineNr:=PSourceWindow(W)^.Editor^.CurPos.Y+1;
  363. Debugger^.Command('tbreak '+GDBFileName(NameAndExtOf(FileName))+':'+IntToStr(LineNr));
  364. Debugger^.Continue;
  365. end
  366. else
  367. begin
  368. CurY:=PDisassemblyWindow(W)^.Editor^.CurPos.Y;
  369. if CurY<PDisassemblyWindow(W)^.Editor^.GetLineCount then
  370. PDL:=PDisasLine(PDisassemblyWindow(W)^.Editor^.GetLine(CurY))
  371. else
  372. PDL:=nil;
  373. if assigned(PDL) then
  374. begin
  375. if PDL^.Address<>0 then
  376. begin
  377. Debugger^.Command('tbreak *0x'+IntToHex(PDL^.Address,8));
  378. end
  379. else
  380. begin
  381. S:=PDisassemblyWindow(W)^.Editor^.GetDisplayText(PDisassemblyWindow(W)^.Editor^.CurPos.Y);
  382. p:=pos(':',S);
  383. FileName:=Copy(S,1,p-1);
  384. S:=Copy(S,p+1,high(S));
  385. p:=pos(' ',S);
  386. S:=Copy(S,1,p-1);
  387. LineNr:=StrToInt(S);
  388. Debugger^.Command('tbreak '+GDBFileName(NameAndExtOf(FileName))+':'+IntToStr(LineNr));
  389. end;
  390. Debugger^.Continue;
  391. end;
  392. end;
  393. end;
  394. {$else NODEBUG}
  395. NoDebugger;
  396. {$endif NODEBUG}
  397. end;
  398. procedure TIDEApp.DoOpenGDBWindow;
  399. begin
  400. {$ifndef NODEBUG}
  401. InitGDBWindow;
  402. if not assigned(Debugger) then
  403. begin
  404. new(Debugger,Init);
  405. if assigned(Debugger) then
  406. Debugger^.SetExe(ExeFile);
  407. end;
  408. If assigned(GDBWindow) then
  409. GDBWindow^.MakeFirst;
  410. {$else NODEBUG}
  411. NoDebugger;
  412. {$endif NODEBUG}
  413. end;
  414. procedure TIDEApp.DoToggleBreak;
  415. {$ifndef NODEBUG}
  416. var
  417. W : PSourceWindow;
  418. WD : PDisassemblyWindow;
  419. PDL : PDisasLine;
  420. PB : PBreakpoint;
  421. S,FileName : string;
  422. b : boolean;
  423. CurY,P,LineNr : longint;
  424. {$endif}
  425. begin
  426. {$ifndef NODEBUG}
  427. if (DeskTop^.Current=nil) or
  428. (TypeOf(DeskTop^.Current^)<>TypeOf(TSourceWindow)) and
  429. (TypeOf(DeskTop^.Current^)<>TypeOf(TDisassemblyWindow)) then
  430. Begin
  431. ErrorBox(msg_impossibletosetbreakpoint,nil);
  432. Exit;
  433. End;
  434. if assigned (DeskTop^.Current) and
  435. (TypeOf(DeskTop^.Current^)=TypeOf(TSourceWindow)) then
  436. begin
  437. W:=PSourceWindow(DeskTop^.Current);
  438. FileName:=W^.Editor^.FileName;
  439. If FileName='' then
  440. begin
  441. W^.Editor^.SaveAs;
  442. FileName:=W^.Editor^.FileName;
  443. If FileName='' then
  444. Begin
  445. ErrorBox(msg_impossibletosetbreakpoint,nil);
  446. Exit;
  447. End;
  448. end;
  449. LineNr:=W^.Editor^.CurPos.Y+1;
  450. BreakpointsCollection^.ToggleFileLine(FileName,LineNr);
  451. end
  452. else if assigned (DeskTop^.Current) and
  453. (TypeOf(DeskTop^.Current^)=TypeOf(TDisassemblyWindow)) then
  454. begin
  455. WD:=PDisassemblyWindow(DeskTop^.Current);
  456. CurY:=WD^.Editor^.CurPos.Y;
  457. if CurY<WD^.Editor^.GetLineCount then
  458. PDL:=PDisasLine(WD^.Editor^.GetLine(CurY))
  459. else
  460. PDL:=nil;
  461. if assigned(PDL) then
  462. begin
  463. if PDL^.Address<>0 then
  464. begin
  465. PB:=New(PBreakpoint,init_address(IntToHex(PDL^.Address,8)));
  466. BreakpointsCollection^.Insert(PB);
  467. WD^.Editor^.SetLineFlagState(CurY,lfBreakpoint,true);
  468. end
  469. else
  470. begin
  471. S:=WD^.Editor^.GetDisplayText(WD^.Editor^.CurPos.Y);
  472. p:=pos(':',S);
  473. FileName:=Copy(S,1,p-1);
  474. S:=Copy(S,p+1,high(S));
  475. p:=pos(' ',S);
  476. S:=Copy(S,1,p-1);
  477. LineNr:=StrToInt(S);
  478. b:=BreakpointsCollection^.ToggleFileLine(FileName,LineNr);
  479. WD^.Editor^.SetLineFlagState(CurY,lfBreakpoint,b);
  480. end;
  481. end;
  482. end;
  483. {$else NODEBUG}
  484. NoDebugger;
  485. {$endif NODEBUG}
  486. end;
  487. {
  488. $Log$
  489. Revision 1.10 2005-01-07 21:52:23 florian
  490. * proper stepping in disassembler window now possible
  491. + disassembler window to menu added
  492. Revision 1.9 2004/11/08 20:28:26 peter
  493. * Breakpoints are now deleted when removed from source, disabling is
  494. still possible from the breakpoint list
  495. * COMPILER_1_0, FVISION, GABOR defines removed, only support new
  496. FV and 1.9.x compilers
  497. * Run directory added to Run menu
  498. * Useless programinfo window removed
  499. Revision 1.8 2002/12/18 01:21:42 pierre
  500. + Use TEditorInputLine instead of TInputLine
  501. Revision 1.7 2002/12/16 09:06:08 pierre
  502. * don't insert breakpoints in unsaved sources
  503. Revision 1.6 2002/10/12 19:43:07 hajny
  504. * missing HasSignal conditionals added (needed for FPC/2)
  505. Revision 1.5 2002/09/07 15:40:44 peter
  506. * old logs removed and tabs fixed
  507. Revision 1.4 2002/09/05 08:45:59 pierre
  508. * try to fix recompilation on changes problems
  509. Revision 1.3 2002/08/13 08:59:12 pierre
  510. + Run menu changes depending on wether the debuggee is running or not
  511. }