fpdebug.pas 101 KB

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