fpdebug.pas 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. Debugger call routines for the IDE
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit FPDebug;
  13. interface
  14. uses
  15. Objects,Dialogs,Drivers,Views,
  16. GDBCon,GDBInt,Menus,
  17. WViews,
  18. FPViews;
  19. type
  20. PDebugController=^TDebugController;
  21. TDebugController=object(TGDBController)
  22. InvalidSourceLine : boolean;
  23. LastFileName : string;
  24. LastSource : PView; {PsourceWindow !! }
  25. HiddenStepsCount : longint;
  26. constructor Init(const exefn:string);
  27. destructor Done;
  28. procedure DoSelectSourceline(const fn:string;line:longint);virtual;
  29. { procedure DoStartSession;virtual;
  30. procedure DoBreakSession;virtual;}
  31. procedure DoEndSession(code:longint);virtual;
  32. procedure AnnotateError;
  33. procedure InsertBreakpoints;
  34. procedure RemoveBreakpoints;
  35. procedure ResetBreakpointsValues;
  36. procedure DoDebuggerScreen;virtual;
  37. procedure DoUserScreen;virtual;
  38. procedure Reset;virtual;
  39. procedure Run;virtual;
  40. procedure Continue;virtual;
  41. procedure CommandBegin(const s:string);virtual;
  42. procedure CommandEnd(const s:string);virtual;
  43. end;
  44. BreakpointType = (bt_function,bt_file_line,bt_watch,bt_awatch,bt_rwatch,bt_invalid);
  45. BreakpointState = (bs_enabled,bs_disabled,bs_deleted);
  46. PBreakpointCollection=^TBreakpointCollection;
  47. PBreakpoint=^TBreakpoint;
  48. TBreakpoint=object(TObject)
  49. typ : BreakpointType;
  50. state : BreakpointState;
  51. owner : PBreakpointCollection;
  52. Name : PString; { either function name or expr to watch }
  53. FileName : PString;
  54. OldValue,CurrentValue : Pstring;
  55. Line : Longint; { only used for bt_file_line type }
  56. Conditions : PString; { conditions relative to that breakpoint }
  57. IgnoreCount : Longint; { how many counts should be ignored }
  58. Commands : pchar; { commands that should be executed on breakpoint }
  59. GDBIndex : longint;
  60. GDBState : BreakpointState;
  61. constructor Init_function(Const AFunc : String);
  62. constructor Init_Empty;
  63. constructor Init_file_line(AFile : String; ALine : longint);
  64. constructor Init_type(atyp : BreakpointType;Const AnExpr : String);
  65. procedure Insert;
  66. procedure Remove;
  67. procedure Enable;
  68. procedure Disable;
  69. procedure ResetValues;
  70. destructor Done;virtual;
  71. end;
  72. TBreakpointCollection=object(TCollection)
  73. function At(Index: Integer): PBreakpoint;
  74. function GetGDB(index : longint) : PBreakpoint;
  75. function GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
  76. function ToggleFileLine(Const FileName: String;LineNr : Longint) : boolean;
  77. procedure Update;
  78. procedure ShowBreakpoints(W : PSourceWindow);
  79. end;
  80. PBreakpointItem = ^TBreakpointItem;
  81. TBreakpointItem = object(TObject)
  82. Breakpoint : PBreakpoint;
  83. constructor Init(ABreakpoint : PBreakpoint);
  84. function GetText(MaxLen: Sw_integer): string; virtual;
  85. procedure Selected; virtual;
  86. function GetModuleName: string; virtual;
  87. end;
  88. PBreakpointListBox = ^TBreakpointListBox;
  89. TBreakpointListBox = object(THSListBox)
  90. Transparent : boolean;
  91. NoSelection : boolean;
  92. MaxWidth : Sw_integer;
  93. (* ModuleNames : PStoreCollection; *)
  94. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  95. procedure AddBreakpoint(P: PBreakpointItem); virtual;
  96. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  97. function GetLocalMenu: PMenu;virtual;
  98. procedure Clear; virtual;
  99. procedure TrackSource; virtual;
  100. procedure EditNew; virtual;
  101. procedure EditCurrent; virtual;
  102. procedure DeleteCurrent; virtual;
  103. procedure ToggleCurrent;
  104. procedure Draw; virtual;
  105. procedure HandleEvent(var Event: TEvent); virtual;
  106. (* constructor Load(var S: TStream);
  107. procedure Store(var S: TStream); *)
  108. destructor Done; virtual;
  109. end;
  110. PBreakpointsWindow = ^TBreakpointsWindow;
  111. TBreakpointsWindow = object(TDlgWindow)
  112. BreakLB : PBreakpointListBox;
  113. constructor Init;
  114. procedure AddBreakpoint(ABreakpoint : PBreakpoint);
  115. procedure ClearBreakpoints;
  116. procedure ReloadBreakpoints;
  117. procedure Close; virtual;
  118. procedure SizeLimits(var Min, Max: TPoint);virtual;
  119. procedure HandleEvent(var Event: TEvent); virtual;
  120. procedure Update; virtual;
  121. destructor Done; virtual;
  122. end;
  123. PBreakpointItemDialog = ^TBreakpointItemDialog;
  124. TBreakpointItemDialog = object(TCenterDialog)
  125. constructor Init(ABreakpoint: PBreakpoint);
  126. function Execute: Word; virtual;
  127. private
  128. Breakpoint : PBreakpoint;
  129. TypeRB : PRadioButtons;
  130. NameIL : PInputLine;
  131. ConditionsIL: PInputLine;
  132. LineIL : PInputLine;
  133. IgnoreIL : PInputLine;
  134. end;
  135. const
  136. BreakpointTypeStr : Array[BreakpointType] of String[9]
  137. = ( 'function','file-line','watch','awatch','rwatch','invalid' );
  138. BreakpointStateStr : Array[BreakpointState] of String[8]
  139. = ( 'enabled','disabled','invalid' );
  140. var
  141. Debugger : PDebugController;
  142. BreakpointCollection : PBreakpointCollection;
  143. procedure InitDebugger;
  144. procedure DoneDebugger;
  145. procedure InitGDBWindow;
  146. procedure DoneGDBWindow;
  147. procedure InitBreakpoints;
  148. procedure DoneBreakpoints;
  149. implementation
  150. uses
  151. Dos,Mouse,Video,
  152. App,Commands,Strings,
  153. FPVars,FPUtils,FPConst,
  154. FPIntf,FPCompile,FPIde,
  155. Validate,WEditor,WUtils;
  156. {****************************************************************************
  157. TDebugController
  158. ****************************************************************************}
  159. constructor TDebugController.Init(const exefn:string);
  160. var f: string;
  161. begin
  162. inherited Init;
  163. f := exefn;
  164. LoadFile(f);
  165. SetArgs(GetRunParameters);
  166. Debugger:=@self;
  167. InsertBreakpoints;
  168. end;
  169. procedure TDebugController.InsertBreakpoints;
  170. procedure DoInsert(PB : PBreakpoint);
  171. begin
  172. PB^.Insert;
  173. end;
  174. begin
  175. BreakpointCollection^.ForEach(@DoInsert);
  176. end;
  177. procedure TDebugController.RemoveBreakpoints;
  178. procedure DoDelete(PB : PBreakpoint);
  179. begin
  180. PB^.Remove;
  181. end;
  182. begin
  183. BreakpointCollection^.ForEach(@DoDelete);
  184. end;
  185. procedure TDebugController.ResetBreakpointsValues;
  186. procedure DoResetVal(PB : PBreakpoint);
  187. begin
  188. PB^.ResetValues;
  189. end;
  190. begin
  191. BreakpointCollection^.ForEach(@DoResetVal);
  192. end;
  193. destructor TDebugController.Done;
  194. begin
  195. { kill the program if running }
  196. Reset;
  197. RemoveBreakpoints;
  198. inherited Done;
  199. end;
  200. procedure TDebugController.Run;
  201. begin
  202. ResetBreakpointsValues;
  203. inherited Run;
  204. MyApp.SetCmdState([cmResetDebugger],true);
  205. end;
  206. procedure TDebugController.Continue;
  207. begin
  208. if not debugger_started then
  209. Run
  210. else
  211. inherited Continue;
  212. end;
  213. procedure TDebugController.CommandBegin(const s:string);
  214. begin
  215. if assigned(GDBWindow) and (in_command>1) then
  216. begin
  217. { We should do something special for errors !! }
  218. If StrLen(GetError)>0 then
  219. GDBWindow^.WriteErrorText(GetError);
  220. GDBWindow^.WriteOutputText(GetOutput);
  221. end;
  222. if assigned(GDBWindow) then
  223. GDBWindow^.WriteString(S);
  224. end;
  225. procedure TDebugController.CommandEnd(const s:string);
  226. begin
  227. if assigned(GDBWindow) and (in_command=0) then
  228. begin
  229. { We should do somethnig special for errors !! }
  230. If StrLen(GetError)>0 then
  231. GDBWindow^.WriteErrorText(GetError);
  232. GDBWindow^.WriteOutputText(GetOutput);
  233. GDBWindow^.Editor^.TextEnd;
  234. end;
  235. end;
  236. procedure TDebugController.Reset;
  237. var
  238. W : PSourceWindow;
  239. begin
  240. inherited Reset;
  241. MyApp.SetCmdState([cmResetDebugger],false);
  242. W:=PSourceWindow(LastSource);
  243. if assigned(W) then
  244. W^.Editor^.SetHighlightRow(-1);
  245. end;
  246. procedure TDebugController.AnnotateError;
  247. var errornb : longint;
  248. begin
  249. if error then
  250. begin
  251. errornb:=error_num;
  252. ErrorBox(#3'Error within GDB'#13#3'Error code = %d',@errornb);
  253. end;
  254. end;
  255. procedure TDebugController.DoSelectSourceLine(const fn:string;line:longint);
  256. var
  257. W: PSourceWindow;
  258. Found : boolean;
  259. PB : PBreakpoint;
  260. S : String;
  261. BreakIndex : longint;
  262. begin
  263. BreakIndex:=stop_breakpoint_number;
  264. Desktop^.Lock;
  265. if Line>0 then
  266. dec(Line);
  267. if (fn=LastFileName) then
  268. begin
  269. W:=PSourceWindow(LastSource);
  270. if assigned(W) then
  271. begin
  272. W^.Editor^.SetCurPtr(0,Line);
  273. W^.Editor^.TrackCursor(true);
  274. W^.Editor^.SetHighlightRow(Line);
  275. if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  276. W^.Select;
  277. InvalidSourceLine:=false;
  278. end
  279. else
  280. InvalidSourceLine:=true;
  281. end
  282. else
  283. begin
  284. W:=TryToOpenFile(nil,fn,0,Line,false);
  285. if assigned(W) then
  286. begin
  287. W^.Editor^.SetHighlightRow(Line);
  288. W^.Editor^.TrackCursor(true);
  289. if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  290. W^.Select;
  291. LastSource:=W;
  292. InvalidSourceLine:=false;
  293. end
  294. { only search a file once }
  295. else
  296. begin
  297. Desktop^.UnLock;
  298. Found:=MyApp.OpenSearch(fn);
  299. Desktop^.Lock;
  300. if not Found then
  301. begin
  302. InvalidSourceLine:=true;
  303. LastSource:=Nil;
  304. end
  305. else
  306. begin
  307. { should now be open }
  308. W:=TryToOpenFile(nil,fn,0,Line,true);
  309. W^.Editor^.SetHighlightRow(Line);
  310. W^.Editor^.TrackCursor(true);
  311. if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  312. W^.Select;
  313. LastSource:=W;
  314. InvalidSourceLine:=false;
  315. end;
  316. end;
  317. end;
  318. LastFileName:=fn;
  319. Desktop^.UnLock;
  320. if BreakIndex>0 then
  321. begin
  322. PB:=BreakpointCollection^.GetGDB(stop_breakpoint_number);
  323. { For watch we should get old and new value !! }
  324. if (Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive)) and
  325. (PB^.typ<>bt_file_line) and (PB^.typ<>bt_function) then
  326. begin
  327. Command('p '+GetStr(PB^.Name));
  328. S:=StrPas(GetOutput);
  329. If Pos('=',S)>0 then
  330. S:=Copy(S,Pos('=',S)+1,255);
  331. If S[Length(S)]=#10 then
  332. Delete(S,Length(S),1);
  333. if Assigned(PB^.OldValue) then
  334. DisposeStr(PB^.OldValue);
  335. PB^.OldValue:=PB^.CurrentValue;
  336. PB^.CurrentValue:=NewStr(S);
  337. If PB^.typ=bt_function then
  338. WarningBox(#3'GDB stopped due to'#13+
  339. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name),nil)
  340. else if (GetStr(PB^.OldValue)<>S) then
  341. WarningBox(#3'GDB stopped due to'#13+
  342. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
  343. #3+'Old value = '+GetStr(PB^.OldValue)+#13+
  344. #3+'New value = '+GetStr(PB^.CurrentValue),nil)
  345. else
  346. WarningBox(#3'GDB stopped due to'#13+
  347. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
  348. #3+' value = '+GetStr(PB^.CurrentValue),nil);
  349. end;
  350. end;
  351. end;
  352. procedure TDebugController.DoEndSession(code:longint);
  353. var P :Array[1..2] of longint;
  354. W : PSourceWindow;
  355. begin
  356. MyApp.SetCmdState([cmResetDebugger],false);
  357. W:=PSourceWindow(LastSource);
  358. if assigned(W) then
  359. W^.Editor^.SetHighlightRow(-1);
  360. If HiddenStepsCount=0 then
  361. InformationBox(#3'Program exited with '#13#3'exitcode = %d',@code)
  362. else
  363. begin
  364. P[1]:=code;
  365. P[2]:=HiddenStepsCount;
  366. WarningBox(#3'Program exited with '#13+
  367. #3'exitcode = %d'#13+
  368. #3'hidden steps = %d',@P);
  369. end;
  370. end;
  371. procedure TDebugController.DoDebuggerScreen;
  372. begin
  373. MyApp.ShowIDEScreen;
  374. end;
  375. procedure TDebugController.DoUserScreen;
  376. begin
  377. MyApp.ShowUserScreen;
  378. end;
  379. {****************************************************************************
  380. TBreakpoint
  381. ****************************************************************************}
  382. constructor TBreakpoint.Init_function(Const AFunc : String);
  383. begin
  384. typ:=bt_function;
  385. state:=bs_enabled;
  386. GDBState:=bs_deleted;
  387. Name:=NewStr(AFunc);
  388. FileName:=nil;
  389. Line:=0;
  390. IgnoreCount:=0;
  391. Commands:=nil;
  392. Conditions:=nil;
  393. OldValue:=nil;
  394. CurrentValue:=nil;
  395. end;
  396. constructor TBreakpoint.Init_Empty;
  397. begin
  398. typ:=bt_function;
  399. state:=bs_enabled;
  400. GDBState:=bs_deleted;
  401. Name:=Nil;
  402. FileName:=nil;
  403. Line:=0;
  404. IgnoreCount:=0;
  405. Commands:=nil;
  406. Conditions:=nil;
  407. OldValue:=nil;
  408. CurrentValue:=nil;
  409. end;
  410. constructor TBreakpoint.Init_type(atyp : BreakpointType;Const AnExpr : String);
  411. begin
  412. typ:=atyp;
  413. state:=bs_enabled;
  414. GDBState:=bs_deleted;
  415. Name:=NewStr(AnExpr);
  416. IgnoreCount:=0;
  417. Commands:=nil;
  418. Conditions:=nil;
  419. OldValue:=nil;
  420. CurrentValue:=nil;
  421. end;
  422. constructor TBreakpoint.Init_file_line(AFile : String; ALine : longint);
  423. begin
  424. typ:=bt_file_line;
  425. state:=bs_enabled;
  426. GDBState:=bs_deleted;
  427. { d:test.pas:12 does not work !! }
  428. { I do not know how to solve this if
  429. if (Length(AFile)>1) and (AFile[2]=':') then
  430. AFile:=Copy(AFile,3,255);
  431. Only use base name for now !! PM }
  432. FileName:=NewStr(AFile);
  433. Name:=nil;
  434. Line:=ALine;
  435. IgnoreCount:=0;
  436. Commands:=nil;
  437. Conditions:=nil;
  438. OldValue:=nil;
  439. CurrentValue:=nil;
  440. end;
  441. procedure TBreakpoint.Insert;
  442. begin
  443. If not assigned(Debugger) then Exit;
  444. Remove;
  445. Debugger^.last_breakpoint_number:=0;
  446. if (GDBState=bs_deleted) and (state=bs_enabled) then
  447. begin
  448. if (typ=bt_file_line) and assigned(FileName) then
  449. Debugger^.Command('break '+NameAndExtOf(FileName^)+':'+IntToStr(Line))
  450. else if (typ=bt_function) and assigned(name) then
  451. Debugger^.Command('break '+name^)
  452. else if (typ=bt_watch) and assigned(name) then
  453. Debugger^.Command('watch '+name^)
  454. else if (typ=bt_awatch) and assigned(name) then
  455. Debugger^.Command('awatch '+name^)
  456. else if (typ=bt_rwatch) and assigned(name) then
  457. Debugger^.Command('rwatch '+name^);
  458. if Debugger^.last_breakpoint_number<>0 then
  459. begin
  460. GDBIndex:=Debugger^.last_breakpoint_number;
  461. GDBState:=bs_enabled;
  462. Debugger^.Command('cond '+IntToStr(GDBIndex)+' '+GetStr(Conditions));
  463. Debugger^.Command('ignore '+IntToStr(GDBIndex)+' '+IntToStr(IgnoreCount));
  464. If Assigned(Commands) then
  465. begin
  466. {Commands are not handled yet }
  467. end;
  468. end
  469. else
  470. { Here there was a problem !! }
  471. begin
  472. GDBIndex:=0;
  473. ErrorBox(#3'Could not set Breakpoint'#13+
  474. #3+BreakpointTypeStr[typ]+' '+Name^,nil);
  475. state:=bs_disabled;
  476. end;
  477. end
  478. else if (GDBState=bs_disabled) and (state=bs_enabled) then
  479. Enable
  480. else if (GDBState=bs_enabled) and (state=bs_disabled) then
  481. Disable;
  482. end;
  483. procedure TBreakpoint.Remove;
  484. begin
  485. If not assigned(Debugger) then Exit;
  486. if GDBIndex>0 then
  487. Debugger^.Command('delete '+IntToStr(GDBIndex));
  488. GDBIndex:=0;
  489. GDBState:=bs_deleted;
  490. end;
  491. procedure TBreakpoint.Enable;
  492. begin
  493. If not assigned(Debugger) then Exit;
  494. if GDBIndex>0 then
  495. Debugger^.Command('enable '+IntToStr(GDBIndex))
  496. else
  497. Insert;
  498. GDBState:=bs_enabled;
  499. end;
  500. procedure TBreakpoint.Disable;
  501. begin
  502. If not assigned(Debugger) then Exit;
  503. if GDBIndex>0 then
  504. Debugger^.Command('disable '+IntToStr(GDBIndex));
  505. GDBState:=bs_disabled;
  506. end;
  507. procedure TBreakpoint.ResetValues;
  508. begin
  509. if assigned(OldValue) then
  510. DisposeStr(OldValue);
  511. OldValue:=nil;
  512. if assigned(CurrentValue) then
  513. DisposeStr(CurrentValue);
  514. CurrentValue:=nil;
  515. end;
  516. destructor TBreakpoint.Done;
  517. begin
  518. Remove;
  519. ResetValues;
  520. if assigned(Name) then
  521. DisposeStr(Name);
  522. if assigned(FileName) then
  523. DisposeStr(FileName);
  524. if assigned(Conditions) then
  525. DisposeStr(Conditions);
  526. if assigned(Commands) then
  527. StrDispose(Commands);
  528. inherited Done;
  529. end;
  530. {****************************************************************************
  531. TBreakpointCollection
  532. ****************************************************************************}
  533. function TBreakpointCollection.At(Index: Integer): PBreakpoint;
  534. begin
  535. At:=inherited At(Index);
  536. end;
  537. procedure TBreakpointCollection.Update;
  538. begin
  539. if assigned(Debugger) then
  540. begin
  541. Debugger^.RemoveBreakpoints;
  542. Debugger^.InsertBreakpoints;
  543. end;
  544. if assigned(BreakpointsWindow) then
  545. BreakpointsWindow^.Update;
  546. end;
  547. function TBreakpointCollection.GetGDB(index : longint) : PBreakpoint;
  548. function IsNum(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  549. begin
  550. IsNum:=P^.GDBIndex=index;
  551. end;
  552. begin
  553. if index=0 then
  554. GetGDB:=nil
  555. else
  556. GetGDB:=FirstThat(@IsNum);
  557. end;
  558. procedure TBreakpointCollection.ShowBreakpoints(W : PSourceWindow);
  559. procedure SetInSource(P : PBreakpoint);{$ifndef FPC}far;{$endif}
  560. begin
  561. If assigned(P^.FileName) and (P^.FileName^=W^.Editor^.FileName) then
  562. W^.Editor^.SetLineBreakState(P^.Line,P^.state=bs_enabled);
  563. end;
  564. begin
  565. ForEach(@SetInSource);
  566. end;
  567. function TBreakpointCollection.GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
  568. function IsThis(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  569. begin
  570. IsThis:=(P^.typ=typ) and (P^.Name^=S);
  571. end;
  572. begin
  573. GetType:=FirstThat(@IsThis);
  574. end;
  575. function TBreakpointCollection.ToggleFileLine(Const FileName: String;LineNr : Longint) : boolean;
  576. var PB : PBreakpoint;
  577. function IsThere(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  578. begin
  579. IsThere:=(P^.typ=bt_file_line) and (P^.FileName^=FileName) and (P^.Line=LineNr);
  580. end;
  581. begin
  582. PB:=FirstThat(@IsThere);
  583. ToggleFileLine:=false;
  584. If Assigned(PB) then
  585. if PB^.state=bs_disabled then
  586. begin
  587. PB^.state:=bs_enabled;
  588. ToggleFileLine:=true;
  589. end
  590. else if PB^.state=bs_enabled then
  591. PB^.state:=bs_disabled;
  592. If not assigned(PB) then
  593. begin
  594. PB:= New(PBreakpoint,Init_file_line(FileName,LineNr));
  595. if assigned(PB) then
  596. Begin
  597. Insert(PB);
  598. ToggleFileLine:=true;
  599. End;
  600. end;
  601. Update;
  602. end;
  603. {****************************************************************************
  604. TBreakpointItem
  605. ****************************************************************************}
  606. constructor TBreakpointItem.Init(ABreakpoint : PBreakpoint);
  607. begin
  608. inherited Init;
  609. Breakpoint:=ABreakpoint;
  610. end;
  611. function TBreakpointItem.GetText(MaxLen: Sw_integer): string;
  612. var S: string;
  613. begin
  614. with Breakpoint^ do
  615. begin
  616. S:=BreakpointTypeStr[typ];
  617. While Length(S)<10 do
  618. S:=S+' ';
  619. S:=S+'|';
  620. S:=S+BreakpointStateStr[state]+' ';
  621. While Length(S)<20 do
  622. S:=S+' ';
  623. S:=S+'|';
  624. if (typ=bt_file_line) then
  625. S:=S+NameAndExtOf(GetStr(FileName))+':'+IntToStr(Line)
  626. else
  627. S:=S+GetStr(name);
  628. While Length(S)<40 do
  629. S:=S+' ';
  630. S:=S+'|';
  631. if IgnoreCount>0 then
  632. S:=S+IntToStr(IgnoreCount);
  633. While Length(S)<49 do
  634. S:=S+' ';
  635. S:=S+'|';
  636. if assigned(Conditions) then
  637. S:=S+' '+GetStr(Conditions);
  638. if length(S)>MaxLen then S:=copy(S,1,MaxLen-2)+'..';
  639. GetText:=S;
  640. end;
  641. end;
  642. procedure TBreakpointItem.Selected;
  643. begin
  644. end;
  645. function TBreakpointItem.GetModuleName: string;
  646. begin
  647. if breakpoint^.typ=bt_file_line then
  648. GetModuleName:=GetStr(breakpoint^.FileName)
  649. else
  650. GetModuleName:='';
  651. end;
  652. {****************************************************************************
  653. TBreakpointListBox
  654. ****************************************************************************}
  655. constructor TBreakpointListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  656. begin
  657. inherited Init(Bounds,1,AHScrollBar, AVScrollBar);
  658. GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  659. (* New(ModuleNames, Init(50,100)); *)
  660. NoSelection:=true;
  661. end;
  662. function TBreakpointListBox.GetLocalMenu: PMenu;
  663. var M: PMenu;
  664. begin
  665. if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
  666. M:=NewMenu(
  667. NewItem('~G~oto source','',kbNoKey,cmMsgGotoSource,hcMsgGotoSource,
  668. NewItem('~E~dit breakpoint','',kbNoKey,cmEdit,hcNoContext,
  669. NewItem('~N~ew breakpoint','',kbNoKey,cmNew,hcNoContext,
  670. NewItem('~D~elete breakpoint','',kbNoKey,cmDelete,hcNoContext,
  671. NewItem('~T~oggle state','',kbNoKey,cmToggleBreakpoint,hcNoContext,
  672. nil))))));
  673. GetLocalMenu:=M;
  674. end;
  675. procedure TBreakpointListBox.HandleEvent(var Event: TEvent);
  676. var DontClear: boolean;
  677. begin
  678. case Event.What of
  679. evKeyDown :
  680. begin
  681. DontClear:=false;
  682. case Event.KeyCode of
  683. kbEnter :
  684. Message(@Self,evCommand,cmMsgGotoSource,nil);
  685. else
  686. DontClear:=true;
  687. end;
  688. if not DontClear then
  689. ClearEvent(Event);
  690. end;
  691. evBroadcast :
  692. case Event.Command of
  693. cmListItemSelected :
  694. if Event.InfoPtr=@Self then
  695. Message(@Self,evCommand,cmEdit,nil);
  696. end;
  697. evCommand :
  698. begin
  699. DontClear:=false;
  700. case Event.Command of
  701. cmMsgTrackSource :
  702. if Range>0 then
  703. TrackSource;
  704. cmEdit :
  705. EditCurrent;
  706. cmToggleBreakpoint :
  707. ToggleCurrent;
  708. cmDelete :
  709. DeleteCurrent;
  710. cmNew :
  711. EditNew;
  712. cmMsgClear :
  713. Clear;
  714. else
  715. DontClear:=true;
  716. end;
  717. if not DontClear then
  718. ClearEvent(Event);
  719. end;
  720. end;
  721. inherited HandleEvent(Event);
  722. end;
  723. procedure TBreakpointListBox.AddBreakpoint(P: PBreakpointItem);
  724. var W : integer;
  725. begin
  726. if List=nil then New(List, Init(20,20));
  727. W:=length(P^.GetText(255));
  728. if W>MaxWidth then
  729. begin
  730. MaxWidth:=W;
  731. if HScrollBar<>nil then
  732. HScrollBar^.SetRange(0,MaxWidth);
  733. end;
  734. List^.Insert(P);
  735. SetRange(List^.Count);
  736. if Focused=List^.Count-1-1 then
  737. FocusItem(List^.Count-1);
  738. DrawView;
  739. end;
  740. (* function TBreakpointListBox.AddModuleName(const Name: string): PString;
  741. var P: PString;
  742. begin
  743. if ModuleNames<>nil then
  744. P:=ModuleNames^.Add(Name)
  745. else
  746. P:=nil;
  747. AddModuleName:=P;
  748. end; *)
  749. function TBreakpointListBox.GetText(Item,MaxLen: Sw_Integer): String;
  750. var P: PBreakpointItem;
  751. S: string;
  752. begin
  753. P:=List^.At(Item);
  754. S:=P^.GetText(MaxLen);
  755. GetText:=copy(S,1,MaxLen);
  756. end;
  757. procedure TBreakpointListBox.Clear;
  758. begin
  759. if assigned(List) then
  760. Dispose(List, Done);
  761. List:=nil;
  762. MaxWidth:=0;
  763. (* if assigned(ModuleNames) then
  764. ModuleNames^.FreeAll; *)
  765. SetRange(0); DrawView;
  766. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  767. end;
  768. procedure TBreakpointListBox.TrackSource;
  769. var W: PSourceWindow;
  770. P: PBreakpointItem;
  771. R: TRect;
  772. Row,Col: sw_integer;
  773. begin
  774. (*Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  775. if Range=0 then Exit;*)
  776. P:=List^.At(Focused);
  777. if P^.GetModuleName='' then Exit;
  778. Desktop^.Lock;
  779. GetNextEditorBounds(R);
  780. R.B.Y:=Owner^.Origin.Y;
  781. W:=EditorWindowFile(P^.GetModuleName);
  782. if assigned(W) then
  783. begin
  784. W^.GetExtent(R);
  785. R.B.Y:=Owner^.Origin.Y;
  786. W^.ChangeBounds(R);
  787. W^.Editor^.SetCurPtr(1,P^.Breakpoint^.Line);
  788. end
  789. else
  790. W:=TryToOpenFile(@R,P^.GetModuleName,1,P^.Breakpoint^.Line,true);
  791. if W<>nil then
  792. begin
  793. W^.Select;
  794. W^.Editor^.TrackCursor(true);
  795. W^.Editor^.SetHighlightRow(P^.Breakpoint^.Line);
  796. end;
  797. if Assigned(Owner) then
  798. Owner^.Select;
  799. Desktop^.UnLock;
  800. end;
  801. procedure TBreakpointListBox.ToggleCurrent;
  802. var W: PSourceWindow;
  803. P: PBreakpointItem;
  804. b : boolean;
  805. Row,Col: sw_integer;
  806. begin
  807. if Range=0 then Exit;
  808. P:=List^.At(Focused);
  809. if P=nil then Exit;
  810. if P^.Breakpoint^.state=bs_enabled then
  811. P^.Breakpoint^.state:=bs_disabled
  812. else if P^.Breakpoint^.state=bs_disabled then
  813. P^.Breakpoint^.state:=bs_enabled;
  814. BreakpointCollection^.Update;
  815. if P^.Breakpoint^.typ=bt_file_line then
  816. begin
  817. W:=TryToOpenFile(nil,GetStr(P^.Breakpoint^.FileName),1,P^.Breakpoint^.Line,false);
  818. If assigned(W) then
  819. begin
  820. if P^.Breakpoint^.state=bs_enabled then
  821. b:=true
  822. else
  823. b:=false;
  824. W^.Editor^.SetLineBreakState(P^.Breakpoint^.Line,b);
  825. end;
  826. end;
  827. end;
  828. procedure TBreakpointListBox.EditCurrent;
  829. var W: PSourceWindow;
  830. P: PBreakpointItem;
  831. Row,Col: sw_integer;
  832. begin
  833. if Range=0 then Exit;
  834. P:=List^.At(Focused);
  835. if P=nil then Exit;
  836. Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P^.Breakpoint)),nil);
  837. BreakpointCollection^.Update;
  838. end;
  839. procedure TBreakpointListBox.DeleteCurrent;
  840. var W: PSourceWindow;
  841. P: PBreakpointItem;
  842. Row,Col: sw_integer;
  843. begin
  844. if Range=0 then Exit;
  845. P:=List^.At(Focused);
  846. if P=nil then Exit;
  847. BreakpointCollection^.free(P^.Breakpoint);
  848. List^.free(P);
  849. BreakpointCollection^.Update;
  850. end;
  851. procedure TBreakpointListBox.EditNew;
  852. var W: PSourceWindow;
  853. P: PBreakpoint;
  854. Row,Col: sw_integer;
  855. begin
  856. P:=New(PBreakpoint,Init_Empty);
  857. if Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P)),nil)<>cmCancel then
  858. begin
  859. BreakpointCollection^.Insert(P);
  860. BreakpointCollection^.Update;
  861. end
  862. else
  863. dispose(P,Done);
  864. end;
  865. procedure TBreakpointListBox.Draw;
  866. var
  867. I, J, Item: Sw_Integer;
  868. NormalColor, SelectedColor, FocusedColor, Color: Word;
  869. ColWidth, CurCol, Indent: Integer;
  870. B: TDrawBuffer;
  871. Text: String;
  872. SCOff: Byte;
  873. TC: byte;
  874. procedure MT(var C: word); begin if TC<>0 then C:=(C and $ff0f) or (TC and $f0); end;
  875. begin
  876. if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
  877. if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
  878. begin
  879. NormalColor := GetColor(1);
  880. FocusedColor := GetColor(3);
  881. SelectedColor := GetColor(4);
  882. end else
  883. begin
  884. NormalColor := GetColor(2);
  885. SelectedColor := GetColor(4);
  886. end;
  887. if Transparent then
  888. begin MT(NormalColor); MT(SelectedColor); end;
  889. if NoSelection then
  890. SelectedColor:=NormalColor;
  891. if HScrollBar <> nil then Indent := HScrollBar^.Value
  892. else Indent := 0;
  893. ColWidth := Size.X div NumCols + 1;
  894. for I := 0 to Size.Y - 1 do
  895. begin
  896. for J := 0 to NumCols-1 do
  897. begin
  898. Item := J*Size.Y + I + TopItem;
  899. CurCol := J*ColWidth;
  900. if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
  901. (Focused = Item) and (Range > 0) then
  902. begin
  903. Color := FocusedColor;
  904. SetCursor(CurCol+1,I);
  905. SCOff := 0;
  906. end
  907. else if (Item < Range) and IsSelected(Item) then
  908. begin
  909. Color := SelectedColor;
  910. SCOff := 2;
  911. end
  912. else
  913. begin
  914. Color := NormalColor;
  915. SCOff := 4;
  916. end;
  917. MoveChar(B[CurCol], ' ', Color, ColWidth);
  918. if Item < Range then
  919. begin
  920. Text := GetText(Item, ColWidth + Indent);
  921. Text := Copy(Text,Indent,ColWidth);
  922. MoveStr(B[CurCol+1], Text, Color);
  923. if ShowMarkers then
  924. begin
  925. WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
  926. WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
  927. end;
  928. end;
  929. MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
  930. end;
  931. WriteLine(0, I, Size.X, 1, B);
  932. end;
  933. end;
  934. (* constructor TBreakpointListBox.Load(var S: TStream);
  935. begin
  936. inherited Load(S);
  937. end;
  938. procedure TBreakpointListBox.Store(var S: TStream);
  939. var OL: PCollection;
  940. begin
  941. OL:=List;
  942. New(List, Init(1,1));
  943. inherited Store(S);
  944. Dispose(List, Done);
  945. List:=OL;
  946. { ^^^ nasty trick - has anyone a better idea how to avoid storing the
  947. collection? Pasting here a modified version of TListBox.Store+
  948. TAdvancedListBox.Store isn't a better solution, since by eventually
  949. changing the obj-hierarchy you'll always have to modify this, too - BG }
  950. end; *)
  951. destructor TBreakpointListBox.Done;
  952. begin
  953. inherited Done;
  954. if List<>nil then Dispose(List, Done);
  955. (* if ModuleNames<>nil then Dispose(ModuleNames, Done);*)
  956. end;
  957. {****************************************************************************
  958. TBreakpointsWindow
  959. ****************************************************************************}
  960. constructor TBreakpointsWindow.Init;
  961. var R,R2: TRect;
  962. HSB,VSB: PScrollBar;
  963. ST: PStaticText;
  964. S: String;
  965. W,H : Sw_integer;
  966. X : Sw_integer;
  967. X1,X2,X3: Sw_integer;
  968. const White = 15;
  969. begin
  970. Desktop^.GetExtent(R); R.A.Y:=R.B.Y-18;
  971. inherited Init(R, 'Breakpoint list', wnNoNumber);
  972. HelpCtx:=hcBreakpointListWindow;
  973. GetExtent(R); R.Grow(-1,-1); R.B.Y:=R.A.Y+1;
  974. S:=' Type | State | Position | Ignore | Conditions ';
  975. New(ST, Init(R,S));
  976. ST^.GrowMode:=gfGrowHiX;
  977. Insert(ST);
  978. GetExtent(R); R.Grow(-1,-1); Inc(R.A.Y,1); R.B.Y:=R.A.Y+1;
  979. New(ST, Init(R, CharStr('Ä', MaxViewWidth)));
  980. ST^.GrowMode:=gfGrowHiX;
  981. Insert(ST);
  982. GetExtent(R); R.Grow(-1,-1); Inc(R.A.Y,2);Dec(R.B.Y,5);
  983. R2.Copy(R); Inc(R2.B.Y); R2.A.Y:=R2.B.Y-1;
  984. New(HSB, Init(R2)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX; Insert(HSB);
  985. R2.Copy(R); Inc(R2.B.X); R2.A.X:=R2.B.X-1;
  986. New(VSB, Init(R2)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY; Insert(VSB);
  987. New(BreakLB, Init(R,HSB,VSB));
  988. BreakLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  989. BreakLB^.Transparent:=true;
  990. Insert(BreakLB);
  991. GetExtent(R);R.Grow(-1,-1);
  992. Dec(R.B.Y);
  993. R.A.Y:=R.B.Y-2;
  994. X:=(R.B.X-R.A.X) div 4;
  995. X1:=R.A.X+(X div 2);
  996. R.A.X:=X1-3;R.B.X:=X1+7;
  997. Insert(New(PButton, Init(R, '~C~lose', cmClose, bfDefault)));
  998. X1:=X1+X;
  999. R.A.X:=X1-3;R.B.X:=X1+7;
  1000. Insert(New(PButton, Init(R, '~N~ew', cmNew, bfNormal)));
  1001. X1:=X1+X;
  1002. R.A.X:=X1-3;R.B.X:=X1+7;
  1003. Insert(New(PButton, Init(R, '~E~dit', cmEdit, bfNormal)));
  1004. X1:=X1+X;
  1005. R.A.X:=X1-3;R.B.X:=X1+7;
  1006. Insert(New(PButton, Init(R, '~D~elete', cmDelete, bfNormal)));
  1007. BreakLB^.Select;
  1008. Update;
  1009. BreakpointsWindow:=@self;
  1010. end;
  1011. procedure TBreakpointsWindow.AddBreakpoint(ABreakpoint : PBreakpoint);
  1012. begin
  1013. BreakLB^.AddBreakpoint(New(PBreakpointItem, Init(ABreakpoint)));
  1014. end;
  1015. procedure TBreakpointsWindow.ClearBreakpoints;
  1016. begin
  1017. BreakLB^.Clear;
  1018. ReDraw;
  1019. end;
  1020. procedure TBreakpointsWindow.ReloadBreakpoints;
  1021. procedure InsertInBreakLB(P : PBreakpoint);
  1022. begin
  1023. BreakLB^.AddBreakpoint(New(PBreakpointItem, Init(P)));
  1024. end;
  1025. begin
  1026. If not assigned(BreakpointCollection) then
  1027. exit;
  1028. BreakpointCollection^.ForEach(@InsertInBreakLB);
  1029. ReDraw;
  1030. end;
  1031. procedure TBreakpointsWindow.SizeLimits(var Min, Max: TPoint);
  1032. begin
  1033. inherited SizeLimits(Min,Max);
  1034. Min.X:=40; Min.Y:=18;
  1035. end;
  1036. procedure TBreakpointsWindow.Close;
  1037. begin
  1038. Hide;
  1039. end;
  1040. procedure TBreakpointsWindow.HandleEvent(var Event: TEvent);
  1041. var DontClear : boolean;
  1042. begin
  1043. case Event.What of
  1044. evCommand :
  1045. begin
  1046. DontClear:=False;
  1047. case Event.Command of
  1048. cmNew :
  1049. BreakLB^.EditNew;
  1050. cmEdit :
  1051. BreakLB^.EditCurrent;
  1052. cmDelete :
  1053. BreakLB^.DeleteCurrent;
  1054. cmClose :
  1055. Hide;
  1056. else
  1057. DontClear:=true;
  1058. end;
  1059. if not DontClear then
  1060. ClearEvent(Event);
  1061. end;
  1062. evBroadcast :
  1063. case Event.Command of
  1064. cmUpdate :
  1065. Update;
  1066. end;
  1067. end;
  1068. inherited HandleEvent(Event);
  1069. end;
  1070. procedure TBreakpointsWindow.Update;
  1071. begin
  1072. ClearBreakpoints;
  1073. ReloadBreakpoints;
  1074. end;
  1075. destructor TBreakpointsWindow.Done;
  1076. begin
  1077. inherited Done;
  1078. BreakpointsWindow:=nil;
  1079. end;
  1080. {****************************************************************************
  1081. TBreakpointItemDialog
  1082. ****************************************************************************}
  1083. constructor TBreakpointItemDialog.Init(ABreakpoint: PBreakpoint);
  1084. var R,R2,R3: TRect;
  1085. Items: PSItem;
  1086. I : BreakpointType;
  1087. KeyCount: sw_integer;
  1088. begin
  1089. KeyCount:=longint(high(BreakpointType));
  1090. R.Assign(0,0,60,Max(3+KeyCount,18));
  1091. inherited Init(R,'Modify/New Breakpoint');
  1092. Breakpoint:=ABreakpoint;
  1093. GetExtent(R); R.Grow(-3,-2); R3.Copy(R);
  1094. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+36;
  1095. New(NameIL, Init(R, 128)); Insert(NameIL);
  1096. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, '~N~ame', NameIL)));
  1097. R.Move(0,3);
  1098. New(LineIL, Init(R, 128)); Insert(LineIL);
  1099. LineIL^.SetValidator(New(PRangeValidator, Init(0,MaxInt)));
  1100. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, '~L~ine', LineIL)));
  1101. R.Move(0,3);
  1102. New(ConditionsIL, Init(R, 128)); Insert(ConditionsIL);
  1103. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, 'Conditions', ConditionsIL)));
  1104. R.Move(0,3);
  1105. New(IgnoreIL, Init(R, 128)); Insert(IgnoreIL);
  1106. IgnoreIL^.SetValidator(New(PRangeValidator, Init(0,MaxInt)));
  1107. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, '~I~gnore count', IgnoreIL)));
  1108. R.Copy(R3); Inc(R.A.X,38); R.B.Y:=R.A.Y+KeyCount;
  1109. Items:=nil;
  1110. for I:=high(BreakpointType) downto low(BreakpointType) do
  1111. Items:=NewSItem(BreakpointTypeStr[I], Items);
  1112. New(TypeRB, Init(R, Items));
  1113. Insert(TypeRB);
  1114. InsertButtons(@Self);
  1115. NameIL^.Select;
  1116. end;
  1117. function TBreakpointItemDialog.Execute: Word;
  1118. var R: word;
  1119. S1: string;
  1120. err: word;
  1121. L: longint;
  1122. begin
  1123. R:=longint(Breakpoint^.typ);
  1124. TypeRB^.SetData(R);
  1125. If Breakpoint^.typ=bt_file_line then
  1126. S1:=GetStr(Breakpoint^.FileName)
  1127. else
  1128. S1:=GetStr(Breakpoint^.name);
  1129. NameIL^.SetData(S1);
  1130. If Breakpoint^.typ=bt_file_line then
  1131. S1:=IntToStr(Breakpoint^.Line)
  1132. else
  1133. S1:='0';
  1134. LineIL^.SetData(S1);
  1135. S1:=IntToStr(Breakpoint^.IgnoreCount);
  1136. IgnoreIL^.SetData(S1);
  1137. S1:=GetStr(Breakpoint^.Conditions);
  1138. ConditionsIL^.SetData(S1);
  1139. R:=inherited Execute;
  1140. if R=cmOK then
  1141. begin
  1142. TypeRB^.GetData(R);
  1143. L:=R;
  1144. Breakpoint^.typ:=BreakpointType(L);
  1145. NameIL^.GetData(S1);
  1146. If Breakpoint^.typ=bt_file_line then
  1147. begin
  1148. If assigned(Breakpoint^.FileName) then
  1149. DisposeStr(Breakpoint^.FileName);
  1150. Breakpoint^.FileName:=NewStr(S1);
  1151. end
  1152. else
  1153. begin
  1154. If assigned(Breakpoint^.Name) then
  1155. DisposeStr(Breakpoint^.Name);
  1156. Breakpoint^.name:=NewStr(S1);
  1157. end;
  1158. If Breakpoint^.typ=bt_file_line then
  1159. begin
  1160. LineIL^.GetData(S1);
  1161. Val(S1,L,err);
  1162. Breakpoint^.Line:=L;
  1163. end;
  1164. IgnoreIL^.GetData(S1);
  1165. Val(S1,L,err);
  1166. Breakpoint^.IgnoreCount:=L;
  1167. ConditionsIL^.GetData(S1);
  1168. If assigned(Breakpoint^.Conditions) then
  1169. DisposeStr(Breakpoint^.Conditions);
  1170. Breakpoint^.Conditions:=NewStr(S1);
  1171. end;
  1172. Execute:=R;
  1173. end;
  1174. {****************************************************************************
  1175. Init/Final
  1176. ****************************************************************************}
  1177. procedure InitDebugger;
  1178. begin
  1179. {$ifdef DEBUG}
  1180. Assign(gdb_file,'gdb$$$.out');
  1181. Rewrite(gdb_file);
  1182. Use_gdb_file:=true;
  1183. {$endif}
  1184. if (not ExistsFile(ExeFile)) or (CompilationPhase<>cpDone) then
  1185. DoCompile(cRun);
  1186. if CompilationPhase<>cpDone then
  1187. Exit;
  1188. if (EXEFile='') then
  1189. begin
  1190. ErrorBox('Oooops, nothing to debug.',nil);
  1191. Exit;
  1192. end;
  1193. { init debugcontroller }
  1194. if assigned(Debugger) then
  1195. dispose(Debugger,Done);
  1196. new(Debugger,Init(ExeFile));
  1197. {$ifdef GDBWINDOW}
  1198. InitGDBWindow;
  1199. {$endif def GDBWINDOW}
  1200. end;
  1201. procedure DoneDebugger;
  1202. begin
  1203. if assigned(Debugger) then
  1204. dispose(Debugger,Done);
  1205. Debugger:=nil;
  1206. {$ifdef DEBUG}
  1207. If Use_gdb_file then
  1208. Close(GDB_file);
  1209. Use_gdb_file:=false;
  1210. {$endif}
  1211. {DoneGDBWindow;}
  1212. end;
  1213. procedure InitGDBWindow;
  1214. var
  1215. R : TRect;
  1216. begin
  1217. if GDBWindow=nil then
  1218. begin
  1219. DeskTop^.GetExtent(R);
  1220. new(GDBWindow,init(R));
  1221. DeskTop^.Insert(GDBWindow);
  1222. end;
  1223. end;
  1224. procedure DoneGDBWindow;
  1225. begin
  1226. if assigned(GDBWindow) then
  1227. begin
  1228. DeskTop^.Delete(GDBWindow);
  1229. GDBWindow:=nil;
  1230. end;
  1231. end;
  1232. procedure InitBreakpoints;
  1233. begin
  1234. New(BreakpointCollection,init(10,10));
  1235. end;
  1236. procedure DoneBreakpoints;
  1237. begin
  1238. Dispose(BreakpointCollection,Done);
  1239. BreakpointCollection:=nil;
  1240. end;
  1241. end.
  1242. {
  1243. $Log$
  1244. Revision 1.19 1999-06-30 23:58:12 pierre
  1245. + BreakpointsList Window implemented
  1246. with Edit/New/Delete functions
  1247. + Individual breakpoint dialog with support for all types
  1248. ignorecount and conditions
  1249. (commands are not yet implemented, don't know if this wolud be useful)
  1250. awatch and rwatch have problems because GDB does not annotate them
  1251. I fixed v4.16 for this
  1252. Revision 1.18 1999/03/16 00:44:42 peter
  1253. * forgotten in last commit :(
  1254. Revision 1.17 1999/03/02 13:48:28 peter
  1255. * fixed far problem is fpdebug
  1256. * tile/cascading with message window
  1257. * grep fixes
  1258. Revision 1.16 1999/03/01 15:41:52 peter
  1259. + Added dummy entries for functions not yet implemented
  1260. * MenuBar didn't update itself automatically on command-set changes
  1261. * Fixed Debugging/Profiling options dialog
  1262. * TCodeEditor converts spaces to tabs at save only if efUseTabChars is
  1263. set
  1264. * efBackSpaceUnindents works correctly
  1265. + 'Messages' window implemented
  1266. + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
  1267. + Added TP message-filter support (for ex. you can call GREP thru
  1268. GREP2MSG and view the result in the messages window - just like in TP)
  1269. * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
  1270. so topic search didn't work...
  1271. * In FPHELP.PAS there were still context-variables defined as word instead
  1272. of THelpCtx
  1273. * StdStatusKeys() was missing from the statusdef for help windows
  1274. + Topic-title for index-table can be specified when adding a HTML-files
  1275. Revision 1.15 1999/02/20 15:18:29 peter
  1276. + ctrl-c capture with confirm dialog
  1277. + ascii table in the tools menu
  1278. + heapviewer
  1279. * empty file fixed
  1280. * fixed callback routines in fpdebug to have far for tp7
  1281. Revision 1.14 1999/02/16 12:47:36 pierre
  1282. * GDBWindow does not popup on F7 or F8 anymore
  1283. Revision 1.13 1999/02/16 10:43:54 peter
  1284. * use -dGDB for the compiler
  1285. * only use gdb_file when -dDEBUG is used
  1286. * profiler switch is now a toggle instead of radiobutton
  1287. Revision 1.12 1999/02/11 19:07:20 pierre
  1288. * GDBWindow redesigned :
  1289. normal editor apart from
  1290. that any kbEnter will send the line (for begin to cursor)
  1291. to GDB command !
  1292. GDBWindow opened in Debugger Menu
  1293. still buggy :
  1294. -echo should not be present if at end of text
  1295. -GDBWindow becomes First after each step (I don't know why !)
  1296. Revision 1.11 1999/02/11 13:10:03 pierre
  1297. + GDBWindow only with -dGDBWindow for now : still buggy !!
  1298. Revision 1.10 1999/02/10 09:55:07 pierre
  1299. + added OldValue and CurrentValue field for watchpoints
  1300. + InitBreakpoints and DoneBreakpoints
  1301. + MessageBox if GDB stops bacause of a watchpoint !
  1302. Revision 1.9 1999/02/08 17:43:43 pierre
  1303. * RestDebugger or multiple running of debugged program now works
  1304. + added DoContToCursor(F4)
  1305. * Breakpoints are now inserted correctly (was mainlyy a problem
  1306. of directories)
  1307. Revision 1.8 1999/02/05 17:21:52 pierre
  1308. Invalid_line renamed InvalidSourceLine
  1309. Revision 1.7 1999/02/05 13:08:41 pierre
  1310. + new breakpoint types added
  1311. Revision 1.6 1999/02/05 12:11:53 pierre
  1312. + SourceDir that stores directories for sources that the
  1313. compiler should not know about
  1314. Automatically asked for addition when a new file that
  1315. needed filedialog to be found is in an unknown directory
  1316. Stored and retrieved from INIFile
  1317. + Breakpoints conditions added to INIFile
  1318. * Breakpoints insterted and removed at debin and end of debug session
  1319. Revision 1.5 1999/02/04 17:54:22 pierre
  1320. + several commands added
  1321. Revision 1.4 1999/02/04 13:32:02 pierre
  1322. * Several things added (I cannot commit them independently !)
  1323. + added TBreakpoint and TBreakpointCollection
  1324. + added cmResetDebugger,cmGrep,CmToggleBreakpoint
  1325. + Breakpoint list in INIFile
  1326. * Select items now also depend of SwitchMode
  1327. * Reading of option '-g' was not possible !
  1328. + added search for -Fu args pathes in TryToOpen
  1329. + added code for automatic opening of FileDialog
  1330. if source not found
  1331. Revision 1.3 1999/02/02 16:41:38 peter
  1332. + automatic .pas/.pp adding by opening of file
  1333. * better debuggerscreen changes
  1334. Revision 1.2 1999/01/22 18:14:09 pierre
  1335. * adaptd to changes in gdbint and gdbcon for to /
  1336. Revision 1.1 1999/01/22 10:24:03 peter
  1337. * first debugger things
  1338. }