fpmrun.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  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. 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'+HexStr(PDL^.Address,sizeof(pointer)*2));
  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(HexStr(PDL^.Address,sizeof(pointer)*2)));
  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;