fpdebug.pas 88 KB

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