fpdebug.pas 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041
  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 ReadWatches;
  36. procedure ResetBreakpointsValues;
  37. procedure DoDebuggerScreen;virtual;
  38. procedure DoUserScreen;virtual;
  39. procedure Reset;virtual;
  40. procedure Run;virtual;
  41. procedure Continue;virtual;
  42. procedure CommandBegin(const s:string);virtual;
  43. procedure CommandEnd(const s:string);virtual;
  44. end;
  45. BreakpointType = (bt_function,bt_file_line,bt_watch,bt_awatch,bt_rwatch,bt_invalid);
  46. BreakpointState = (bs_enabled,bs_disabled,bs_deleted);
  47. PBreakpointCollection=^TBreakpointCollection;
  48. PBreakpoint=^TBreakpoint;
  49. TBreakpoint=object(TObject)
  50. typ : BreakpointType;
  51. state : BreakpointState;
  52. owner : PBreakpointCollection;
  53. Name : PString; { either function name or expr to watch }
  54. FileName : PString;
  55. OldValue,CurrentValue : Pstring;
  56. Line : Longint; { only used for bt_file_line type }
  57. Conditions : PString; { conditions relative to that breakpoint }
  58. IgnoreCount : Longint; { how many counts should be ignored }
  59. Commands : pchar; { commands that should be executed on breakpoint }
  60. GDBIndex : longint;
  61. GDBState : BreakpointState;
  62. constructor Init_function(Const AFunc : String);
  63. constructor Init_Empty;
  64. constructor Init_file_line(AFile : String; ALine : longint);
  65. constructor Init_type(atyp : BreakpointType;Const AnExpr : String);
  66. procedure Insert;
  67. procedure Remove;
  68. procedure Enable;
  69. procedure Disable;
  70. procedure ResetValues;
  71. destructor Done;virtual;
  72. end;
  73. TBreakpointCollection=object(TCollection)
  74. function At(Index: Integer): PBreakpoint;
  75. function GetGDB(index : longint) : PBreakpoint;
  76. function GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
  77. function ToggleFileLine(Const FileName: String;LineNr : Longint) : boolean;
  78. procedure Update;
  79. procedure ShowBreakpoints(W : PSourceWindow);
  80. end;
  81. PBreakpointItem = ^TBreakpointItem;
  82. TBreakpointItem = object(TObject)
  83. Breakpoint : PBreakpoint;
  84. constructor Init(ABreakpoint : PBreakpoint);
  85. function GetText(MaxLen: Sw_integer): string; virtual;
  86. procedure Selected; virtual;
  87. function GetModuleName: string; virtual;
  88. end;
  89. PBreakpointListBox = ^TBreakpointListBox;
  90. TBreakpointListBox = object(THSListBox)
  91. Transparent : boolean;
  92. NoSelection : boolean;
  93. MaxWidth : Sw_integer;
  94. (* ModuleNames : PStoreCollection; *)
  95. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  96. procedure AddBreakpoint(P: PBreakpointItem); virtual;
  97. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  98. function GetLocalMenu: PMenu;virtual;
  99. procedure Clear; virtual;
  100. procedure TrackSource; virtual;
  101. procedure EditNew; virtual;
  102. procedure EditCurrent; virtual;
  103. procedure DeleteCurrent; virtual;
  104. procedure ToggleCurrent;
  105. procedure Draw; virtual;
  106. procedure HandleEvent(var Event: TEvent); virtual;
  107. (* constructor Load(var S: TStream);
  108. procedure Store(var S: TStream); *)
  109. destructor Done; virtual;
  110. end;
  111. PBreakpointsWindow = ^TBreakpointsWindow;
  112. TBreakpointsWindow = object(TDlgWindow)
  113. BreakLB : PBreakpointListBox;
  114. constructor Init;
  115. procedure AddBreakpoint(ABreakpoint : PBreakpoint);
  116. procedure ClearBreakpoints;
  117. procedure ReloadBreakpoints;
  118. procedure Close; virtual;
  119. procedure SizeLimits(var Min, Max: TPoint);virtual;
  120. procedure HandleEvent(var Event: TEvent); virtual;
  121. procedure Update; virtual;
  122. destructor Done; virtual;
  123. end;
  124. PBreakpointItemDialog = ^TBreakpointItemDialog;
  125. TBreakpointItemDialog = object(TCenterDialog)
  126. constructor Init(ABreakpoint: PBreakpoint);
  127. function Execute: Word; virtual;
  128. private
  129. Breakpoint : PBreakpoint;
  130. TypeRB : PRadioButtons;
  131. NameIL : PInputLine;
  132. ConditionsIL: PInputLine;
  133. LineIL : PInputLine;
  134. IgnoreIL : PInputLine;
  135. end;
  136. PWatch = ^TWatch;
  137. TWatch = Object(TObject)
  138. constructor Init(s : string);
  139. procedure rename(s : string);
  140. procedure Get_new_value;
  141. destructor done;virtual;
  142. private
  143. expr : pstring;
  144. last_value,current_value : pchar;
  145. end;
  146. PWatchesCollection = ^TWatchesCollection;
  147. TWatchesCollection = Object(TCollection)
  148. constructor Init;
  149. procedure Insert(Item: Pointer); virtual;
  150. function At(Index: Integer): PWatch;
  151. procedure Update;
  152. private
  153. MaxW : integer;
  154. end;
  155. PWatchesListBox = ^TWatchesListBox;
  156. TWatchesListBox = object(THSListBox)
  157. Transparent : boolean;
  158. MaxWidth : Sw_integer;
  159. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  160. (* procedure AddWatch(P: PWatch); virtual; *)
  161. procedure Update(AMaxWidth : integer);
  162. function GetIndentedText(Item,Indent,MaxLen: Sw_Integer): String; virtual;
  163. function GetLocalMenu: PMenu;virtual;
  164. (* procedure Clear; virtual;
  165. procedure TrackSource; virtual;*)
  166. procedure EditNew; virtual;
  167. procedure EditCurrent; virtual;
  168. procedure DeleteCurrent; virtual;
  169. (*procedure ToggleCurrent; *)
  170. procedure Draw; virtual;
  171. procedure HandleEvent(var Event: TEvent); virtual;
  172. (* constructor Load(var S: TStream);
  173. procedure Store(var S: TStream); *)
  174. destructor Done; virtual;
  175. end;
  176. PWatchItemDialog = ^TWatchItemDialog;
  177. TWatchItemDialog = object(TCenterDialog)
  178. constructor Init(AWatch: PWatch);
  179. function Execute: Word; virtual;
  180. private
  181. Watch : PWatch;
  182. NameIL : PInputLine;
  183. TextST : PAdvancedStaticText;
  184. end;
  185. PWatchesWindow = ^TWatchesWindow;
  186. TWatchesWindow = Object(TDlgWindow)
  187. WLB : PWatchesListBox;
  188. Constructor Init;
  189. procedure Update; virtual;
  190. destructor Done; virtual;
  191. end;
  192. const
  193. BreakpointTypeStr : Array[BreakpointType] of String[9]
  194. = ( 'function','file-line','watch','awatch','rwatch','invalid' );
  195. BreakpointStateStr : Array[BreakpointState] of String[8]
  196. = ( 'enabled','disabled','invalid' );
  197. var
  198. Debugger : PDebugController;
  199. BreakpointCollection : PBreakpointCollection;
  200. WatchesCollection : PwatchesCollection;
  201. procedure InitDebugger;
  202. procedure DoneDebugger;
  203. procedure InitGDBWindow;
  204. procedure DoneGDBWindow;
  205. procedure InitBreakpoints;
  206. procedure DoneBreakpoints;
  207. procedure InitWatches;
  208. procedure DoneWatches;
  209. implementation
  210. uses
  211. Dos,Mouse,Video,
  212. App,Commands,Strings,
  213. FPVars,FPUtils,FPConst,
  214. FPIntf,FPCompile,FPIde,
  215. Validate,WEditor,WUtils;
  216. {****************************************************************************
  217. TDebugController
  218. ****************************************************************************}
  219. constructor TDebugController.Init(const exefn:string);
  220. var f: string;
  221. begin
  222. inherited Init;
  223. f := exefn;
  224. LoadFile(f);
  225. SetArgs(GetRunParameters);
  226. Debugger:=@self;
  227. InsertBreakpoints;
  228. ReadWatches;
  229. end;
  230. procedure TDebugController.InsertBreakpoints;
  231. procedure DoInsert(PB : PBreakpoint);
  232. begin
  233. PB^.Insert;
  234. end;
  235. begin
  236. BreakpointCollection^.ForEach(@DoInsert);
  237. end;
  238. procedure TDebugController.ReadWatches;
  239. procedure DoRead(PB : PWatch);
  240. begin
  241. PB^.Get_new_value;
  242. end;
  243. begin
  244. WatchesCollection^.ForEach(@DoRead);
  245. end;
  246. procedure TDebugController.RemoveBreakpoints;
  247. procedure DoDelete(PB : PBreakpoint);
  248. begin
  249. PB^.Remove;
  250. end;
  251. begin
  252. BreakpointCollection^.ForEach(@DoDelete);
  253. end;
  254. procedure TDebugController.ResetBreakpointsValues;
  255. procedure DoResetVal(PB : PBreakpoint);
  256. begin
  257. PB^.ResetValues;
  258. end;
  259. begin
  260. BreakpointCollection^.ForEach(@DoResetVal);
  261. end;
  262. destructor TDebugController.Done;
  263. begin
  264. { kill the program if running }
  265. Reset;
  266. RemoveBreakpoints;
  267. inherited Done;
  268. end;
  269. procedure TDebugController.Run;
  270. begin
  271. ResetBreakpointsValues;
  272. inherited Run;
  273. MyApp.SetCmdState([cmResetDebugger],true);
  274. end;
  275. procedure TDebugController.Continue;
  276. begin
  277. if not debugger_started then
  278. Run
  279. else
  280. inherited Continue;
  281. end;
  282. procedure TDebugController.CommandBegin(const s:string);
  283. begin
  284. if assigned(GDBWindow) and (in_command>1) then
  285. begin
  286. { We should do something special for errors !! }
  287. If StrLen(GetError)>0 then
  288. GDBWindow^.WriteErrorText(GetError);
  289. GDBWindow^.WriteOutputText(GetOutput);
  290. end;
  291. if assigned(GDBWindow) then
  292. GDBWindow^.WriteString(S);
  293. end;
  294. procedure TDebugController.CommandEnd(const s:string);
  295. begin
  296. if assigned(GDBWindow) and (in_command=0) then
  297. begin
  298. { We should do something special for errors !! }
  299. If StrLen(GetError)>0 then
  300. GDBWindow^.WriteErrorText(GetError);
  301. GDBWindow^.WriteOutputText(GetOutput);
  302. GDBWindow^.Editor^.TextEnd;
  303. end;
  304. end;
  305. procedure TDebugController.Reset;
  306. var
  307. W : PSourceWindow;
  308. begin
  309. inherited Reset;
  310. MyApp.SetCmdState([cmResetDebugger],false);
  311. W:=PSourceWindow(LastSource);
  312. if assigned(W) then
  313. W^.Editor^.SetHighlightRow(-1);
  314. end;
  315. procedure TDebugController.AnnotateError;
  316. var errornb : longint;
  317. begin
  318. if error then
  319. begin
  320. errornb:=error_num;
  321. ErrorBox(#3'Error within GDB'#13#3'Error code = %d',@errornb);
  322. end;
  323. end;
  324. procedure TDebugController.DoSelectSourceLine(const fn:string;line:longint);
  325. var
  326. W: PSourceWindow;
  327. Found : boolean;
  328. PB : PBreakpoint;
  329. S : String;
  330. BreakIndex : longint;
  331. begin
  332. BreakIndex:=stop_breakpoint_number;
  333. Desktop^.Lock;
  334. { 0 based line count in Editor }
  335. if Line>0 then
  336. dec(Line);
  337. if (fn=LastFileName) then
  338. begin
  339. W:=PSourceWindow(LastSource);
  340. if assigned(W) then
  341. begin
  342. W^.Editor^.SetCurPtr(0,Line);
  343. W^.Editor^.TrackCursor(true);
  344. W^.Editor^.SetHighlightRow(Line);
  345. ReadWatches;
  346. if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  347. W^.Select;
  348. InvalidSourceLine:=false;
  349. end
  350. else
  351. InvalidSourceLine:=true;
  352. end
  353. else
  354. begin
  355. W:=TryToOpenFile(nil,fn,0,Line,false);
  356. if assigned(W) then
  357. begin
  358. W^.Editor^.SetHighlightRow(Line);
  359. W^.Editor^.TrackCursor(true);
  360. ReadWatches;
  361. if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  362. W^.Select;
  363. LastSource:=W;
  364. InvalidSourceLine:=false;
  365. end
  366. { only search a file once }
  367. else
  368. begin
  369. Desktop^.UnLock;
  370. Found:=MyApp.OpenSearch(fn);
  371. Desktop^.Lock;
  372. if not Found then
  373. begin
  374. InvalidSourceLine:=true;
  375. LastSource:=Nil;
  376. end
  377. else
  378. begin
  379. { should now be open }
  380. W:=TryToOpenFile(nil,fn,0,Line,true);
  381. W^.Editor^.SetHighlightRow(Line);
  382. W^.Editor^.TrackCursor(true);
  383. ReadWatches;
  384. if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  385. W^.Select;
  386. LastSource:=W;
  387. InvalidSourceLine:=false;
  388. end;
  389. end;
  390. end;
  391. LastFileName:=fn;
  392. Desktop^.UnLock;
  393. if BreakIndex>0 then
  394. begin
  395. PB:=BreakpointCollection^.GetGDB(BreakIndex);
  396. { For watch we should get old and new value !! }
  397. if (Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive)) and
  398. (PB^.typ<>bt_file_line) and (PB^.typ<>bt_function) then
  399. begin
  400. Command('p '+GetStr(PB^.Name));
  401. S:=StrPas(GetOutput);
  402. If Pos('=',S)>0 then
  403. S:=Copy(S,Pos('=',S)+1,255);
  404. If S[Length(S)]=#10 then
  405. Delete(S,Length(S),1);
  406. if Assigned(PB^.OldValue) then
  407. DisposeStr(PB^.OldValue);
  408. PB^.OldValue:=PB^.CurrentValue;
  409. PB^.CurrentValue:=NewStr(S);
  410. If PB^.typ=bt_function then
  411. WarningBox(#3'GDB stopped due to'#13+
  412. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name),nil)
  413. else if (GetStr(PB^.OldValue)<>S) then
  414. WarningBox(#3'GDB stopped due to'#13+
  415. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
  416. #3+'Old value = '+GetStr(PB^.OldValue)+#13+
  417. #3+'New value = '+GetStr(PB^.CurrentValue),nil)
  418. else
  419. WarningBox(#3'GDB stopped due to'#13+
  420. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
  421. #3+' value = '+GetStr(PB^.CurrentValue),nil);
  422. end;
  423. end;
  424. end;
  425. procedure TDebugController.DoEndSession(code:longint);
  426. var P :Array[1..2] of longint;
  427. W : PSourceWindow;
  428. begin
  429. MyApp.SetCmdState([cmResetDebugger],false);
  430. W:=PSourceWindow(LastSource);
  431. if assigned(W) then
  432. W^.Editor^.SetHighlightRow(-1);
  433. If HiddenStepsCount=0 then
  434. InformationBox(#3'Program exited with '#13#3'exitcode = %d',@code)
  435. else
  436. begin
  437. P[1]:=code;
  438. P[2]:=HiddenStepsCount;
  439. WarningBox(#3'Program exited with '#13+
  440. #3'exitcode = %d'#13+
  441. #3'hidden steps = %d',@P);
  442. end;
  443. end;
  444. procedure TDebugController.DoDebuggerScreen;
  445. begin
  446. MyApp.ShowIDEScreen;
  447. end;
  448. procedure TDebugController.DoUserScreen;
  449. begin
  450. MyApp.ShowUserScreen;
  451. end;
  452. {****************************************************************************
  453. TBreakpoint
  454. ****************************************************************************}
  455. constructor TBreakpoint.Init_function(Const AFunc : String);
  456. begin
  457. typ:=bt_function;
  458. state:=bs_enabled;
  459. GDBState:=bs_deleted;
  460. Name:=NewStr(AFunc);
  461. FileName:=nil;
  462. Line:=0;
  463. IgnoreCount:=0;
  464. Commands:=nil;
  465. Conditions:=nil;
  466. OldValue:=nil;
  467. CurrentValue:=nil;
  468. end;
  469. constructor TBreakpoint.Init_Empty;
  470. begin
  471. typ:=bt_function;
  472. state:=bs_enabled;
  473. GDBState:=bs_deleted;
  474. Name:=Nil;
  475. FileName:=nil;
  476. Line:=0;
  477. IgnoreCount:=0;
  478. Commands:=nil;
  479. Conditions:=nil;
  480. OldValue:=nil;
  481. CurrentValue:=nil;
  482. end;
  483. constructor TBreakpoint.Init_type(atyp : BreakpointType;Const AnExpr : String);
  484. begin
  485. typ:=atyp;
  486. state:=bs_enabled;
  487. GDBState:=bs_deleted;
  488. Name:=NewStr(AnExpr);
  489. IgnoreCount:=0;
  490. Commands:=nil;
  491. Conditions:=nil;
  492. OldValue:=nil;
  493. CurrentValue:=nil;
  494. end;
  495. constructor TBreakpoint.Init_file_line(AFile : String; ALine : longint);
  496. begin
  497. typ:=bt_file_line;
  498. state:=bs_enabled;
  499. GDBState:=bs_deleted;
  500. { d:test.pas:12 does not work !! }
  501. { I do not know how to solve this if
  502. if (Length(AFile)>1) and (AFile[2]=':') then
  503. AFile:=Copy(AFile,3,255);
  504. Only use base name for now !! PM }
  505. FileName:=NewStr(AFile);
  506. Name:=nil;
  507. Line:=ALine;
  508. IgnoreCount:=0;
  509. Commands:=nil;
  510. Conditions:=nil;
  511. OldValue:=nil;
  512. CurrentValue:=nil;
  513. end;
  514. procedure TBreakpoint.Insert;
  515. begin
  516. If not assigned(Debugger) then Exit;
  517. Remove;
  518. Debugger^.last_breakpoint_number:=0;
  519. if (GDBState=bs_deleted) and (state=bs_enabled) then
  520. begin
  521. if (typ=bt_file_line) and assigned(FileName) then
  522. Debugger^.Command('break '+NameAndExtOf(FileName^)+':'+IntToStr(Line))
  523. else if (typ=bt_function) and assigned(name) then
  524. Debugger^.Command('break '+name^)
  525. else if (typ=bt_watch) and assigned(name) then
  526. Debugger^.Command('watch '+name^)
  527. else if (typ=bt_awatch) and assigned(name) then
  528. Debugger^.Command('awatch '+name^)
  529. else if (typ=bt_rwatch) and assigned(name) then
  530. Debugger^.Command('rwatch '+name^);
  531. if Debugger^.last_breakpoint_number<>0 then
  532. begin
  533. GDBIndex:=Debugger^.last_breakpoint_number;
  534. GDBState:=bs_enabled;
  535. Debugger^.Command('cond '+IntToStr(GDBIndex)+' '+GetStr(Conditions));
  536. Debugger^.Command('ignore '+IntToStr(GDBIndex)+' '+IntToStr(IgnoreCount));
  537. If Assigned(Commands) then
  538. begin
  539. {Commands are not handled yet }
  540. end;
  541. end
  542. else
  543. { Here there was a problem !! }
  544. begin
  545. GDBIndex:=0;
  546. ErrorBox(#3'Could not set Breakpoint'#13+
  547. #3+BreakpointTypeStr[typ]+' '+Name^,nil);
  548. state:=bs_disabled;
  549. end;
  550. end
  551. else if (GDBState=bs_disabled) and (state=bs_enabled) then
  552. Enable
  553. else if (GDBState=bs_enabled) and (state=bs_disabled) then
  554. Disable;
  555. end;
  556. procedure TBreakpoint.Remove;
  557. begin
  558. If not assigned(Debugger) then Exit;
  559. if GDBIndex>0 then
  560. Debugger^.Command('delete '+IntToStr(GDBIndex));
  561. GDBIndex:=0;
  562. GDBState:=bs_deleted;
  563. end;
  564. procedure TBreakpoint.Enable;
  565. begin
  566. If not assigned(Debugger) then Exit;
  567. if GDBIndex>0 then
  568. Debugger^.Command('enable '+IntToStr(GDBIndex))
  569. else
  570. Insert;
  571. GDBState:=bs_enabled;
  572. end;
  573. procedure TBreakpoint.Disable;
  574. begin
  575. If not assigned(Debugger) then Exit;
  576. if GDBIndex>0 then
  577. Debugger^.Command('disable '+IntToStr(GDBIndex));
  578. GDBState:=bs_disabled;
  579. end;
  580. procedure TBreakpoint.ResetValues;
  581. begin
  582. if assigned(OldValue) then
  583. DisposeStr(OldValue);
  584. OldValue:=nil;
  585. if assigned(CurrentValue) then
  586. DisposeStr(CurrentValue);
  587. CurrentValue:=nil;
  588. end;
  589. destructor TBreakpoint.Done;
  590. begin
  591. Remove;
  592. ResetValues;
  593. if assigned(Name) then
  594. DisposeStr(Name);
  595. if assigned(FileName) then
  596. DisposeStr(FileName);
  597. if assigned(Conditions) then
  598. DisposeStr(Conditions);
  599. if assigned(Commands) then
  600. StrDispose(Commands);
  601. inherited Done;
  602. end;
  603. {****************************************************************************
  604. TBreakpointCollection
  605. ****************************************************************************}
  606. function TBreakpointCollection.At(Index: Integer): PBreakpoint;
  607. begin
  608. At:=inherited At(Index);
  609. end;
  610. procedure TBreakpointCollection.Update;
  611. begin
  612. if assigned(Debugger) then
  613. begin
  614. Debugger^.RemoveBreakpoints;
  615. Debugger^.InsertBreakpoints;
  616. end;
  617. if assigned(BreakpointsWindow) then
  618. BreakpointsWindow^.Update;
  619. end;
  620. function TBreakpointCollection.GetGDB(index : longint) : PBreakpoint;
  621. function IsNum(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  622. begin
  623. IsNum:=P^.GDBIndex=index;
  624. end;
  625. begin
  626. if index=0 then
  627. GetGDB:=nil
  628. else
  629. GetGDB:=FirstThat(@IsNum);
  630. end;
  631. procedure TBreakpointCollection.ShowBreakpoints(W : PSourceWindow);
  632. procedure SetInSource(P : PBreakpoint);{$ifndef FPC}far;{$endif}
  633. begin
  634. If assigned(P^.FileName) and (P^.FileName^=W^.Editor^.FileName) then
  635. W^.Editor^.SetLineBreakState(P^.Line,P^.state=bs_enabled);
  636. end;
  637. begin
  638. ForEach(@SetInSource);
  639. end;
  640. function TBreakpointCollection.GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
  641. function IsThis(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  642. begin
  643. IsThis:=(P^.typ=typ) and (P^.Name^=S);
  644. end;
  645. begin
  646. GetType:=FirstThat(@IsThis);
  647. end;
  648. function TBreakpointCollection.ToggleFileLine(Const FileName: String;LineNr : Longint) : boolean;
  649. var PB : PBreakpoint;
  650. function IsThere(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  651. begin
  652. IsThere:=(P^.typ=bt_file_line) and (P^.FileName^=FileName) and (P^.Line=LineNr);
  653. end;
  654. begin
  655. PB:=FirstThat(@IsThere);
  656. ToggleFileLine:=false;
  657. If Assigned(PB) then
  658. if PB^.state=bs_disabled then
  659. begin
  660. PB^.state:=bs_enabled;
  661. ToggleFileLine:=true;
  662. end
  663. else if PB^.state=bs_enabled then
  664. PB^.state:=bs_disabled;
  665. If not assigned(PB) then
  666. begin
  667. PB:= New(PBreakpoint,Init_file_line(FileName,LineNr));
  668. if assigned(PB) then
  669. Begin
  670. Insert(PB);
  671. ToggleFileLine:=true;
  672. End;
  673. end;
  674. Update;
  675. end;
  676. {****************************************************************************
  677. TBreakpointItem
  678. ****************************************************************************}
  679. constructor TBreakpointItem.Init(ABreakpoint : PBreakpoint);
  680. begin
  681. inherited Init;
  682. Breakpoint:=ABreakpoint;
  683. end;
  684. function TBreakpointItem.GetText(MaxLen: Sw_integer): string;
  685. var S: string;
  686. begin
  687. with Breakpoint^ do
  688. begin
  689. S:=BreakpointTypeStr[typ];
  690. While Length(S)<10 do
  691. S:=S+' ';
  692. S:=S+'|';
  693. S:=S+BreakpointStateStr[state]+' ';
  694. While Length(S)<20 do
  695. S:=S+' ';
  696. S:=S+'|';
  697. if (typ=bt_file_line) then
  698. S:=S+NameAndExtOf(GetStr(FileName))+':'+IntToStr(Line)
  699. else
  700. S:=S+GetStr(name);
  701. While Length(S)<40 do
  702. S:=S+' ';
  703. S:=S+'|';
  704. if IgnoreCount>0 then
  705. S:=S+IntToStr(IgnoreCount);
  706. While Length(S)<49 do
  707. S:=S+' ';
  708. S:=S+'|';
  709. if assigned(Conditions) then
  710. S:=S+' '+GetStr(Conditions);
  711. if length(S)>MaxLen then S:=copy(S,1,MaxLen-2)+'..';
  712. GetText:=S;
  713. end;
  714. end;
  715. procedure TBreakpointItem.Selected;
  716. begin
  717. end;
  718. function TBreakpointItem.GetModuleName: string;
  719. begin
  720. if breakpoint^.typ=bt_file_line then
  721. GetModuleName:=GetStr(breakpoint^.FileName)
  722. else
  723. GetModuleName:='';
  724. end;
  725. {****************************************************************************
  726. TBreakpointListBox
  727. ****************************************************************************}
  728. constructor TBreakpointListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  729. begin
  730. inherited Init(Bounds,1,AHScrollBar, AVScrollBar);
  731. GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  732. NoSelection:=true;
  733. end;
  734. function TBreakpointListBox.GetLocalMenu: PMenu;
  735. var M: PMenu;
  736. begin
  737. if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
  738. M:=NewMenu(
  739. NewItem('~G~oto source','',kbNoKey,cmMsgGotoSource,hcMsgGotoSource,
  740. NewItem('~E~dit breakpoint','',kbNoKey,cmEdit,hcNoContext,
  741. NewItem('~N~ew breakpoint','',kbNoKey,cmNew,hcNoContext,
  742. NewItem('~D~elete breakpoint','',kbNoKey,cmDelete,hcNoContext,
  743. NewItem('~T~oggle state','',kbNoKey,cmToggleBreakpoint,hcNoContext,
  744. nil))))));
  745. GetLocalMenu:=M;
  746. end;
  747. procedure TBreakpointListBox.HandleEvent(var Event: TEvent);
  748. var DontClear: boolean;
  749. begin
  750. case Event.What of
  751. evKeyDown :
  752. begin
  753. DontClear:=false;
  754. case Event.KeyCode of
  755. kbEnter :
  756. Message(@Self,evCommand,cmMsgGotoSource,nil);
  757. else
  758. DontClear:=true;
  759. end;
  760. if not DontClear then
  761. ClearEvent(Event);
  762. end;
  763. evBroadcast :
  764. case Event.Command of
  765. cmListItemSelected :
  766. if Event.InfoPtr=@Self then
  767. Message(@Self,evCommand,cmEdit,nil);
  768. end;
  769. evCommand :
  770. begin
  771. DontClear:=false;
  772. case Event.Command of
  773. cmMsgTrackSource :
  774. if Range>0 then
  775. TrackSource;
  776. cmEdit :
  777. EditCurrent;
  778. cmToggleBreakpoint :
  779. ToggleCurrent;
  780. cmDelete :
  781. DeleteCurrent;
  782. cmNew :
  783. EditNew;
  784. cmMsgClear :
  785. Clear;
  786. else
  787. DontClear:=true;
  788. end;
  789. if not DontClear then
  790. ClearEvent(Event);
  791. end;
  792. end;
  793. inherited HandleEvent(Event);
  794. end;
  795. procedure TBreakpointListBox.AddBreakpoint(P: PBreakpointItem);
  796. var W : integer;
  797. begin
  798. if List=nil then New(List, Init(20,20));
  799. W:=length(P^.GetText(255));
  800. if W>MaxWidth then
  801. begin
  802. MaxWidth:=W;
  803. if HScrollBar<>nil then
  804. HScrollBar^.SetRange(0,MaxWidth);
  805. end;
  806. List^.Insert(P);
  807. SetRange(List^.Count);
  808. if Focused=List^.Count-1-1 then
  809. FocusItem(List^.Count-1);
  810. DrawView;
  811. end;
  812. (* function TBreakpointListBox.AddModuleName(const Name: string): PString;
  813. var P: PString;
  814. begin
  815. if ModuleNames<>nil then
  816. P:=ModuleNames^.Add(Name)
  817. else
  818. P:=nil;
  819. AddModuleName:=P;
  820. end; *)
  821. function TBreakpointListBox.GetText(Item,MaxLen: Sw_Integer): String;
  822. var P: PBreakpointItem;
  823. S: string;
  824. begin
  825. P:=List^.At(Item);
  826. S:=P^.GetText(MaxLen);
  827. GetText:=copy(S,1,MaxLen);
  828. end;
  829. procedure TBreakpointListBox.Clear;
  830. begin
  831. if assigned(List) then
  832. Dispose(List, Done);
  833. List:=nil;
  834. MaxWidth:=0;
  835. (* if assigned(ModuleNames) then
  836. ModuleNames^.FreeAll; *)
  837. SetRange(0); DrawView;
  838. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  839. end;
  840. procedure TBreakpointListBox.TrackSource;
  841. var W: PSourceWindow;
  842. P: PBreakpointItem;
  843. R: TRect;
  844. (* Row,Col: sw_integer; *)
  845. begin
  846. (*Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  847. if Range=0 then Exit;*)
  848. P:=List^.At(Focused);
  849. if P^.GetModuleName='' then Exit;
  850. Desktop^.Lock;
  851. GetNextEditorBounds(R);
  852. R.B.Y:=Owner^.Origin.Y;
  853. W:=EditorWindowFile(P^.GetModuleName);
  854. if assigned(W) then
  855. begin
  856. W^.GetExtent(R);
  857. R.B.Y:=Owner^.Origin.Y;
  858. W^.ChangeBounds(R);
  859. W^.Editor^.SetCurPtr(1,P^.Breakpoint^.Line);
  860. end
  861. else
  862. W:=TryToOpenFile(@R,P^.GetModuleName,1,P^.Breakpoint^.Line,true);
  863. if W<>nil then
  864. begin
  865. W^.Select;
  866. W^.Editor^.TrackCursor(true);
  867. W^.Editor^.SetHighlightRow(P^.Breakpoint^.Line);
  868. end;
  869. if Assigned(Owner) then
  870. Owner^.Select;
  871. Desktop^.UnLock;
  872. end;
  873. procedure TBreakpointListBox.ToggleCurrent;
  874. var W: PSourceWindow;
  875. P: PBreakpointItem;
  876. b : boolean;
  877. (* Row,Col: sw_integer; *)
  878. begin
  879. if Range=0 then Exit;
  880. P:=List^.At(Focused);
  881. if P=nil then Exit;
  882. if P^.Breakpoint^.state=bs_enabled then
  883. P^.Breakpoint^.state:=bs_disabled
  884. else if P^.Breakpoint^.state=bs_disabled then
  885. P^.Breakpoint^.state:=bs_enabled;
  886. BreakpointCollection^.Update;
  887. if P^.Breakpoint^.typ=bt_file_line then
  888. begin
  889. W:=TryToOpenFile(nil,GetStr(P^.Breakpoint^.FileName),1,P^.Breakpoint^.Line,false);
  890. If assigned(W) then
  891. begin
  892. if P^.Breakpoint^.state=bs_enabled then
  893. b:=true
  894. else
  895. b:=false;
  896. W^.Editor^.SetLineBreakState(P^.Breakpoint^.Line,b);
  897. end;
  898. end;
  899. end;
  900. procedure TBreakpointListBox.EditCurrent;
  901. var
  902. P: PBreakpointItem;
  903. begin
  904. if Range=0 then Exit;
  905. P:=List^.At(Focused);
  906. if P=nil then Exit;
  907. Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P^.Breakpoint)),nil);
  908. BreakpointCollection^.Update;
  909. end;
  910. procedure TBreakpointListBox.DeleteCurrent;
  911. var
  912. P: PBreakpointItem;
  913. begin
  914. if Range=0 then Exit;
  915. P:=List^.At(Focused);
  916. if P=nil then Exit;
  917. BreakpointCollection^.free(P^.Breakpoint);
  918. List^.free(P);
  919. BreakpointCollection^.Update;
  920. end;
  921. procedure TBreakpointListBox.EditNew;
  922. var
  923. P: PBreakpoint;
  924. begin
  925. P:=New(PBreakpoint,Init_Empty);
  926. if Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P)),nil)<>cmCancel then
  927. begin
  928. BreakpointCollection^.Insert(P);
  929. BreakpointCollection^.Update;
  930. end
  931. else
  932. dispose(P,Done);
  933. end;
  934. procedure TBreakpointListBox.Draw;
  935. var
  936. I, J, Item: Sw_Integer;
  937. NormalColor, SelectedColor, FocusedColor, Color: Word;
  938. ColWidth, CurCol, Indent: Integer;
  939. B: TDrawBuffer;
  940. Text: String;
  941. SCOff: Byte;
  942. TC: byte;
  943. procedure MT(var C: word); begin if TC<>0 then C:=(C and $ff0f) or (TC and $f0); end;
  944. begin
  945. if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
  946. if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
  947. begin
  948. NormalColor := GetColor(1);
  949. FocusedColor := GetColor(3);
  950. SelectedColor := GetColor(4);
  951. end else
  952. begin
  953. NormalColor := GetColor(2);
  954. SelectedColor := GetColor(4);
  955. end;
  956. if Transparent then
  957. begin MT(NormalColor); MT(SelectedColor); end;
  958. if NoSelection then
  959. SelectedColor:=NormalColor;
  960. if HScrollBar <> nil then Indent := HScrollBar^.Value
  961. else Indent := 0;
  962. ColWidth := Size.X div NumCols + 1;
  963. for I := 0 to Size.Y - 1 do
  964. begin
  965. for J := 0 to NumCols-1 do
  966. begin
  967. Item := J*Size.Y + I + TopItem;
  968. CurCol := J*ColWidth;
  969. if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
  970. (Focused = Item) and (Range > 0) then
  971. begin
  972. Color := FocusedColor;
  973. SetCursor(CurCol+1,I);
  974. SCOff := 0;
  975. end
  976. else if (Item < Range) and IsSelected(Item) then
  977. begin
  978. Color := SelectedColor;
  979. SCOff := 2;
  980. end
  981. else
  982. begin
  983. Color := NormalColor;
  984. SCOff := 4;
  985. end;
  986. MoveChar(B[CurCol], ' ', Color, ColWidth);
  987. if Item < Range then
  988. begin
  989. Text := GetText(Item, ColWidth + Indent);
  990. Text := Copy(Text,Indent,ColWidth);
  991. MoveStr(B[CurCol+1], Text, Color);
  992. if ShowMarkers then
  993. begin
  994. WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
  995. WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
  996. end;
  997. end;
  998. MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
  999. end;
  1000. WriteLine(0, I, Size.X, 1, B);
  1001. end;
  1002. end;
  1003. (* constructor TBreakpointListBox.Load(var S: TStream);
  1004. begin
  1005. inherited Load(S);
  1006. end;
  1007. procedure TBreakpointListBox.Store(var S: TStream);
  1008. var OL: PCollection;
  1009. begin
  1010. OL:=List;
  1011. New(List, Init(1,1));
  1012. inherited Store(S);
  1013. Dispose(List, Done);
  1014. List:=OL;
  1015. { ^^^ nasty trick - has anyone a better idea how to avoid storing the
  1016. collection? Pasting here a modified version of TListBox.Store+
  1017. TAdvancedListBox.Store isn't a better solution, since by eventually
  1018. changing the obj-hierarchy you'll always have to modify this, too - BG }
  1019. end; *)
  1020. destructor TBreakpointListBox.Done;
  1021. begin
  1022. inherited Done;
  1023. if List<>nil then Dispose(List, Done);
  1024. (* if ModuleNames<>nil then Dispose(ModuleNames, Done);*)
  1025. end;
  1026. {****************************************************************************
  1027. TBreakpointsWindow
  1028. ****************************************************************************}
  1029. constructor TBreakpointsWindow.Init;
  1030. var R,R2: TRect;
  1031. HSB,VSB: PScrollBar;
  1032. ST: PStaticText;
  1033. S: String;
  1034. X,X1 : Sw_integer;
  1035. const White = 15;
  1036. begin
  1037. Desktop^.GetExtent(R); R.A.Y:=R.B.Y-18;
  1038. inherited Init(R, 'Breakpoint list', wnNoNumber);
  1039. HelpCtx:=hcBreakpointListWindow;
  1040. GetExtent(R); R.Grow(-1,-1); R.B.Y:=R.A.Y+1;
  1041. S:=' Type | State | Position | Ignore | Conditions ';
  1042. New(ST, Init(R,S));
  1043. ST^.GrowMode:=gfGrowHiX;
  1044. Insert(ST);
  1045. GetExtent(R); R.Grow(-1,-1); Inc(R.A.Y,1); R.B.Y:=R.A.Y+1;
  1046. New(ST, Init(R, CharStr('Ä', MaxViewWidth)));
  1047. ST^.GrowMode:=gfGrowHiX;
  1048. Insert(ST);
  1049. GetExtent(R); R.Grow(-1,-1); Inc(R.A.Y,2);Dec(R.B.Y,5);
  1050. R2.Copy(R); Inc(R2.B.Y); R2.A.Y:=R2.B.Y-1;
  1051. New(HSB, Init(R2)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX; Insert(HSB);
  1052. R2.Copy(R); Inc(R2.B.X); R2.A.X:=R2.B.X-1;
  1053. New(VSB, Init(R2)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY; Insert(VSB);
  1054. New(BreakLB, Init(R,HSB,VSB));
  1055. BreakLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  1056. BreakLB^.Transparent:=true;
  1057. Insert(BreakLB);
  1058. GetExtent(R);R.Grow(-1,-1);
  1059. Dec(R.B.Y);
  1060. R.A.Y:=R.B.Y-2;
  1061. X:=(R.B.X-R.A.X) div 4;
  1062. X1:=R.A.X+(X div 2);
  1063. R.A.X:=X1-3;R.B.X:=X1+7;
  1064. Insert(New(PButton, Init(R, '~C~lose', cmClose, bfDefault)));
  1065. X1:=X1+X;
  1066. R.A.X:=X1-3;R.B.X:=X1+7;
  1067. Insert(New(PButton, Init(R, '~N~ew', cmNew, bfNormal)));
  1068. X1:=X1+X;
  1069. R.A.X:=X1-3;R.B.X:=X1+7;
  1070. Insert(New(PButton, Init(R, '~E~dit', cmEdit, bfNormal)));
  1071. X1:=X1+X;
  1072. R.A.X:=X1-3;R.B.X:=X1+7;
  1073. Insert(New(PButton, Init(R, '~D~elete', cmDelete, bfNormal)));
  1074. BreakLB^.Select;
  1075. Update;
  1076. BreakpointsWindow:=@self;
  1077. end;
  1078. procedure TBreakpointsWindow.AddBreakpoint(ABreakpoint : PBreakpoint);
  1079. begin
  1080. BreakLB^.AddBreakpoint(New(PBreakpointItem, Init(ABreakpoint)));
  1081. end;
  1082. procedure TBreakpointsWindow.ClearBreakpoints;
  1083. begin
  1084. BreakLB^.Clear;
  1085. ReDraw;
  1086. end;
  1087. procedure TBreakpointsWindow.ReloadBreakpoints;
  1088. procedure InsertInBreakLB(P : PBreakpoint);
  1089. begin
  1090. BreakLB^.AddBreakpoint(New(PBreakpointItem, Init(P)));
  1091. end;
  1092. begin
  1093. If not assigned(BreakpointCollection) then
  1094. exit;
  1095. BreakpointCollection^.ForEach(@InsertInBreakLB);
  1096. ReDraw;
  1097. end;
  1098. procedure TBreakpointsWindow.SizeLimits(var Min, Max: TPoint);
  1099. begin
  1100. inherited SizeLimits(Min,Max);
  1101. Min.X:=40; Min.Y:=18;
  1102. end;
  1103. procedure TBreakpointsWindow.Close;
  1104. begin
  1105. Hide;
  1106. end;
  1107. procedure TBreakpointsWindow.HandleEvent(var Event: TEvent);
  1108. var DontClear : boolean;
  1109. begin
  1110. case Event.What of
  1111. evCommand :
  1112. begin
  1113. DontClear:=False;
  1114. case Event.Command of
  1115. cmNew :
  1116. BreakLB^.EditNew;
  1117. cmEdit :
  1118. BreakLB^.EditCurrent;
  1119. cmDelete :
  1120. BreakLB^.DeleteCurrent;
  1121. cmClose :
  1122. Hide;
  1123. else
  1124. DontClear:=true;
  1125. end;
  1126. if not DontClear then
  1127. ClearEvent(Event);
  1128. end;
  1129. evBroadcast :
  1130. case Event.Command of
  1131. cmUpdate :
  1132. Update;
  1133. end;
  1134. end;
  1135. inherited HandleEvent(Event);
  1136. end;
  1137. procedure TBreakpointsWindow.Update;
  1138. begin
  1139. ClearBreakpoints;
  1140. ReloadBreakpoints;
  1141. end;
  1142. destructor TBreakpointsWindow.Done;
  1143. begin
  1144. inherited Done;
  1145. BreakpointsWindow:=nil;
  1146. end;
  1147. {****************************************************************************
  1148. TBreakpointItemDialog
  1149. ****************************************************************************}
  1150. constructor TBreakpointItemDialog.Init(ABreakpoint: PBreakpoint);
  1151. var R,R2,R3: TRect;
  1152. Items: PSItem;
  1153. I : BreakpointType;
  1154. KeyCount: sw_integer;
  1155. begin
  1156. KeyCount:=longint(high(BreakpointType));
  1157. R.Assign(0,0,60,Max(3+KeyCount,18));
  1158. inherited Init(R,'Modify/New Breakpoint');
  1159. Breakpoint:=ABreakpoint;
  1160. GetExtent(R); R.Grow(-3,-2); R3.Copy(R);
  1161. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+36;
  1162. New(NameIL, Init(R, 128)); Insert(NameIL);
  1163. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, '~N~ame', NameIL)));
  1164. R.Move(0,3);
  1165. New(LineIL, Init(R, 128)); Insert(LineIL);
  1166. LineIL^.SetValidator(New(PRangeValidator, Init(0,MaxInt)));
  1167. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, '~L~ine', LineIL)));
  1168. R.Move(0,3);
  1169. New(ConditionsIL, Init(R, 128)); Insert(ConditionsIL);
  1170. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, 'Conditions', ConditionsIL)));
  1171. R.Move(0,3);
  1172. New(IgnoreIL, Init(R, 128)); Insert(IgnoreIL);
  1173. IgnoreIL^.SetValidator(New(PRangeValidator, Init(0,MaxInt)));
  1174. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, '~I~gnore count', IgnoreIL)));
  1175. R.Copy(R3); Inc(R.A.X,38); R.B.Y:=R.A.Y+KeyCount;
  1176. Items:=nil;
  1177. for I:=high(BreakpointType) downto low(BreakpointType) do
  1178. Items:=NewSItem(BreakpointTypeStr[I], Items);
  1179. New(TypeRB, Init(R, Items));
  1180. Insert(TypeRB);
  1181. InsertButtons(@Self);
  1182. NameIL^.Select;
  1183. end;
  1184. function TBreakpointItemDialog.Execute: Word;
  1185. var R: word;
  1186. S1: string;
  1187. err: word;
  1188. L: longint;
  1189. begin
  1190. R:=longint(Breakpoint^.typ);
  1191. TypeRB^.SetData(R);
  1192. If Breakpoint^.typ=bt_file_line then
  1193. S1:=GetStr(Breakpoint^.FileName)
  1194. else
  1195. S1:=GetStr(Breakpoint^.name);
  1196. NameIL^.SetData(S1);
  1197. If Breakpoint^.typ=bt_file_line then
  1198. S1:=IntToStr(Breakpoint^.Line)
  1199. else
  1200. S1:='0';
  1201. LineIL^.SetData(S1);
  1202. S1:=IntToStr(Breakpoint^.IgnoreCount);
  1203. IgnoreIL^.SetData(S1);
  1204. S1:=GetStr(Breakpoint^.Conditions);
  1205. ConditionsIL^.SetData(S1);
  1206. R:=inherited Execute;
  1207. if R=cmOK then
  1208. begin
  1209. TypeRB^.GetData(R);
  1210. L:=R;
  1211. Breakpoint^.typ:=BreakpointType(L);
  1212. NameIL^.GetData(S1);
  1213. If Breakpoint^.typ=bt_file_line then
  1214. begin
  1215. If assigned(Breakpoint^.FileName) then
  1216. DisposeStr(Breakpoint^.FileName);
  1217. Breakpoint^.FileName:=NewStr(S1);
  1218. end
  1219. else
  1220. begin
  1221. If assigned(Breakpoint^.Name) then
  1222. DisposeStr(Breakpoint^.Name);
  1223. Breakpoint^.name:=NewStr(S1);
  1224. end;
  1225. If Breakpoint^.typ=bt_file_line then
  1226. begin
  1227. LineIL^.GetData(S1);
  1228. Val(S1,L,err);
  1229. Breakpoint^.Line:=L;
  1230. end;
  1231. IgnoreIL^.GetData(S1);
  1232. Val(S1,L,err);
  1233. Breakpoint^.IgnoreCount:=L;
  1234. ConditionsIL^.GetData(S1);
  1235. If assigned(Breakpoint^.Conditions) then
  1236. DisposeStr(Breakpoint^.Conditions);
  1237. Breakpoint^.Conditions:=NewStr(S1);
  1238. end;
  1239. Execute:=R;
  1240. end;
  1241. {****************************************************************************
  1242. TWatch
  1243. ****************************************************************************}
  1244. constructor TWatch.Init(s : string);
  1245. begin
  1246. expr:=NewStr(s);
  1247. last_value:=nil;
  1248. current_value:=nil;
  1249. Get_new_value;
  1250. end;
  1251. procedure TWatch.rename(s : string);
  1252. begin
  1253. if assigned(expr) then
  1254. begin
  1255. if GetStr(expr)=S then
  1256. exit;
  1257. DisposeStr(expr);
  1258. end;
  1259. expr:=NewStr(s);
  1260. if assigned(last_value) then
  1261. StrDispose(last_value);
  1262. last_value:=nil;
  1263. if assigned(current_value) then
  1264. StrDispose(current_value);
  1265. current_value:=nil;
  1266. Get_new_value;
  1267. end;
  1268. procedure TWatch.Get_new_value;
  1269. var p,q : pchar;
  1270. i : longint;
  1271. last_removed : boolean;
  1272. begin
  1273. If not assigned(Debugger) then
  1274. exit;
  1275. if assigned(last_value) then
  1276. strdispose(last_value);
  1277. last_value:=current_value;
  1278. Debugger^.Command('p '+GetStr(expr));
  1279. p:=strnew(Debugger^.GetOutput);
  1280. if assigned(p) and (p[0]='$') then
  1281. q:=StrPos(p,'=');
  1282. if not assigned(q) then
  1283. q:=p;
  1284. i:=strlen(q);
  1285. if q[i-1]=#10 then
  1286. begin
  1287. q[i-1]:=#0;
  1288. last_removed:=true;
  1289. end
  1290. else
  1291. last_removed:=false;
  1292. current_value:=strnew(q);
  1293. if last_removed then
  1294. q[i-1]:=#10;
  1295. strdispose(p);
  1296. end;
  1297. destructor TWatch.Done;
  1298. begin
  1299. if assigned(expr) then
  1300. disposestr(expr);
  1301. if assigned(last_value) then
  1302. strdispose(last_value);
  1303. if assigned(current_value) then
  1304. strdispose(current_value);
  1305. inherited done;
  1306. end;
  1307. {****************************************************************************
  1308. TWatchesCollection
  1309. ****************************************************************************}
  1310. constructor TWatchesCollection.Init;
  1311. begin
  1312. inherited Init(10,10);
  1313. end;
  1314. procedure TWatchesCollection.Insert(Item: Pointer);
  1315. begin
  1316. PWatch(Item)^.Get_new_value;
  1317. Inherited Insert(Item);
  1318. Update;
  1319. end;
  1320. procedure TWatchesCollection.Update;
  1321. var
  1322. W,W1 : integer;
  1323. procedure GetMax(P : PWatch);
  1324. begin
  1325. if assigned(P^.Current_value) then
  1326. begin
  1327. W1:=StrLen(P^.Current_value)+2+Length(GetStr(P^.expr));
  1328. if W1>W then
  1329. W:=W1;
  1330. end;
  1331. end;
  1332. begin
  1333. W:=0;
  1334. ForEach(@GetMax);
  1335. MaxW:=W;
  1336. If assigned(WatchesWindow) then
  1337. WatchesWindow^.WLB^.Update(MaxW);
  1338. end;
  1339. function TWatchesCollection.At(Index: Integer): PWatch;
  1340. begin
  1341. At:=Inherited At(Index);
  1342. end;
  1343. {****************************************************************************
  1344. TWatchesListBox
  1345. ****************************************************************************}
  1346. (* PWatchesListBox = ^TWatchesListBox;
  1347. TWatchesListBox = object(THSListBox)
  1348. MaxWidth : Sw_integer; *)
  1349. constructor TWatchesListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  1350. begin
  1351. inherited Init(Bounds,1,AHScrollBar,AVScrollBar);
  1352. If assigned(List) then
  1353. dispose(list,done);
  1354. List:=WatchesCollection;
  1355. end;
  1356. procedure TWatchesListBox.Update(AMaxWidth : integer);
  1357. begin
  1358. MaxWidth:=AMaxWidth;
  1359. if HScrollBar<>nil then
  1360. HScrollBar^.SetRange(0,MaxWidth);
  1361. SetRange(List^.Count);
  1362. if Focused=List^.Count-1-1 then
  1363. FocusItem(List^.Count-1);
  1364. DrawView;
  1365. end;
  1366. function TWatchesListBox.GetIndentedText(Item,Indent,MaxLen: Sw_Integer): String;
  1367. var
  1368. PW : PWatch;
  1369. ValOffset : Sw_integer;
  1370. S : String;
  1371. begin
  1372. PW:=WatchesCollection^.At(Item);
  1373. ValOffset:=Length(GetStr(PW^.Expr))+2;
  1374. if Indent<ValOffset then
  1375. begin
  1376. if not assigned(PW^.current_value) then
  1377. S:=' '+GetStr(PW^.Expr)+' <Unknown value>'
  1378. else if not assigned(PW^.last_value) or
  1379. (strcomp(PW^.Last_value,PW^.Current_value)=0) then
  1380. S:=' '+GetStr(PW^.Expr)+' '+StrPas(PW^.Current_value)
  1381. else
  1382. S:='!'+GetStr(PW^.Expr)+'!'+StrPas(PW^.Current_value);
  1383. GetIndentedText:=Copy(S,Indent,MaxLen);
  1384. end
  1385. else
  1386. begin
  1387. if not assigned(PW^.Current_value) or
  1388. (StrLen(PW^.Current_value)<Indent-Valoffset) then
  1389. S:=''
  1390. else
  1391. S:=StrPas(@(PW^.Current_Value[Indent-Valoffset]));
  1392. GetIndentedText:=Copy(S,1,MaxLen);
  1393. end;
  1394. end;
  1395. (* function TWatchesListBox.GetLocalMenu: PMenu;virtual;
  1396. procedure TWatchesListBox.Clear; virtual;
  1397. procedure TWatchesListBox.TrackSource; virtual;
  1398. procedure TWatchesListBox.EditNew; virtual;
  1399. procedure TWatchesListBox.EditCurrent; virtual;
  1400. procedure TWatchesListBox.DeleteCurrent; virtual;
  1401. procedure TWatchesListBox.ToggleCurrent; *)
  1402. procedure TWatchesListBox.EditCurrent;
  1403. var
  1404. P: PWatch;
  1405. begin
  1406. if Range=0 then Exit;
  1407. P:=WatchesCollection^.At(Focused);
  1408. if P=nil then Exit;
  1409. Application^.ExecuteDialog(New(PWatchItemDialog,Init(P)),nil);
  1410. WatchesCollection^.Update;
  1411. end;
  1412. procedure TWatchesListBox.DeleteCurrent;
  1413. var
  1414. P: PWatch;
  1415. begin
  1416. if Range=0 then Exit;
  1417. P:=WatchesCollection^.At(Focused);
  1418. if P=nil then Exit;
  1419. WatchesCollection^.free(P);
  1420. WatchesCollection^.Update;
  1421. end;
  1422. procedure TWatchesListBox.EditNew;
  1423. var
  1424. P: PWatch;
  1425. begin
  1426. P:=New(PWatch,Init(''));
  1427. if Application^.ExecuteDialog(New(PWatchItemDialog,Init(P)),nil)<>cmCancel then
  1428. begin
  1429. WatchesCollection^.Insert(P);
  1430. WatchesCollection^.Update;
  1431. end
  1432. else
  1433. dispose(P,Done);
  1434. end;
  1435. procedure TWatchesListBox.Draw;
  1436. var
  1437. I, J, Item: Sw_Integer;
  1438. NormalColor, SelectedColor, FocusedColor, Color: Word;
  1439. ColWidth, CurCol, Indent: Integer;
  1440. B: TDrawBuffer;
  1441. Text: String;
  1442. SCOff: Byte;
  1443. TC: byte;
  1444. procedure MT(var C: word); begin if TC<>0 then C:=(C and $ff0f) or (TC and $f0); end;
  1445. begin
  1446. if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
  1447. if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
  1448. begin
  1449. NormalColor := GetColor(1);
  1450. FocusedColor := GetColor(3);
  1451. SelectedColor := GetColor(4);
  1452. end else
  1453. begin
  1454. NormalColor := GetColor(2);
  1455. SelectedColor := GetColor(4);
  1456. end;
  1457. if Transparent then
  1458. begin MT(NormalColor); MT(SelectedColor); end;
  1459. (* if NoSelection then
  1460. SelectedColor:=NormalColor;*)
  1461. if HScrollBar <> nil then Indent := HScrollBar^.Value
  1462. else Indent := 0;
  1463. ColWidth := Size.X div NumCols + 1;
  1464. for I := 0 to Size.Y - 1 do
  1465. begin
  1466. for J := 0 to NumCols-1 do
  1467. begin
  1468. Item := J*Size.Y + I + TopItem;
  1469. CurCol := J*ColWidth;
  1470. if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
  1471. (Focused = Item) and (Range > 0) then
  1472. begin
  1473. Color := FocusedColor;
  1474. SetCursor(CurCol+1,I);
  1475. SCOff := 0;
  1476. end
  1477. else if (Item < Range) and IsSelected(Item) then
  1478. begin
  1479. Color := SelectedColor;
  1480. SCOff := 2;
  1481. end
  1482. else
  1483. begin
  1484. Color := NormalColor;
  1485. SCOff := 4;
  1486. end;
  1487. MoveChar(B[CurCol], ' ', Color, ColWidth);
  1488. if Item < Range then
  1489. begin
  1490. (* Text := GetText(Item, ColWidth + Indent);
  1491. Text := Copy(Text,Indent,ColWidth); *)
  1492. Text:=GetIndentedText(Item,Indent,ColWidth);
  1493. MoveStr(B[CurCol+1], Text, Color);
  1494. if ShowMarkers then
  1495. begin
  1496. WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
  1497. WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
  1498. end;
  1499. end;
  1500. MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
  1501. end;
  1502. WriteLine(0, I, Size.X, 1, B);
  1503. end;
  1504. end;
  1505. function TWatchesListBox.GetLocalMenu: PMenu;
  1506. var M: PMenu;
  1507. begin
  1508. if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
  1509. M:=NewMenu(
  1510. NewItem('~E~dit watch','',kbNoKey,cmEdit,hcNoContext,
  1511. NewItem('~N~ew watch','',kbNoKey,cmNew,hcNoContext,
  1512. NewItem('~D~elete watch','',kbNoKey,cmDelete,hcNoContext,
  1513. nil))));
  1514. GetLocalMenu:=M;
  1515. end;
  1516. procedure TWatchesListBox.HandleEvent(var Event: TEvent);
  1517. var DontClear: boolean;
  1518. begin
  1519. case Event.What of
  1520. evKeyDown :
  1521. begin
  1522. DontClear:=false;
  1523. case Event.KeyCode of
  1524. kbEnter :
  1525. Message(@Self,evCommand,cmEdit,nil);
  1526. kbIns :
  1527. Message(@Self,evCommand,cmNew,nil);
  1528. kbDel :
  1529. Message(@Self,evCommand,cmDelete,nil);
  1530. else
  1531. DontClear:=true;
  1532. end;
  1533. if not DontClear then
  1534. ClearEvent(Event);
  1535. end;
  1536. evBroadcast :
  1537. case Event.Command of
  1538. cmListItemSelected :
  1539. if Event.InfoPtr=@Self then
  1540. Message(@Self,evCommand,cmEdit,nil);
  1541. end;
  1542. evCommand :
  1543. begin
  1544. DontClear:=false;
  1545. case Event.Command of
  1546. cmEdit :
  1547. EditCurrent;
  1548. cmDelete :
  1549. DeleteCurrent;
  1550. cmNew :
  1551. EditNew;
  1552. else
  1553. DontClear:=true;
  1554. end;
  1555. if not DontClear then
  1556. ClearEvent(Event);
  1557. end;
  1558. end;
  1559. inherited HandleEvent(Event);
  1560. end;
  1561. (* constructor TWatchesListBox.Load(var S: TStream);
  1562. procedure TWatchesListBox.Store(var S: TStream); *)
  1563. destructor TWatchesListBox.Done;
  1564. begin
  1565. List:=nil;
  1566. inherited Done;
  1567. end;
  1568. {****************************************************************************
  1569. TWatchesWindow
  1570. ****************************************************************************}
  1571. Constructor TWatchesWindow.Init;
  1572. var
  1573. R : trect;
  1574. begin
  1575. Desktop^.GetExtent(R);
  1576. R.A.Y:=R.B.Y-5;
  1577. inherited Init(R, 'Watches', wnNoNumber);
  1578. GetExtent(R);
  1579. HelpCtx:=hcWatches;
  1580. R.Grow(-1,-1);
  1581. New(WLB,Init(R,nil,nil));
  1582. WLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  1583. WLB^.Transparent:=true;
  1584. Insert(WLB);
  1585. If assigned(WatchesWindow) then
  1586. dispose(WatchesWindow,done);
  1587. WatchesWindow:=@Self;
  1588. end;
  1589. procedure TWatchesWindow.Update;
  1590. begin
  1591. WatchesCollection^.Update;
  1592. Draw;
  1593. end;
  1594. Destructor TWatchesWindow.Done;
  1595. begin
  1596. WatchesWindow:=nil;
  1597. Dispose(WLB,done);
  1598. inherited done;
  1599. end;
  1600. {****************************************************************************
  1601. TWatchItemDialog
  1602. ****************************************************************************}
  1603. (* TWatchItemDialog = object(TCenterDialog)
  1604. constructor Init(AWatch: PWatch);
  1605. function Execute: Word; virtual;
  1606. private
  1607. Watch : PWatch;
  1608. NameIL : PInputLine;
  1609. TextST : PAdvancedStaticText;
  1610. CurrentIL: PLabel;
  1611. LastIL : PLabel;
  1612. end; *)
  1613. constructor TWatchItemDialog.Init(AWatch: PWatch);
  1614. var R,R2: TRect;
  1615. begin
  1616. R.Assign(0,0,50,10);
  1617. inherited Init(R,'Edit Watch');
  1618. Watch:=AWatch;
  1619. GetExtent(R); R.Grow(-3,-2);
  1620. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+36;
  1621. New(NameIL, Init(R, 255)); Insert(NameIL);
  1622. R2.Copy(R); R2.Move(-1,-1);
  1623. Insert(New(PLabel, Init(R2, '~E~xpression to watch', NameIL)));
  1624. GetExtent(R);
  1625. R.Grow(-1,-1);
  1626. R.A.Y:=R.A.Y+3;
  1627. R.B.X:=R.A.X+36;
  1628. TextST:=New(PAdvancedStaticText, Init(R, 'Watch values'));
  1629. Insert(TextST);
  1630. InsertButtons(@Self);
  1631. NameIL^.Select;
  1632. end;
  1633. function TWatchItemDialog.Execute: Word;
  1634. var R: word;
  1635. S1,S2: string;
  1636. err: word;
  1637. L: longint;
  1638. begin
  1639. S1:=GetStr(Watch^.expr);
  1640. NameIL^.SetData(S1);
  1641. if assigned(Watch^.Current_value) then
  1642. S1:=StrPas(Watch^.Current_value)
  1643. else
  1644. S1:='';
  1645. if assigned(Watch^.Last_value) then
  1646. S2:=StrPas(Watch^.Last_value)
  1647. else
  1648. S2:='';
  1649. if assigned(Watch^.Last_value) and
  1650. assigned(Watch^.Current_value) and
  1651. (strcomp(Watch^.Last_value,Watch^.Current_value)=0) then
  1652. S1:='Current value: '+#13+S1
  1653. else
  1654. S1:='Current value: '+#13+S1+#13+
  1655. 'Previous value: '+#13+S2;
  1656. TextST^.SetText(S1);
  1657. R:=inherited Execute;
  1658. if R=cmOK then
  1659. begin
  1660. NameIL^.GetData(S1);
  1661. If assigned(Watch^.Expr) then
  1662. DisposeStr(Watch^.Expr);
  1663. Watch^.expr:=NewStr(S1);
  1664. end;
  1665. Execute:=R;
  1666. end;
  1667. {****************************************************************************
  1668. Init/Final
  1669. ****************************************************************************}
  1670. procedure InitDebugger;
  1671. begin
  1672. {$ifdef DEBUG}
  1673. Assign(gdb_file,'gdb$$$.out');
  1674. Rewrite(gdb_file);
  1675. Use_gdb_file:=true;
  1676. {$endif}
  1677. if (not ExistsFile(ExeFile)) or (CompilationPhase<>cpDone) then
  1678. DoCompile(cRun);
  1679. if CompilationPhase<>cpDone then
  1680. Exit;
  1681. if (EXEFile='') then
  1682. begin
  1683. ErrorBox('Oooops, nothing to debug.',nil);
  1684. Exit;
  1685. end;
  1686. { init debugcontroller }
  1687. if assigned(Debugger) then
  1688. dispose(Debugger,Done);
  1689. new(Debugger,Init(ExeFile));
  1690. {$ifdef GDBWINDOW}
  1691. InitGDBWindow;
  1692. {$endif def GDBWINDOW}
  1693. end;
  1694. procedure DoneDebugger;
  1695. begin
  1696. if assigned(Debugger) then
  1697. dispose(Debugger,Done);
  1698. Debugger:=nil;
  1699. {$ifdef DEBUG}
  1700. If Use_gdb_file then
  1701. Close(GDB_file);
  1702. Use_gdb_file:=false;
  1703. {$endif}
  1704. {DoneGDBWindow;}
  1705. end;
  1706. procedure InitGDBWindow;
  1707. var
  1708. R : TRect;
  1709. begin
  1710. if GDBWindow=nil then
  1711. begin
  1712. DeskTop^.GetExtent(R);
  1713. new(GDBWindow,init(R));
  1714. DeskTop^.Insert(GDBWindow);
  1715. end;
  1716. end;
  1717. procedure DoneGDBWindow;
  1718. begin
  1719. if assigned(GDBWindow) then
  1720. begin
  1721. DeskTop^.Delete(GDBWindow);
  1722. GDBWindow:=nil;
  1723. end;
  1724. end;
  1725. procedure InitBreakpoints;
  1726. begin
  1727. New(BreakpointCollection,init(10,10));
  1728. end;
  1729. procedure DoneBreakpoints;
  1730. begin
  1731. Dispose(BreakpointCollection,Done);
  1732. BreakpointCollection:=nil;
  1733. end;
  1734. procedure InitWatches;
  1735. begin
  1736. New(WatchesCollection,init);
  1737. end;
  1738. procedure DoneWatches;
  1739. begin
  1740. Dispose(WatchesCollection,Done);
  1741. WatchesCollection:=nil;
  1742. end;
  1743. end.
  1744. {
  1745. $Log$
  1746. Revision 1.20 1999-07-10 01:24:14 pierre
  1747. + First implementation of watches window
  1748. Revision 1.19 1999/06/30 23:58:12 pierre
  1749. + BreakpointsList Window implemented
  1750. with Edit/New/Delete functions
  1751. + Individual breakpoint dialog with support for all types
  1752. ignorecount and conditions
  1753. (commands are not yet implemented, don't know if this wolud be useful)
  1754. awatch and rwatch have problems because GDB does not annotate them
  1755. I fixed v4.16 for this
  1756. Revision 1.18 1999/03/16 00:44:42 peter
  1757. * forgotten in last commit :(
  1758. Revision 1.17 1999/03/02 13:48:28 peter
  1759. * fixed far problem is fpdebug
  1760. * tile/cascading with message window
  1761. * grep fixes
  1762. Revision 1.16 1999/03/01 15:41:52 peter
  1763. + Added dummy entries for functions not yet implemented
  1764. * MenuBar didn't update itself automatically on command-set changes
  1765. * Fixed Debugging/Profiling options dialog
  1766. * TCodeEditor converts spaces to tabs at save only if efUseTabChars is
  1767. set
  1768. * efBackSpaceUnindents works correctly
  1769. + 'Messages' window implemented
  1770. + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
  1771. + Added TP message-filter support (for ex. you can call GREP thru
  1772. GREP2MSG and view the result in the messages window - just like in TP)
  1773. * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
  1774. so topic search didn't work...
  1775. * In FPHELP.PAS there were still context-variables defined as word instead
  1776. of THelpCtx
  1777. * StdStatusKeys() was missing from the statusdef for help windows
  1778. + Topic-title for index-table can be specified when adding a HTML-files
  1779. Revision 1.15 1999/02/20 15:18:29 peter
  1780. + ctrl-c capture with confirm dialog
  1781. + ascii table in the tools menu
  1782. + heapviewer
  1783. * empty file fixed
  1784. * fixed callback routines in fpdebug to have far for tp7
  1785. Revision 1.14 1999/02/16 12:47:36 pierre
  1786. * GDBWindow does not popup on F7 or F8 anymore
  1787. Revision 1.13 1999/02/16 10:43:54 peter
  1788. * use -dGDB for the compiler
  1789. * only use gdb_file when -dDEBUG is used
  1790. * profiler switch is now a toggle instead of radiobutton
  1791. Revision 1.12 1999/02/11 19:07:20 pierre
  1792. * GDBWindow redesigned :
  1793. normal editor apart from
  1794. that any kbEnter will send the line (for begin to cursor)
  1795. to GDB command !
  1796. GDBWindow opened in Debugger Menu
  1797. still buggy :
  1798. -echo should not be present if at end of text
  1799. -GDBWindow becomes First after each step (I don't know why !)
  1800. Revision 1.11 1999/02/11 13:10:03 pierre
  1801. + GDBWindow only with -dGDBWindow for now : still buggy !!
  1802. Revision 1.10 1999/02/10 09:55:07 pierre
  1803. + added OldValue and CurrentValue field for watchpoints
  1804. + InitBreakpoints and DoneBreakpoints
  1805. + MessageBox if GDB stops bacause of a watchpoint !
  1806. Revision 1.9 1999/02/08 17:43:43 pierre
  1807. * RestDebugger or multiple running of debugged program now works
  1808. + added DoContToCursor(F4)
  1809. * Breakpoints are now inserted correctly (was mainlyy a problem
  1810. of directories)
  1811. Revision 1.8 1999/02/05 17:21:52 pierre
  1812. Invalid_line renamed InvalidSourceLine
  1813. Revision 1.7 1999/02/05 13:08:41 pierre
  1814. + new breakpoint types added
  1815. Revision 1.6 1999/02/05 12:11:53 pierre
  1816. + SourceDir that stores directories for sources that the
  1817. compiler should not know about
  1818. Automatically asked for addition when a new file that
  1819. needed filedialog to be found is in an unknown directory
  1820. Stored and retrieved from INIFile
  1821. + Breakpoints conditions added to INIFile
  1822. * Breakpoints insterted and removed at debin and end of debug session
  1823. Revision 1.5 1999/02/04 17:54:22 pierre
  1824. + several commands added
  1825. Revision 1.4 1999/02/04 13:32:02 pierre
  1826. * Several things added (I cannot commit them independently !)
  1827. + added TBreakpoint and TBreakpointCollection
  1828. + added cmResetDebugger,cmGrep,CmToggleBreakpoint
  1829. + Breakpoint list in INIFile
  1830. * Select items now also depend of SwitchMode
  1831. * Reading of option '-g' was not possible !
  1832. + added search for -Fu args pathes in TryToOpen
  1833. + added code for automatic opening of FileDialog
  1834. if source not found
  1835. Revision 1.3 1999/02/02 16:41:38 peter
  1836. + automatic .pas/.pp adding by opening of file
  1837. * better debuggerscreen changes
  1838. Revision 1.2 1999/01/22 18:14:09 pierre
  1839. * adaptd to changes in gdbint and gdbcon for to /
  1840. Revision 1.1 1999/01/22 10:24:03 peter
  1841. * first debugger things
  1842. }