fpmrun.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  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. begin
  262. if AskRecompileIfModified then
  263. exit;
  264. Debugger^.Continue;
  265. end;
  266. {$endif}
  267. ;
  268. end;
  269. procedure TIDEApp.UpdateRunMenu(DebuggeeRunning : boolean);
  270. var MenuItem : PMenuItem;
  271. begin
  272. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmRun);
  273. if not assigned(MenuItem) then
  274. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmContinue);
  275. if assigned(MenuItem) then
  276. begin
  277. If assigned(MenuItem^.Name) then
  278. DisposeStr(MenuItem^.Name);
  279. if DebuggeeRunning then
  280. begin
  281. MenuItem^.Name:=NewStr(menu_run_continue);
  282. MenuItem^.command:=cmContinue;
  283. end
  284. else
  285. begin
  286. MenuItem^.Name:=NewStr(menu_run_run);
  287. MenuItem^.command:=cmRun;
  288. end;
  289. end;
  290. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmResetDebugger);
  291. if assigned(MenuItem) then
  292. MenuItem^.Disabled:=not DebuggeeRunning;
  293. MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmUntilReturn);
  294. if assigned(MenuItem) then
  295. MenuItem^.Disabled:=not DebuggeeRunning;
  296. end;
  297. procedure TIDEApp.RunDir;
  298. var
  299. s : DirStr;
  300. begin
  301. s:=GetRunDir;
  302. SelectDir(s,hidRunDir);
  303. SetRunDir(s);
  304. end;
  305. procedure TIDEApp.Parameters;
  306. var R,R2: TRect;
  307. D: PCenterDialog;
  308. IL: PEditorInputLine;
  309. begin
  310. R.Assign(0,0,round(ScreenWidth*54/80),4);
  311. New(D, Init(R, dialog_programparameters));
  312. with D^ do
  313. begin
  314. GetExtent(R); R.Grow(-2,-1); Inc(R.A.Y); R.B.Y:=R.A.Y+1;
  315. R2.Copy(R); R2.A.X:=16; Dec(R2.B.X,4);
  316. New(IL, Init(R2, 255));
  317. IL^.Data^:=GetRunParameters;
  318. Insert(IL);
  319. R2.Copy(R); R2.A.X:=R2.B.X-3; R2.B.X:=R2.A.X+3;
  320. Insert(New(PHistory, Init(R2, IL, hidRunParameters)));
  321. R2.Copy(R); R2.B.X:=16;
  322. Insert(New(PLabel, Init(R2, label_parameters_parameter, IL)));
  323. end;
  324. InsertButtons(D);
  325. IL^.Select;
  326. if Desktop^.ExecView(D)=cmOK then
  327. begin
  328. SetRunParameters(IL^.Data^);
  329. end;
  330. Dispose(D, Done);
  331. end;
  332. procedure TIDEApp.DoResetDebugger;
  333. begin
  334. {$ifndef NODEBUG}
  335. if assigned(Debugger) then
  336. DoneDebugger;
  337. UpdateScreen(true);
  338. {$else NODEBUG}
  339. NoDebugger;
  340. {$endif NODEBUG}
  341. end;
  342. procedure TIDEApp.DoContToCursor;
  343. {$ifndef NODEBUG}
  344. var
  345. W : PFPWindow;
  346. PDL : PDisasLine;
  347. S,FileName : string;
  348. P,CurY,LineNr : longint;
  349. {$endif}
  350. begin
  351. {$ifndef NODEBUG}
  352. if (DeskTop^.Current=nil) or
  353. ((TypeOf(DeskTop^.Current^)<>TypeOf(TSourceWindow)) and
  354. (TypeOf(DeskTop^.Current^)<>TypeOf(TDisassemblyWindow))) then
  355. Begin
  356. ErrorBox(msg_impossibletoreachcursor,nil);
  357. Exit;
  358. End;
  359. If not assigned(Debugger) or Not Debugger^.HasExe then
  360. begin
  361. InitDebugger;
  362. if not assigned(Debugger) then
  363. begin
  364. NoDebugger;
  365. exit;
  366. end;
  367. end;
  368. W:=PFPWindow(DeskTop^.Current);
  369. If assigned(W) then
  370. begin
  371. If TypeOf(W^)=TypeOf(TSourceWindow) then
  372. begin
  373. FileName:=PSourceWindow(W)^.Editor^.FileName;
  374. LineNr:=PSourceWindow(W)^.Editor^.CurPos.Y+1;
  375. Debugger^.Command('tbreak '+GDBFileName(NameAndExtOf(FileName))+':'+IntToStr(LineNr));
  376. Debugger^.Continue;
  377. end
  378. else
  379. begin
  380. CurY:=PDisassemblyWindow(W)^.Editor^.CurPos.Y;
  381. if CurY<PDisassemblyWindow(W)^.Editor^.GetLineCount then
  382. PDL:=PDisasLine(PDisassemblyWindow(W)^.Editor^.GetLine(CurY))
  383. else
  384. PDL:=nil;
  385. if assigned(PDL) then
  386. begin
  387. if PDL^.Address<>0 then
  388. begin
  389. Debugger^.Command('tbreak *0x'+HexStr(PDL^.Address,sizeof(pointer)*2));
  390. end
  391. else
  392. begin
  393. S:=PDisassemblyWindow(W)^.Editor^.GetDisplayText(PDisassemblyWindow(W)^.Editor^.CurPos.Y);
  394. p:=pos(':',S);
  395. FileName:=Copy(S,1,p-1);
  396. S:=Copy(S,p+1,high(S));
  397. p:=pos(' ',S);
  398. S:=Copy(S,1,p-1);
  399. LineNr:=StrToInt(S);
  400. Debugger^.Command('tbreak '+GDBFileName(NameAndExtOf(FileName))+':'+IntToStr(LineNr));
  401. end;
  402. Debugger^.Continue;
  403. end;
  404. end;
  405. end;
  406. {$else NODEBUG}
  407. NoDebugger;
  408. {$endif NODEBUG}
  409. end;
  410. procedure TIDEApp.DoOpenGDBWindow;
  411. begin
  412. {$ifndef NODEBUG}
  413. InitGDBWindow;
  414. if not assigned(Debugger) then
  415. begin
  416. new(Debugger,Init);
  417. if assigned(Debugger) then
  418. Debugger^.SetExe(ExeFile);
  419. end;
  420. If assigned(GDBWindow) then
  421. GDBWindow^.MakeFirst;
  422. {$else NODEBUG}
  423. NoDebugger;
  424. {$endif NODEBUG}
  425. end;
  426. procedure TIDEApp.DoToggleBreak;
  427. {$ifndef NODEBUG}
  428. var
  429. W : PSourceWindow;
  430. WD : PDisassemblyWindow;
  431. PDL : PDisasLine;
  432. PB : PBreakpoint;
  433. S,FileName : string;
  434. b : boolean;
  435. CurY,P,LineNr : longint;
  436. {$endif}
  437. begin
  438. {$ifndef NODEBUG}
  439. if (DeskTop^.Current=nil) or
  440. (TypeOf(DeskTop^.Current^)<>TypeOf(TSourceWindow)) and
  441. (TypeOf(DeskTop^.Current^)<>TypeOf(TDisassemblyWindow)) then
  442. Begin
  443. ErrorBox(msg_impossibletosetbreakpoint,nil);
  444. Exit;
  445. End;
  446. if assigned (DeskTop^.Current) and
  447. (TypeOf(DeskTop^.Current^)=TypeOf(TSourceWindow)) then
  448. begin
  449. W:=PSourceWindow(DeskTop^.Current);
  450. FileName:=W^.Editor^.FileName;
  451. If FileName='' then
  452. begin
  453. W^.Editor^.SaveAs;
  454. FileName:=W^.Editor^.FileName;
  455. If FileName='' then
  456. Begin
  457. ErrorBox(msg_impossibletosetbreakpoint,nil);
  458. Exit;
  459. End;
  460. end;
  461. LineNr:=W^.Editor^.CurPos.Y+1;
  462. BreakpointsCollection^.ToggleFileLine(FileName,LineNr);
  463. end
  464. else if assigned (DeskTop^.Current) and
  465. (TypeOf(DeskTop^.Current^)=TypeOf(TDisassemblyWindow)) then
  466. begin
  467. WD:=PDisassemblyWindow(DeskTop^.Current);
  468. CurY:=WD^.Editor^.CurPos.Y;
  469. if CurY<WD^.Editor^.GetLineCount then
  470. PDL:=PDisasLine(WD^.Editor^.GetLine(CurY))
  471. else
  472. PDL:=nil;
  473. if assigned(PDL) then
  474. begin
  475. if PDL^.Address<>0 then
  476. begin
  477. PB:=New(PBreakpoint,init_address(HexStr(PDL^.Address,sizeof(pointer)*2)));
  478. BreakpointsCollection^.Insert(PB);
  479. WD^.Editor^.SetLineFlagState(CurY,lfBreakpoint,true);
  480. end
  481. else
  482. begin
  483. S:=WD^.Editor^.GetDisplayText(WD^.Editor^.CurPos.Y);
  484. p:=pos(':',S);
  485. FileName:=Copy(S,1,p-1);
  486. S:=Copy(S,p+1,high(S));
  487. p:=pos(' ',S);
  488. S:=Copy(S,1,p-1);
  489. LineNr:=StrToInt(S);
  490. b:=BreakpointsCollection^.ToggleFileLine(FileName,LineNr);
  491. WD^.Editor^.SetLineFlagState(CurY,lfBreakpoint,b);
  492. end;
  493. end;
  494. end;
  495. {$else NODEBUG}
  496. NoDebugger;
  497. {$endif NODEBUG}
  498. end;