fpdebug.pas 57 KB

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