fpdebug.pas 69 KB

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