fpdebug.pas 101 KB

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