fpmrun.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  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. Debugger^.AnnotateError;
  95. {$else NODEBUG}
  96. NoDebugger;
  97. {$endif NODEBUG}
  98. end;
  99. procedure TIDEApp.DoTraceInto;
  100. begin
  101. {$ifndef NODEBUG}
  102. if not assigned(Debugger) or Not Debugger^.HasExe then
  103. begin
  104. InitDebugger;
  105. if not assigned(Debugger) then
  106. begin
  107. NoDebugger;
  108. exit;
  109. end;
  110. end;
  111. if not debugger^.IsRunning then
  112. Debugger^.StartTrace
  113. else
  114. begin
  115. if AskRecompileIfModified then
  116. exit;
  117. if InDisassemblyWindow then
  118. Debugger^.TraceStepI
  119. else
  120. Debugger^.TraceStep;
  121. end;
  122. { I think we should not try to go deeper !
  123. if the source is not found PM }
  124. { in disassembly windows we should FK }
  125. if not(InDisassemblyWindow) then
  126. begin
  127. While (Debugger^.InvalidSourceLine and
  128. Debugger^.IsRunning and
  129. not Debugger^.error) do
  130. begin
  131. Inc(Debugger^.HiddenStepsCount);
  132. Debugger^.TraceNext;
  133. end;
  134. end;
  135. Debugger^.AnnotateError;
  136. {$else NODEBUG}
  137. NoDebugger;
  138. {$endif NODEBUG}
  139. end;
  140. procedure TIDEApp.DoContUntilReturn;
  141. begin
  142. {$ifndef NODEBUG}
  143. if not assigned(Debugger) or Not Debugger^.HasExe then
  144. begin
  145. InitDebugger;
  146. if not assigned(Debugger) then
  147. begin
  148. NoDebugger;
  149. exit;
  150. end;
  151. end;
  152. if not debugger^.IsRunning then
  153. Debugger^.Run
  154. else
  155. begin
  156. if AskRecompileIfModified then
  157. exit;
  158. Debugger^.UntilReturn;
  159. end;
  160. Debugger^.AnnotateError;
  161. {$else NODEBUG}
  162. NoDebugger;
  163. {$endif NODEBUG}
  164. end;
  165. procedure TIDEApp.DoRun;
  166. var
  167. RunDirect : boolean;
  168. oldcurrdir : string;
  169. begin
  170. {$ifndef NODEBUG}
  171. if not assigned(Debugger) or not Debugger^.HasExe or not Debugger^.IsRunning then
  172. {$endif}
  173. begin
  174. if (not ExistsFile(ExeFile)) or (CompilationPhase<>cpDone) or
  175. NeedRecompile(cRun,false) then
  176. begin
  177. DoCompile(cRun);
  178. if CompilationPhase<>cpDone then
  179. Exit;
  180. if not Status.IsExe then
  181. begin
  182. ErrorBox(msg_cannotrununit,nil);
  183. Exit;
  184. end;
  185. if IsLibrary then
  186. begin
  187. ErrorBox(msg_cannotrunlibrary,nil);
  188. Exit;
  189. end;
  190. end;
  191. if (EXEFile='') then
  192. begin
  193. ErrorBox(msg_nothingtorun,nil);
  194. Exit;
  195. end;
  196. if not ExistsFile(ExeFile) then
  197. begin
  198. MsgParms[1].Ptr:=@EXEFile;
  199. ErrorBox(msg_invalidfilename,@MsgParms);
  200. Exit;
  201. end;
  202. RunDirect:=true;
  203. {$ifndef NODEBUG}
  204. { we use debugger if and only if there are active breakpoints
  205. AND the target is correct for debugging !! PM }
  206. if (ActiveBreakpoints or RestartingDebugger) and
  207. (target_info.shortname=source_info.shortname)
  208. then
  209. begin
  210. if not assigned(Debugger) or Not Debugger^.HasExe then
  211. InitDebugger;
  212. if assigned(Debugger) then
  213. begin
  214. if RestartingDebugger then
  215. begin
  216. RestartingDebugger:=false;
  217. Debugger^.StartTrace;
  218. end
  219. else
  220. Debugger^.Run;
  221. RunDirect:=false;
  222. end;
  223. end;
  224. {$endif ndef NODEBUG}
  225. if Not RunDirect then
  226. exit;
  227. {$I-}
  228. GetDir(0,oldcurrdir);
  229. chdir(GetRunDir);
  230. {$I+}
  231. EatIO;
  232. {$ifdef Unix}
  233. if (DebuggeeTTY<>'') then
  234. DoExecute(ExeFile,GetRunParameters,DebuggeeTTY,DebuggeeTTY,DebuggeeTTY,exNormal)
  235. else
  236. {$endif Unix}
  237. DoExecute(ExeFile,GetRunParameters,'','','',exNormal);
  238. {$I-}
  239. chdir(oldcurrdir);
  240. {$I+}
  241. EatIO;
  242. { In case we have something that the compiler touched }
  243. AskToReloadAllModifiedFiles;
  244. LastExitCode:=ExecuteResult;
  245. If IOStatus<>0 then
  246. begin
  247. MsgParms[1].Ptr:=@EXEFile;
  248. MsgParms[2].long:=IOStatus;
  249. InformationBox(msg_programnotrundoserroris,@MsgParms);
  250. end
  251. else If LastExitCode<>0 then
  252. begin
  253. MsgParms[1].Ptr:=@EXEFile;
  254. MsgParms[2].long:=LastExitCode;
  255. InformationBox(msg_programfileexitedwithexitcode,@MsgParms);
  256. end;
  257. end
  258. {$ifndef NODEBUG}
  259. else
  260. Debugger^.Continue
  261. {$endif}
  262. ;
  263. end;
  264. procedure TIDEApp.UpdateRunMenu(DebuggeeRunning : boolean);
  265. var MenuItem : PMenuItem;
  266. begin
  267. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmRun);
  268. if assigned(MenuItem) then
  269. begin
  270. If assigned(MenuItem^.Name) then
  271. DisposeStr(MenuItem^.Name);
  272. if DebuggeeRunning then
  273. MenuItem^.Name:=NewStr(menu_run_continue)
  274. else
  275. MenuItem^.Name:=NewStr(menu_run_run);
  276. end;
  277. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmResetDebugger);
  278. if assigned(MenuItem) then
  279. MenuItem^.Disabled:=not DebuggeeRunning;
  280. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmUntilReturn);
  281. if assigned(MenuItem) then
  282. MenuItem^.Disabled:=not DebuggeeRunning;
  283. end;
  284. procedure TIDEApp.RunDir;
  285. var
  286. s : DirStr;
  287. begin
  288. s:=GetRunDir;
  289. SelectDir(s,hidRunDir);
  290. SetRunDir(s);
  291. end;
  292. procedure TIDEApp.Parameters;
  293. var R,R2: TRect;
  294. D: PCenterDialog;
  295. IL: PEditorInputLine;
  296. begin
  297. R.Assign(0,0,round(ScreenWidth*54/80),4);
  298. New(D, Init(R, dialog_programparameters));
  299. with D^ do
  300. begin
  301. GetExtent(R); R.Grow(-2,-1); Inc(R.A.Y); R.B.Y:=R.A.Y+1;
  302. R2.Copy(R); R2.A.X:=16; Dec(R2.B.X,4);
  303. New(IL, Init(R2, 255));
  304. IL^.Data^:=GetRunParameters;
  305. Insert(IL);
  306. R2.Copy(R); R2.A.X:=R2.B.X-3; R2.B.X:=R2.A.X+3;
  307. Insert(New(PHistory, Init(R2, IL, hidRunParameters)));
  308. R2.Copy(R); R2.B.X:=16;
  309. Insert(New(PLabel, Init(R2, label_parameters_parameter, IL)));
  310. end;
  311. InsertButtons(D);
  312. IL^.Select;
  313. if Desktop^.ExecView(D)=cmOK then
  314. begin
  315. SetRunParameters(IL^.Data^);
  316. end;
  317. Dispose(D, Done);
  318. end;
  319. procedure TIDEApp.DoResetDebugger;
  320. begin
  321. {$ifndef NODEBUG}
  322. if assigned(Debugger) then
  323. DoneDebugger;
  324. UpdateScreen(true);
  325. {$else NODEBUG}
  326. NoDebugger;
  327. {$endif NODEBUG}
  328. end;
  329. procedure TIDEApp.DoContToCursor;
  330. {$ifndef NODEBUG}
  331. var
  332. W : PFPWindow;
  333. PDL : PDisasLine;
  334. S,FileName : string;
  335. P,CurY,LineNr : longint;
  336. {$endif}
  337. begin
  338. {$ifndef NODEBUG}
  339. if (DeskTop^.Current=nil) or
  340. ((TypeOf(DeskTop^.Current^)<>TypeOf(TSourceWindow)) and
  341. (TypeOf(DeskTop^.Current^)<>TypeOf(TDisassemblyWindow))) then
  342. Begin
  343. ErrorBox(msg_impossibletoreachcursor,nil);
  344. Exit;
  345. End;
  346. If not assigned(Debugger) or Not Debugger^.HasExe then
  347. begin
  348. InitDebugger;
  349. if not assigned(Debugger) then
  350. begin
  351. NoDebugger;
  352. exit;
  353. end;
  354. end;
  355. W:=PFPWindow(DeskTop^.Current);
  356. If assigned(W) then
  357. begin
  358. If TypeOf(W^)=TypeOf(TSourceWindow) then
  359. begin
  360. FileName:=PSourceWindow(W)^.Editor^.FileName;
  361. LineNr:=PSourceWindow(W)^.Editor^.CurPos.Y+1;
  362. Debugger^.Command('tbreak '+GDBFileName(NameAndExtOf(FileName))+':'+IntToStr(LineNr));
  363. Debugger^.Continue;
  364. end
  365. else
  366. begin
  367. CurY:=PDisassemblyWindow(W)^.Editor^.CurPos.Y;
  368. if CurY<PDisassemblyWindow(W)^.Editor^.GetLineCount then
  369. PDL:=PDisasLine(PDisassemblyWindow(W)^.Editor^.GetLine(CurY))
  370. else
  371. PDL:=nil;
  372. if assigned(PDL) then
  373. begin
  374. if PDL^.Address<>0 then
  375. begin
  376. Debugger^.Command('tbreak *0x'+IntToHex(PDL^.Address,8));
  377. end
  378. else
  379. begin
  380. S:=PDisassemblyWindow(W)^.Editor^.GetDisplayText(PDisassemblyWindow(W)^.Editor^.CurPos.Y);
  381. p:=pos(':',S);
  382. FileName:=Copy(S,1,p-1);
  383. S:=Copy(S,p+1,high(S));
  384. p:=pos(' ',S);
  385. S:=Copy(S,1,p-1);
  386. LineNr:=StrToInt(S);
  387. Debugger^.Command('tbreak '+GDBFileName(NameAndExtOf(FileName))+':'+IntToStr(LineNr));
  388. end;
  389. Debugger^.Continue;
  390. end;
  391. end;
  392. end;
  393. {$else NODEBUG}
  394. NoDebugger;
  395. {$endif NODEBUG}
  396. end;
  397. procedure TIDEApp.DoOpenGDBWindow;
  398. begin
  399. {$ifndef NODEBUG}
  400. InitGDBWindow;
  401. if not assigned(Debugger) then
  402. begin
  403. new(Debugger,Init);
  404. if assigned(Debugger) then
  405. Debugger^.SetExe(ExeFile);
  406. end;
  407. If assigned(GDBWindow) then
  408. GDBWindow^.MakeFirst;
  409. {$else NODEBUG}
  410. NoDebugger;
  411. {$endif NODEBUG}
  412. end;
  413. procedure TIDEApp.DoToggleBreak;
  414. {$ifndef NODEBUG}
  415. var
  416. W : PSourceWindow;
  417. WD : PDisassemblyWindow;
  418. PDL : PDisasLine;
  419. PB : PBreakpoint;
  420. S,FileName : string;
  421. b : boolean;
  422. CurY,P,LineNr : longint;
  423. {$endif}
  424. begin
  425. {$ifndef NODEBUG}
  426. if (DeskTop^.Current=nil) or
  427. (TypeOf(DeskTop^.Current^)<>TypeOf(TSourceWindow)) and
  428. (TypeOf(DeskTop^.Current^)<>TypeOf(TDisassemblyWindow)) then
  429. Begin
  430. ErrorBox(msg_impossibletosetbreakpoint,nil);
  431. Exit;
  432. End;
  433. if assigned (DeskTop^.Current) and
  434. (TypeOf(DeskTop^.Current^)=TypeOf(TSourceWindow)) then
  435. begin
  436. W:=PSourceWindow(DeskTop^.Current);
  437. FileName:=W^.Editor^.FileName;
  438. If FileName='' then
  439. begin
  440. W^.Editor^.SaveAs;
  441. FileName:=W^.Editor^.FileName;
  442. If FileName='' then
  443. Begin
  444. ErrorBox(msg_impossibletosetbreakpoint,nil);
  445. Exit;
  446. End;
  447. end;
  448. LineNr:=W^.Editor^.CurPos.Y+1;
  449. BreakpointsCollection^.ToggleFileLine(FileName,LineNr);
  450. end
  451. else if assigned (DeskTop^.Current) and
  452. (TypeOf(DeskTop^.Current^)=TypeOf(TDisassemblyWindow)) then
  453. begin
  454. WD:=PDisassemblyWindow(DeskTop^.Current);
  455. CurY:=WD^.Editor^.CurPos.Y;
  456. if CurY<WD^.Editor^.GetLineCount then
  457. PDL:=PDisasLine(WD^.Editor^.GetLine(CurY))
  458. else
  459. PDL:=nil;
  460. if assigned(PDL) then
  461. begin
  462. if PDL^.Address<>0 then
  463. begin
  464. PB:=New(PBreakpoint,init_address(IntToHex(PDL^.Address,8)));
  465. BreakpointsCollection^.Insert(PB);
  466. WD^.Editor^.SetLineFlagState(CurY,lfBreakpoint,true);
  467. end
  468. else
  469. begin
  470. S:=WD^.Editor^.GetDisplayText(WD^.Editor^.CurPos.Y);
  471. p:=pos(':',S);
  472. FileName:=Copy(S,1,p-1);
  473. S:=Copy(S,p+1,high(S));
  474. p:=pos(' ',S);
  475. S:=Copy(S,1,p-1);
  476. LineNr:=StrToInt(S);
  477. b:=BreakpointsCollection^.ToggleFileLine(FileName,LineNr);
  478. WD^.Editor^.SetLineFlagState(CurY,lfBreakpoint,b);
  479. end;
  480. end;
  481. end;
  482. {$else NODEBUG}
  483. NoDebugger;
  484. {$endif NODEBUG}
  485. end;