2
0

fpmrun.inc 14 KB

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