fpdebug.pas 69 KB

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