fpmrun.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Run menu entries
  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. {$define MODIFIEDINDEBUG}
  12. function TIDEApp.AskRecompileIfModified:boolean;
  13. var
  14. PW,PPW : PSourceWindow;
  15. Checkmodifiededitor : boolean;
  16. begin
  17. AskRecompileIfModified:=false;
  18. {$ifdef MODIFIEDINDEBUG}
  19. if not AskRecompileIfModifiedFlag then
  20. exit;
  21. Checkmodifiededitor:=false;
  22. PW:=FirstEditorWindow;
  23. PPW:=PW;
  24. while assigned(PW) do
  25. begin
  26. If PW^.HelpCtx=hcSourceWindow then
  27. begin
  28. if pw^.editor^.getmodified then
  29. if pw^.editor^.core^.getmodifytime > LastCompileTime then
  30. begin
  31. Checkmodifiededitor:=true;
  32. break;
  33. end;
  34. end;
  35. PW:=PSourceWindow(PW^.next);
  36. While assigned(PW) and (PW<>PPW) and (PW^.HelpCtx<>hcSourceWindow) do
  37. PW:=PSourceWindow(PW^.next);
  38. If PW=PPW then
  39. break;
  40. end;
  41. if Checkmodifiededitor then
  42. begin
  43. if (MessageBox(#3+'You''ve edited a file, recompile the project?',nil,mfinformation+mfyesbutton+mfnobutton)=cmYes) then
  44. begin
  45. {$IFNDEF NODEBUG}
  46. if Assigned(Debugger) then
  47. begin
  48. if Debugger^.IsRunning then
  49. RestartingDebugger:=true;
  50. end;
  51. DoResetDebugger;
  52. {$ENDIF}
  53. DoRun;
  54. AskRecompileIfModified:=true;
  55. end
  56. else
  57. AskRecompileIfModifiedFlag:=false;
  58. end;
  59. {$endif MODIFIEDINDEBUG}
  60. end;
  61. procedure TIDEApp.DoStepOver;
  62. begin
  63. {$ifndef NODEBUG}
  64. if not assigned(Debugger) or Not Debugger^.HasExe then
  65. begin
  66. InitDebugger;
  67. if not assigned(Debugger) then
  68. begin
  69. NoDebugger;
  70. exit;
  71. end;
  72. end;
  73. if not Debugger^.IsRunning then
  74. Debugger^.StartTrace
  75. else
  76. begin
  77. if AskRecompileIfModified then
  78. exit;
  79. if InDisassemblyWindow then
  80. Debugger^.TraceNextI
  81. else
  82. Debugger^.TraceNext;
  83. end;
  84. {While (Debugger^.InvalidSourceLine and
  85. Debugger^.IsRunning and
  86. not Debugger^.error) do
  87. begin
  88. Inc(Debugger^.HiddenStepsCount);
  89. if InDisassemblyWindow then
  90. Debugger^.TraceNextI
  91. else
  92. Debugger^.TraceNext;
  93. end;}
  94. if Debugger^.IsRunning then
  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. s : shortstring;
  171. begin
  172. {$ifndef NODEBUG}
  173. if not assigned(Debugger) or not Debugger^.HasExe or not Debugger^.IsRunning then
  174. {$endif}
  175. begin
  176. if (not ExistsFile(ExeFile)) or (CompilationPhase<>cpDone) or
  177. NeedRecompile(cRun,false) then
  178. begin
  179. DoCompile(cRun);
  180. if CompilationPhase<>cpDone then
  181. Exit;
  182. if not Status.IsExe then
  183. begin
  184. ErrorBox(msg_cannotrununit,nil);
  185. Exit;
  186. end;
  187. if IsLibrary then
  188. begin
  189. ErrorBox(msg_cannotrunlibrary,nil);
  190. Exit;
  191. end;
  192. end;
  193. if (EXEFile='') then
  194. begin
  195. ErrorBox(msg_nothingtorun,nil);
  196. Exit;
  197. end;
  198. s:=EXEFile;
  199. if not ExistsFile(ExeFile) then
  200. begin
  201. MsgParms[1].Ptr:=@s;
  202. ErrorBox(msg_invalidfilename,@MsgParms);
  203. Exit;
  204. end;
  205. RunDirect:=true;
  206. {$ifndef NODEBUG}
  207. { we use debugger if and only if there are active breakpoints
  208. AND the target is correct for debugging !! PM }
  209. if (ActiveBreakpoints or RestartingDebugger) and
  210. (target_info.shortname=source_info.shortname)
  211. then
  212. begin
  213. if not assigned(Debugger) or Not Debugger^.HasExe then
  214. InitDebugger;
  215. if assigned(Debugger) then
  216. begin
  217. if RestartingDebugger then
  218. begin
  219. RestartingDebugger:=false;
  220. Debugger^.StartTrace;
  221. end
  222. else
  223. Debugger^.Run;
  224. RunDirect:=false;
  225. end;
  226. end;
  227. {$endif ndef NODEBUG}
  228. if Not RunDirect then
  229. exit;
  230. {$I-}
  231. GetDir(0,oldcurrdir);
  232. chdir(GetRunDir);
  233. {$I+}
  234. EatIO;
  235. {$ifdef Unix}
  236. if (DebuggeeTTY<>'') then
  237. DoExecute(ExeFile,GetRunParameters,DebuggeeTTY,DebuggeeTTY,DebuggeeTTY,exNormal)
  238. else
  239. {$endif Unix}
  240. DoExecute(ExeFile,GetRunParameters,'','','',exNormal);
  241. {$I-}
  242. chdir(oldcurrdir);
  243. {$I+}
  244. EatIO;
  245. { In case we have something that the compiler touched }
  246. AskToReloadAllModifiedFiles;
  247. LastExitCode:=ExecuteResult;
  248. s:=EXEFile;
  249. If IOStatus<>0 then
  250. begin
  251. MsgParms[1].Ptr:=@s;
  252. MsgParms[2].long:=IOStatus;
  253. InformationBox(msg_programnotrundoserroris,@MsgParms);
  254. end
  255. else If LastExitCode<>0 then
  256. begin
  257. MsgParms[1].Ptr:=@s;
  258. MsgParms[2].long:=LastExitCode;
  259. InformationBox(msg_programfileexitedwithexitcode,@MsgParms);
  260. end;
  261. end
  262. {$ifndef NODEBUG}
  263. else
  264. begin
  265. if AskRecompileIfModified then
  266. exit;
  267. Debugger^.Continue;
  268. end;
  269. {$endif}
  270. ;
  271. end;
  272. procedure TIDEApp.UpdateRunMenu(DebuggeeRunning : boolean);
  273. var MenuItem : PMenuItem;
  274. begin
  275. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmRun);
  276. if not assigned(MenuItem) then
  277. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmContinue);
  278. if assigned(MenuItem) then
  279. begin
  280. If assigned(MenuItem^.Name) then
  281. DisposeStr(MenuItem^.Name);
  282. if DebuggeeRunning then
  283. begin
  284. MenuItem^.Name:=NewStr(menu_run_continue);
  285. MenuItem^.command:=cmContinue;
  286. end
  287. else
  288. begin
  289. MenuItem^.Name:=NewStr(menu_run_run);
  290. MenuItem^.command:=cmRun;
  291. end;
  292. end;
  293. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmResetDebugger);
  294. if assigned(MenuItem) then
  295. MenuItem^.Disabled:=not DebuggeeRunning;
  296. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmUntilReturn);
  297. if assigned(MenuItem) then
  298. MenuItem^.Disabled:=not DebuggeeRunning;
  299. end;
  300. procedure TIDEApp.RunDir;
  301. var
  302. s : DirStr;
  303. begin
  304. s:=GetRunDir;
  305. SelectDir(s,hidRunDir);
  306. SetRunDir(s);
  307. end;
  308. procedure TIDEApp.Parameters;
  309. var R,R2: TRect;
  310. D: PCenterDialog;
  311. IL: PEditorInputLine;
  312. begin
  313. R.Assign(0,0,round(ScreenWidth*54/80),4);
  314. New(D, Init(R, dialog_programparameters));
  315. with D^ do
  316. begin
  317. GetExtent(R); R.Grow(-2,-1); Inc(R.A.Y); R.B.Y:=R.A.Y+1;
  318. R2.Copy(R); R2.A.X:=16; Dec(R2.B.X,4);
  319. New(IL, Init(R2, 255));
  320. IL^.Data^:=GetRunParameters;
  321. Insert(IL);
  322. R2.Copy(R); R2.A.X:=R2.B.X-3; R2.B.X:=R2.A.X+3;
  323. Insert(New(PHistory, Init(R2, IL, hidRunParameters)));
  324. R2.Copy(R); R2.B.X:=16;
  325. Insert(New(PLabel, Init(R2, label_parameters_parameter, IL)));
  326. end;
  327. InsertButtons(D);
  328. IL^.Select;
  329. if Desktop^.ExecView(D)=cmOK then
  330. begin
  331. SetRunParameters(IL^.Data^);
  332. end;
  333. Dispose(D, Done);
  334. end;
  335. procedure TIDEApp.DoResetDebugger;
  336. begin
  337. {$ifndef NODEBUG}
  338. if assigned(Debugger) then
  339. DoneDebugger;
  340. UpdateScreen(true);
  341. {$else NODEBUG}
  342. NoDebugger;
  343. {$endif NODEBUG}
  344. end;
  345. procedure TIDEApp.DoContToCursor;
  346. {$ifndef NODEBUG}
  347. var
  348. W : PFPWindow;
  349. PDL : PDisasLine;
  350. S,FileName : string;
  351. P,CurY,LineNr : longint;
  352. {$endif}
  353. begin
  354. {$ifndef NODEBUG}
  355. if (DeskTop^.Current=nil) or
  356. ((TypeOf(DeskTop^.Current^)<>TypeOf(TSourceWindow)) and
  357. (TypeOf(DeskTop^.Current^)<>TypeOf(TDisassemblyWindow))) then
  358. Begin
  359. ErrorBox(msg_impossibletoreachcursor,nil);
  360. Exit;
  361. End;
  362. If not assigned(Debugger) or Not Debugger^.HasExe then
  363. begin
  364. InitDebugger;
  365. if not assigned(Debugger) then
  366. begin
  367. NoDebugger;
  368. exit;
  369. end;
  370. end;
  371. W:=PFPWindow(DeskTop^.Current);
  372. If assigned(W) then
  373. begin
  374. If TypeOf(W^)=TypeOf(TSourceWindow) then
  375. begin
  376. FileName:=PSourceWindow(W)^.Editor^.FileName;
  377. LineNr:=PSourceWindow(W)^.Editor^.CurPos.Y+1;
  378. Debugger^.SetTbreak(GDBFileName(NameAndExtOf(FileName))+':'+IntToStr(LineNr));
  379. Debugger^.Continue;
  380. end
  381. else
  382. begin
  383. CurY:=PDisassemblyWindow(W)^.Editor^.CurPos.Y;
  384. if CurY<PDisassemblyWindow(W)^.Editor^.GetLineCount then
  385. PDL:=PDisasLine(PDisassemblyWindow(W)^.Editor^.GetLine(CurY))
  386. else
  387. PDL:=nil;
  388. if assigned(PDL) then
  389. begin
  390. if PDL^.Address<>0 then
  391. begin
  392. Debugger^.SetTBreak('*0x'+HexStr(PDL^.Address,sizeof(pointer)*2));
  393. end
  394. else
  395. begin
  396. S:=PDisassemblyWindow(W)^.Editor^.GetDisplayText(PDisassemblyWindow(W)^.Editor^.CurPos.Y);
  397. p:=pos(':',S);
  398. FileName:=Copy(S,1,p-1);
  399. S:=Copy(S,p+1,high(S));
  400. p:=pos(' ',S);
  401. S:=Copy(S,1,p-1);
  402. LineNr:=StrToInt(S);
  403. Debugger^.SetTBreak(GDBFileName(NameAndExtOf(FileName))+':'+IntToStr(LineNr));
  404. end;
  405. Debugger^.Continue;
  406. end;
  407. end;
  408. end;
  409. {$else NODEBUG}
  410. NoDebugger;
  411. {$endif NODEBUG}
  412. end;
  413. procedure TIDEApp.DoOpenGDBWindow;
  414. begin
  415. {$ifndef NODEBUG}
  416. InitGDBWindow;
  417. if not assigned(Debugger) then
  418. begin
  419. new(Debugger,Init);
  420. if assigned(Debugger) then
  421. Debugger^.SetExe(ExeFile);
  422. end;
  423. If assigned(GDBWindow) then
  424. GDBWindow^.MakeFirst;
  425. {$else NODEBUG}
  426. NoDebugger;
  427. {$endif NODEBUG}
  428. end;
  429. procedure TIDEApp.DoToggleBreak;
  430. {$ifndef NODEBUG}
  431. var
  432. W : PSourceWindow;
  433. WD : PDisassemblyWindow;
  434. PDL : PDisasLine;
  435. PB : PBreakpoint;
  436. S,FileName : string;
  437. b : boolean;
  438. CurY,P,LineNr : longint;
  439. {$endif}
  440. begin
  441. {$ifndef NODEBUG}
  442. if (DeskTop^.Current=nil) or
  443. (TypeOf(DeskTop^.Current^)<>TypeOf(TSourceWindow)) and
  444. (TypeOf(DeskTop^.Current^)<>TypeOf(TDisassemblyWindow)) then
  445. Begin
  446. ErrorBox(msg_impossibletosetbreakpoint,nil);
  447. Exit;
  448. End;
  449. if assigned (DeskTop^.Current) and
  450. (TypeOf(DeskTop^.Current^)=TypeOf(TSourceWindow)) then
  451. begin
  452. W:=PSourceWindow(DeskTop^.Current);
  453. FileName:=W^.Editor^.FileName;
  454. If FileName='' then
  455. begin
  456. W^.Editor^.SaveAs;
  457. FileName:=W^.Editor^.FileName;
  458. If FileName='' then
  459. Begin
  460. ErrorBox(msg_impossibletosetbreakpoint,nil);
  461. Exit;
  462. End;
  463. end;
  464. LineNr:=W^.Editor^.CurPos.Y+1;
  465. BreakpointsCollection^.ToggleFileLine(FileName,LineNr);
  466. end
  467. else if assigned (DeskTop^.Current) and
  468. (TypeOf(DeskTop^.Current^)=TypeOf(TDisassemblyWindow)) then
  469. begin
  470. WD:=PDisassemblyWindow(DeskTop^.Current);
  471. CurY:=WD^.Editor^.CurPos.Y;
  472. if CurY<WD^.Editor^.GetLineCount then
  473. PDL:=PDisasLine(WD^.Editor^.GetLine(CurY))
  474. else
  475. PDL:=nil;
  476. if assigned(PDL) then
  477. begin
  478. if PDL^.Address<>0 then
  479. begin
  480. PB:=New(PBreakpoint,init_address(HexStr(PDL^.Address,sizeof(pointer)*2)));
  481. BreakpointsCollection^.Insert(PB);
  482. WD^.Editor^.SetLineFlagState(CurY,lfBreakpoint,true);
  483. end
  484. else
  485. begin
  486. S:=WD^.Editor^.GetDisplayText(WD^.Editor^.CurPos.Y);
  487. p:=pos(':',S);
  488. FileName:=Copy(S,1,p-1);
  489. S:=Copy(S,p+1,high(S));
  490. p:=pos(' ',S);
  491. S:=Copy(S,1,p-1);
  492. LineNr:=StrToInt(S);
  493. b:=BreakpointsCollection^.ToggleFileLine(FileName,LineNr);
  494. WD^.Editor^.SetLineFlagState(CurY,lfBreakpoint,b);
  495. end;
  496. end;
  497. end;
  498. {$else NODEBUG}
  499. NoDebugger;
  500. {$endif NODEBUG}
  501. end;