fpdebug.pas 63 KB

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