fpdebug.pas 98 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998-2000 by Pierre Muller
  4. Debugger call routines for the IDE
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit FPDebug;
  12. {$ifdef NODEBUG}
  13. interface
  14. implementation
  15. end.
  16. {$else}
  17. interface
  18. {$i globdir.inc}
  19. uses
  20. {$ifdef Windows}
  21. Windows,
  22. {$endif Windows}
  23. Objects,Dialogs,Drivers,Views,
  24. {$ifndef NODEBUG}
  25. GDBCon,GDBInt,
  26. {$endif NODEBUG}
  27. Menus,
  28. WViews,WEditor,
  29. FPViews;
  30. type
  31. {$ifndef NODEBUG}
  32. PDebugController=^TDebugController;
  33. TDebugController=object(TGDBController)
  34. InvalidSourceLine : boolean;
  35. { if true the current debugger raw will stay in middle of
  36. editor window when debugging PM }
  37. CenterDebuggerRow : TCentre;
  38. Disableallinvalidbreakpoints : boolean;
  39. OrigPwd, { pwd at startup }
  40. LastFileName : string;
  41. LastSource : PView; {PsourceWindow !! }
  42. HiddenStepsCount : longint;
  43. { no need to switch if using another terminal }
  44. NoSwitch : boolean;
  45. HasExe : boolean;
  46. RunCount : longint;
  47. WindowWidth : longint;
  48. FPCBreakErrorNumber : longint;
  49. {$ifdef SUPPORT_REMOTE}
  50. isRemoteDebugging:boolean;
  51. {$endif SUPPORT_REMOTE}
  52. constructor Init;
  53. procedure SetExe(const exefn:string);
  54. procedure SetWidth(AWidth : longint);
  55. procedure SetSourceDirs;
  56. destructor Done;
  57. procedure DoSelectSourceline(const fn:string;line:longint);virtual;
  58. { procedure DoStartSession;virtual;
  59. procedure DoBreakSession;virtual;}
  60. procedure DoEndSession(code:longint);virtual;
  61. procedure DoUserSignal;virtual;
  62. procedure AnnotateError;
  63. procedure InsertBreakpoints;
  64. procedure RemoveBreakpoints;
  65. procedure ReadWatches;
  66. procedure RereadWatches;
  67. procedure ResetBreakpointsValues;
  68. procedure DoDebuggerScreen;virtual;
  69. procedure DoUserScreen;virtual;
  70. procedure Reset;virtual;
  71. procedure ResetDebuggerRows;
  72. procedure Run;virtual;
  73. procedure Continue;virtual;
  74. procedure UntilReturn;virtual;
  75. procedure CommandBegin(const s:string);virtual;
  76. procedure CommandEnd(const s:string);virtual;
  77. function IsRunning : boolean;
  78. function AllowQuit : boolean;virtual;
  79. function GetValue(Const expr : string) : pchar;
  80. function GetFramePointer : CORE_ADDR;
  81. function GetLongintAt(addr : CORE_ADDR) : longint;
  82. function GetPointerAt(addr : CORE_ADDR) : CORE_ADDR;
  83. end;
  84. {$endif NODEBUG}
  85. BreakpointType = (bt_function,bt_file_line,bt_watch,
  86. bt_awatch,bt_rwatch,bt_address,bt_invalid);
  87. BreakpointState = (bs_enabled,bs_disabled,bs_deleted,bs_delete_after);
  88. PBreakpointCollection=^TBreakpointCollection;
  89. PBreakpoint=^TBreakpoint;
  90. TBreakpoint=object(TObject)
  91. typ : BreakpointType;
  92. state : BreakpointState;
  93. owner : PBreakpointCollection;
  94. Name : PString; { either function name or expr to watch }
  95. FileName : PString;
  96. OldValue,CurrentValue : Pstring;
  97. Line : Longint; { only used for bt_file_line type }
  98. Conditions : PString; { conditions relative to that breakpoint }
  99. IgnoreCount : Longint; { how many counts should be ignored }
  100. Commands : pchar; { commands that should be executed on breakpoint }
  101. GDBIndex : longint;
  102. GDBState : BreakpointState;
  103. constructor Init_function(Const AFunc : String);
  104. constructor Init_Address(Const AAddress : String);
  105. constructor Init_Empty;
  106. constructor Init_file_line(AFile : String; ALine : longint);
  107. constructor Init_type(atyp : BreakpointType;Const AnExpr : String);
  108. constructor Load(var S: TStream);
  109. procedure Store(var S: TStream);
  110. procedure Insert;
  111. procedure Remove;
  112. procedure Enable;
  113. procedure Disable;
  114. procedure UpdateSource;
  115. procedure ResetValues;
  116. destructor Done;virtual;
  117. end;
  118. TBreakpointCollection=object(TCollection)
  119. function At(Index: Integer): PBreakpoint;
  120. function GetGDB(index : longint) : PBreakpoint;
  121. function GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
  122. function ToggleFileLine(FileName: String;LineNr : Longint) : boolean;
  123. procedure Update;
  124. procedure ShowBreakpoints(W : PFPWindow);
  125. function FindBreakpointAt(Editor : PSourceEditor; Line : longint) : PBreakpoint;
  126. procedure AdaptBreakpoints(Editor : PSourceEditor; Pos, Change : longint);
  127. procedure ShowAllBreakpoints;
  128. end;
  129. PBreakpointItem = ^TBreakpointItem;
  130. TBreakpointItem = object(TObject)
  131. Breakpoint : PBreakpoint;
  132. constructor Init(ABreakpoint : PBreakpoint);
  133. function GetText(MaxLen: Sw_integer): string; virtual;
  134. procedure Selected; virtual;
  135. function GetModuleName: string; virtual;
  136. end;
  137. PBreakpointsListBox = ^TBreakpointsListBox;
  138. TBreakpointsListBox = object(THSListBox)
  139. Transparent : boolean;
  140. NoSelection : boolean;
  141. MaxWidth : Sw_integer;
  142. (* ModuleNames : PStoreCollection; *)
  143. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  144. procedure AddBreakpoint(P: PBreakpointItem); virtual;
  145. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  146. function GetLocalMenu: PMenu;virtual;
  147. procedure Clear; virtual;
  148. procedure TrackSource; virtual;
  149. procedure EditNew; virtual;
  150. procedure EditCurrent; virtual;
  151. procedure DeleteCurrent; virtual;
  152. procedure ToggleCurrent;
  153. procedure Draw; virtual;
  154. procedure HandleEvent(var Event: TEvent); virtual;
  155. constructor Load(var S: TStream);
  156. procedure Store(var S: TStream);
  157. destructor Done; virtual;
  158. end;
  159. PBreakpointsWindow = ^TBreakpointsWindow;
  160. TBreakpointsWindow = object(TFPDlgWindow)
  161. BreakLB : PBreakpointsListBox;
  162. constructor Init;
  163. procedure AddBreakpoint(ABreakpoint : PBreakpoint);
  164. procedure ClearBreakpoints;
  165. procedure ReloadBreakpoints;
  166. procedure Close; virtual;
  167. procedure SizeLimits(var Min, Max: TPoint);virtual;
  168. procedure HandleEvent(var Event: TEvent); virtual;
  169. procedure Update; virtual;
  170. constructor Load(var S: TStream);
  171. procedure Store(var S: TStream);
  172. destructor Done; virtual;
  173. end;
  174. PBreakpointItemDialog = ^TBreakpointItemDialog;
  175. TBreakpointItemDialog = object(TCenterDialog)
  176. constructor Init(ABreakpoint: PBreakpoint);
  177. function Execute: Word; virtual;
  178. private
  179. Breakpoint : PBreakpoint;
  180. TypeRB : PRadioButtons;
  181. NameIL : PEditorInputLine;
  182. ConditionsIL: PEditorInputLine;
  183. LineIL : PEditorInputLine;
  184. IgnoreIL : PEditorInputLine;
  185. end;
  186. PWatch = ^TWatch;
  187. TWatch = Object(TObject)
  188. expr : pstring;
  189. last_value,current_value : pchar;
  190. constructor Init(s : string);
  191. constructor Load(var S: TStream);
  192. procedure Store(var S: TStream);
  193. procedure rename(s : string);
  194. procedure Get_new_value;
  195. procedure Force_new_value;
  196. destructor done;virtual;
  197. private
  198. GDBRunCount : longint;
  199. end;
  200. PWatchesCollection = ^TWatchesCollection;
  201. TWatchesCollection = Object(TCollection)
  202. constructor Init;
  203. procedure Insert(Item: Pointer); virtual;
  204. function At(Index: Integer): PWatch;
  205. procedure Update;
  206. private
  207. MaxW : integer;
  208. end;
  209. PWatchesListBox = ^TWatchesListBox;
  210. TWatchesListBox = object(THSListBox)
  211. Transparent : boolean;
  212. MaxWidth : Sw_integer;
  213. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  214. (* procedure AddWatch(P: PWatch); virtual; *)
  215. procedure Update(AMaxWidth : integer);
  216. function GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String; Virtual;
  217. function GetIndentedText(Item,Indent,MaxLen: Sw_Integer;var Modified : boolean): String; virtual;
  218. function GetLocalMenu: PMenu;virtual;
  219. (* procedure Clear; virtual;
  220. procedure TrackSource; virtual;*)
  221. procedure EditNew; virtual;
  222. procedure EditCurrent; virtual;
  223. procedure DeleteCurrent; virtual;
  224. (*procedure ToggleCurrent; *)
  225. procedure Draw; virtual;
  226. procedure HandleEvent(var Event: TEvent); virtual;
  227. constructor Load(var S: TStream);
  228. procedure Store(var S: TStream);
  229. destructor Done; virtual;
  230. end;
  231. PWatchItemDialog = ^TWatchItemDialog;
  232. TWatchItemDialog = object(TCenterDialog)
  233. constructor Init(AWatch: PWatch);
  234. function Execute: Word; virtual;
  235. private
  236. Watch : PWatch;
  237. NameIL : PEditorInputLine;
  238. TextST : PAdvancedStaticText;
  239. end;
  240. PWatchesWindow = ^TWatchesWindow;
  241. TWatchesWindow = Object(TFPDlgWindow)
  242. WLB : PWatchesListBox;
  243. Constructor Init;
  244. constructor Load(var S: TStream);
  245. procedure Store(var S: TStream);
  246. procedure Update; virtual;
  247. destructor Done; virtual;
  248. end;
  249. PFramesListBox = ^TFramesListBox;
  250. TFramesListBox = object(TMessageListBox)
  251. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  252. procedure Update;
  253. function GetLocalMenu: PMenu;virtual;
  254. procedure GotoSource; virtual;
  255. procedure GotoAssembly; virtual;
  256. procedure HandleEvent(var Event: TEvent); virtual;
  257. destructor Done; virtual;
  258. end;
  259. PStackWindow = ^TStackWindow;
  260. TStackWindow = Object(TFPDlgWindow)
  261. FLB : PFramesListBox;
  262. Constructor Init;
  263. constructor Load(var S: TStream);
  264. procedure Store(var S: TStream);
  265. procedure Update; virtual;
  266. destructor Done; virtual;
  267. end;
  268. procedure InitStackWindow;
  269. procedure DoneStackWindow;
  270. function ActiveBreakpoints : boolean;
  271. function GDBFileName(st : string) : string;
  272. function OSFileName(st : string) : string;
  273. const
  274. BreakpointTypeStr : Array[BreakpointType] of String[9]
  275. = ( 'function','file-line','watch','awatch','rwatch','address','invalid');
  276. BreakpointStateStr : Array[BreakpointState] of String[8]
  277. = ( 'enabled','disabled','invalid',''{'to be deleted' should never be used});
  278. var
  279. {$ifndef NODEBUG}
  280. Debugger : PDebugController;
  281. {$endif NODEBUG}
  282. BreakpointsCollection : PBreakpointCollection;
  283. WatchesCollection : PwatchesCollection;
  284. procedure InitDebugger;
  285. procedure DoneDebugger;
  286. procedure InitGDBWindow;
  287. procedure DoneGDBWindow;
  288. procedure InitDisassemblyWindow;
  289. procedure DoneDisassemblyWindow;
  290. procedure InitBreakpoints;
  291. procedure DoneBreakpoints;
  292. procedure InitWatches;
  293. procedure DoneWatches;
  294. procedure RegisterFPDebugViews;
  295. procedure UpdateDebugViews;
  296. implementation
  297. uses
  298. Dos,
  299. Video,
  300. {$ifdef DOS}
  301. fpusrscr,
  302. {$endif DOS}
  303. App,Strings,
  304. FVConsts,
  305. {$ifdef Windows}
  306. Windebug,
  307. {$endif Windows}
  308. {$ifdef Unix}
  309. termio,
  310. {$endif Unix}
  311. Systems,Globals,
  312. FPRegs,
  313. FPVars,FPUtils,FPConst,FPSwitch,
  314. FPIntf,FPCompil,FPIde,FPHelp,
  315. Validate,WUtils,Wconsts;
  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. {$ifdef USERESSTRINGS}
  378. resourcestring
  379. {$else}
  380. const
  381. {$endif}
  382. button_OK = 'O~K~';
  383. button_Cancel = 'Cancel';
  384. button_New = '~N~ew';
  385. button_Edit = '~E~dit';
  386. button_Delete = '~D~elete';
  387. button_Close = '~C~lose';
  388. button_ToggleButton = '~T~oggle';
  389. { Watches local menu items }
  390. menu_watchlocal_edit = '~E~dit watch';
  391. menu_watchlocal_new = '~N~ew watch';
  392. menu_watchlocal_delete = '~D~elete watch';
  393. { Breakpoints window local menu items }
  394. menu_bplocal_gotosource = '~G~oto source';
  395. menu_bplocal_editbreakpoint = '~E~dit breakpoint';
  396. menu_bplocal_newbreakpoint = '~N~ew breakpoint';
  397. menu_bplocal_deletebreakpoint = '~D~elete breakpoint';
  398. menu_bplocal_togglestate = '~T~oggle state';
  399. { Debugger messages and status hints }
  400. msg_programexitedwithcodeandsteps = #3'Program exited with '#13+
  401. #3'exitcode = %d'#13+
  402. #3'hidden steps = %d';
  403. msg_programexitedwithexitcode = #3'Program exited with '#13+
  404. #3'exitcode = %d';
  405. msg_programsignal = #3'Program recieved signal %s'#13+
  406. #3'%s';
  407. msg_runningprogram = 'Running...';
  408. msg_runningremotely = 'Executable running remotely on ';
  409. msg_connectingto = 'Connecting to ';
  410. msg_getting_info_on = 'Getting infos from ';
  411. msg_runninginanotherwindow = 'Executable running in another window..';
  412. msg_couldnotsetbreakpointat = #3'Could not set Breakpoint'#13+
  413. #3+'%s:%d';
  414. msg_couldnotsetbreakpointtype = #3'Could not set Breakpoint'#13+
  415. #3+'%s %s';
  416. button_DisableAllBreakpoints = 'Dis. ~a~ll invalid';
  417. { Breakpoints window }
  418. dialog_breakpointlist = 'Breakpoint list';
  419. label_breakpointpropheader = ' Type | State | Position | Path | Ignore | Conditions ';
  420. dialog_modifynewbreakpoint = 'Modify/New Breakpoint';
  421. label_breakpoint_name = '~N~ame';
  422. label_breakpoint_line = '~L~ine';
  423. label_breakpoint_conditions = '~C~onditions';
  424. label_breakpoint_ignorecount = '~I~gnore count';
  425. label_breakpoint_type = '~T~ype';
  426. { Watches window }
  427. dialog_watches = 'Watches';
  428. label_watch_expressiontowatch = '~E~xpression to watch';
  429. label_watch_values = 'Watch values';
  430. msg_watch_currentvalue = 'Current value: '+#13+
  431. '%s';
  432. msg_watch_currentandpreviousvalue = 'Current value: '+#13+
  433. '%s'+#13+
  434. 'Previous value: '+#13+
  435. '%s';
  436. dialog_callstack = 'Call Stack';
  437. menu_msglocal_saveas = 'Save ~a~s';
  438. msg_cantdebugchangetargetto = #3'Sorry, can not debug'#13+
  439. #3'programs compiled for %s.'#13+
  440. #3'Change target to %s?';
  441. msg_compiledwithoutdebuginforecompile =
  442. #3'Warning, the program'#13+
  443. #3'was compiled without'#13+
  444. #3'debugging info.'#13+
  445. #3'Recompile it?';
  446. msg_nothingtodebug = 'Oooops, nothing to debug.';
  447. msg_startingdebugger = 'Starting debugger';
  448. {$ifdef I386}
  449. const
  450. FrameName = '$ebp';
  451. {$define FrameNameKnown}
  452. {$endif i386}
  453. {$ifdef m68k}
  454. const
  455. FrameName = '$fp';
  456. {$define FrameNameKnown}
  457. {$endif m68k}
  458. {$ifdef powerpc}
  459. { stack and frame registers are the same on powerpc,
  460. so I am not sure that this will work PM }
  461. const
  462. FrameName = '$r1';
  463. {$define FrameNameKnown}
  464. {$endif powerpc}
  465. function GDBFileName(st : string) : string;
  466. {$ifndef Unix}
  467. var i : longint;
  468. {$endif Unix}
  469. begin
  470. {$ifdef NODEBUG}
  471. GDBFileName:=st;
  472. {$else NODEBUG}
  473. {$ifdef Unix}
  474. GDBFileName:=st;
  475. {$else}
  476. { should we also use / chars ? }
  477. for i:=1 to Length(st) do
  478. if st[i]='\' then
  479. {$ifdef Windows}
  480. { Don't touch at '\ ' used to escapes spaces in windows file names PM }
  481. if (i=length(st)) or (st[i+1]<>' ') then
  482. {$endif Windows}
  483. st[i]:='/';
  484. {$ifdef Windows}
  485. {$ifndef USE_MINGW_GDB} // see mantis 11968 because of mingw build. MvdV
  486. { for Windows we should convert e:\ into //e/ PM }
  487. if (length(st)>2) and (st[2]=':') and (st[3]='/') then
  488. st:=CygDrivePrefix+'/'+st[1]+copy(st,3,length(st));
  489. {$endif}
  490. { support spaces in the name by escaping them but without changing '\ ' into '\\ ' }
  491. for i:=Length(st) downto 1 do
  492. if (st[i]=' ') and ((i=1) or (st[i-1]<>'\')) then
  493. st:=copy(st,1,i-1)+'\'+copy(st,i,length(st));
  494. {$endif Windows}
  495. {$ifdef go32v2}
  496. { for go32v2 we should convert //e/ back into e:/ PM }
  497. if (length(st)>3) and (st[1]='/') and (st[2]='/') and (st[4]='/') then
  498. st:=st[3]+':/'+copy(st,5,length(st));
  499. {$endif go32v2}
  500. GDBFileName:=LowerCaseStr(st);
  501. {$endif}
  502. {$endif NODEBUG}
  503. end;
  504. function OSFileName(st : string) : string;
  505. {$ifndef Unix}
  506. var i : longint;
  507. {$endif Unix}
  508. begin
  509. {$ifdef Unix}
  510. OSFileName:=st;
  511. {$else}
  512. {$ifdef Windows}
  513. {$ifndef NODEBUG}
  514. { for Windows we should convert /cygdrive/e/ into e:\ PM }
  515. if pos(CygDrivePrefix+'/',st)=1 then
  516. st:=st[Length(CygdrivePrefix)+2]+':\'+copy(st,length(CygdrivePrefix)+4,length(st));
  517. {$endif NODEBUG}
  518. {$endif Windows}
  519. { support spaces in the name by escaping them but without changing '\ ' into '\\ ' }
  520. for i:=Length(st) downto 2 do
  521. if (st[i]=' ') and (st[i-1]='\') then
  522. st:=copy(st,1,i-2)+copy(st,i,length(st));
  523. {$ifdef go32v2}
  524. { for go32v2 we should convert //e/ back into e:/ PM }
  525. if (length(st)>3) and (st[1]='/') and (st[2]='/') and (st[4]='/') then
  526. st:=st[3]+':\'+copy(st,5,length(st));
  527. {$endif go32v2}
  528. { should we also use / chars ? }
  529. for i:=1 to Length(st) do
  530. if st[i]='/' then
  531. st[i]:='\';
  532. OSFileName:=LowerCaseStr(st);
  533. {$endif}
  534. end;
  535. {****************************************************************************
  536. TDebugController
  537. ****************************************************************************}
  538. procedure UpdateDebugViews;
  539. begin
  540. {$ifdef SUPPORT_REMOTE}
  541. PushStatus(msg_getting_info_on+RemoteMachine);
  542. {$endif SUPPORT_REMOTE}
  543. DeskTop^.Lock;
  544. If assigned(StackWindow) then
  545. StackWindow^.Update;
  546. If assigned(RegistersWindow) then
  547. RegistersWindow^.Update;
  548. {$ifndef NODEBUG}
  549. If assigned(Debugger) then
  550. Debugger^.ReadWatches;
  551. {$endif NODEBUG}
  552. If assigned(FPUWindow) then
  553. FPUWindow^.Update;
  554. If assigned(VectorWindow) then
  555. VectorWindow^.Update;
  556. DeskTop^.UnLock;
  557. {$ifdef SUPPORT_REMOTE}
  558. PopStatus;
  559. {$endif SUPPORT_REMOTE}
  560. end;
  561. {$ifndef NODEBUG}
  562. constructor TDebugController.Init;
  563. begin
  564. inherited Init;
  565. CenterDebuggerRow:=IniCenterDebuggerRow;
  566. Disableallinvalidbreakpoints:=false;
  567. NoSwitch:=False;
  568. HasExe:=false;
  569. Debugger:=@self;
  570. WindowWidth:=-1;
  571. switch_to_user:=true;
  572. GetDir(0,OrigPwd);
  573. Command('set print object off');
  574. end;
  575. procedure TDebugController.SetExe(const exefn:string);
  576. var f : string;
  577. begin
  578. f := GDBFileName(GetShortName(exefn));
  579. if (f<>'') and ExistsFile(exefn) then
  580. begin
  581. LoadFile(f);
  582. HasExe:=true;
  583. Command('b FPC_BREAK_ERROR');
  584. FPCBreakErrorNumber:=last_breakpoint_number;
  585. {$ifdef FrameNameKnown}
  586. { this fails in GDB 5.1 because
  587. GDB replies that there is an attempt to dereference
  588. a generic pointer...
  589. test delayed in DoSourceLine... PM
  590. Command('cond '+IntToStr(FPCBreakErrorNumber)+
  591. ' (('+FrameName+' + 8)^ <> 0) or'+
  592. ' (('+FrameName+' + 12)^ <> 0)'); }
  593. {$endif FrameNameKnown}
  594. SetArgs(GetRunParameters);
  595. SetSourceDirs;
  596. InsertBreakpoints;
  597. ReadWatches;
  598. end
  599. else
  600. begin
  601. HasExe:=false;
  602. Command('file');
  603. end;
  604. end;
  605. procedure TDebugController.SetWidth(AWidth : longint);
  606. begin
  607. WindowWidth:=AWidth;
  608. Command('set width '+inttostr(WindowWidth));
  609. end;
  610. procedure TDebugController.SetSourceDirs;
  611. var f,s: ansistring;
  612. i : longint;
  613. Dir : SearchRec;
  614. begin
  615. f:=GetSourceDirectories+';'+OrigPwd;
  616. repeat
  617. i:=pos(';',f);
  618. if i=0 then
  619. s:=f
  620. else
  621. begin
  622. s:=copy(f,1,i-1);
  623. system.delete(f,1,i);
  624. end;
  625. DefaultReplacements(s);
  626. if (pos('*',s)=0) and ExistsDir(s) then
  627. Command('dir '+GDBFileName(GetShortName(s)))
  628. { we should also handle the /* cases of -Fu option }
  629. else if pos('*',s)>0 then
  630. begin
  631. Dos.FindFirst(s,Directory,Dir);
  632. { the '*' can only be in the last dir level }
  633. s:=DirOf(s);
  634. while Dos.DosError=0 do
  635. begin
  636. if ((Dir.attr and Directory) <> 0) and ExistsDir(s+Dir.Name) then
  637. Command('dir '+GDBFileName(GetShortName(s+Dir.Name)));
  638. Dos.FindNext(Dir);
  639. end;
  640. Dos.FindClose(Dir);
  641. end;
  642. until i=0;
  643. end;
  644. procedure TDebugController.InsertBreakpoints;
  645. procedure DoInsert(PB : PBreakpoint);
  646. begin
  647. PB^.Insert;
  648. end;
  649. begin
  650. BreakpointsCollection^.ForEach(@DoInsert);
  651. Disableallinvalidbreakpoints:=false;
  652. end;
  653. procedure TDebugController.ReadWatches;
  654. procedure DoRead(PB : PWatch);
  655. begin
  656. PB^.Get_new_value;
  657. end;
  658. begin
  659. WatchesCollection^.ForEach(@DoRead);
  660. If Assigned(WatchesWindow) then
  661. WatchesWindow^.Update;
  662. end;
  663. procedure TDebugController.RereadWatches;
  664. procedure DoRead(PB : PWatch);
  665. begin
  666. PB^.Force_new_value;
  667. end;
  668. begin
  669. WatchesCollection^.ForEach(@DoRead);
  670. If Assigned(WatchesWindow) then
  671. WatchesWindow^.Update;
  672. end;
  673. procedure TDebugController.RemoveBreakpoints;
  674. procedure DoDelete(PB : PBreakpoint);
  675. begin
  676. PB^.Remove;
  677. end;
  678. begin
  679. BreakpointsCollection^.ForEach(@DoDelete);
  680. end;
  681. procedure TDebugController.ResetBreakpointsValues;
  682. procedure DoResetVal(PB : PBreakpoint);
  683. begin
  684. PB^.ResetValues;
  685. end;
  686. begin
  687. BreakpointsCollection^.ForEach(@DoResetVal);
  688. end;
  689. destructor TDebugController.Done;
  690. begin
  691. { kill the program if running }
  692. Reset;
  693. RemoveBreakpoints;
  694. inherited Done;
  695. end;
  696. procedure TDebugController.Run;
  697. {$ifdef Unix}
  698. var
  699. Debuggeefile : text;
  700. ResetOK, TTYUsed : boolean;
  701. {$endif Unix}
  702. {$ifdef PALMOSGDB}
  703. const
  704. TargetProtocol = 'palmos';
  705. {$else}
  706. const
  707. TargetProtocol = 'remote';
  708. {$endif PALMOSGDB}
  709. {$ifdef SUPPORT_REMOTE}
  710. var
  711. S,ErrorStr : string;
  712. {$endif SUPPORT_REMOTE}
  713. begin
  714. ResetBreakpointsValues;
  715. {$ifdef SUPPORT_REMOTE}
  716. NoSwitch:=true;
  717. isRemoteDebugging:=false;
  718. {$ifndef CROSSGDB}
  719. If (RemoteMachine<>'') and (RemotePort<>'') then
  720. {$else CROSSGDB}
  721. if true then
  722. {$endif CROSSGDB}
  723. begin
  724. isRemoteDebugging:=true;
  725. S:=RemoteMachine;
  726. If pos('@',S)>0 then
  727. S:=copy(S,pos('@',S)+1,High(S));
  728. If RemotePort<>'' then
  729. S:=S+':'+RemotePort;
  730. {$ifdef PALMOSGDB}
  731. { set the default value for PalmOS }
  732. If S='' then
  733. S:='localhost:2000';
  734. {$endif PALMOSGDB}
  735. PushStatus(msg_connectingto+S);
  736. Command('target '+TargetProtocol+' '+S);
  737. if Error then
  738. begin
  739. ErrorStr:=strpas(GetError);
  740. ErrorBox(#3'Error in "target '+TargetProtocol+'"'#13#3+ErrorStr,nil);
  741. PopStatus;
  742. exit;
  743. end;
  744. PopStatus;
  745. end
  746. else
  747. begin
  748. {$endif SUPPORT_REMOTE}
  749. {$ifdef Windows}
  750. { Run the debugge in another console }
  751. if DebuggeeTTY<>'' then
  752. Command('set new-console on')
  753. else
  754. Command('set new-console off');
  755. NoSwitch:=DebuggeeTTY<>'';
  756. {$endif Windows}
  757. {$ifdef Unix}
  758. { Run the debuggee in another tty }
  759. if DebuggeeTTY <> '' then
  760. begin
  761. {$I-}
  762. Assign(Debuggeefile,DebuggeeTTY);
  763. system.Reset(Debuggeefile);
  764. ResetOK:=IOResult=0;
  765. If ResetOK and (IsATTY(textrec(Debuggeefile).handle)<>-1) then
  766. begin
  767. Command('tty '+DebuggeeTTY);
  768. TTYUsed:=true;
  769. end
  770. else
  771. begin
  772. Command('tty ');
  773. TTYUsed:=false;
  774. end;
  775. if ResetOK then
  776. close(Debuggeefile);
  777. if TTYUsed and (DebuggeeTTY<>TTYName(stdout)) then
  778. NoSwitch:= true
  779. else
  780. NoSwitch:=false;
  781. end
  782. else
  783. begin
  784. if TTYName(input)<>'' then
  785. Command('tty '+TTYName(input));
  786. NoSwitch := false;
  787. end;
  788. {$endif Unix}
  789. {$ifdef SUPPORT_REMOTE}
  790. end;
  791. {$endif SUPPORT_REMOTE}
  792. { Switch to user screen to get correct handles }
  793. UserScreen;
  794. { Don't try to print GDB messages while in User Screen mode }
  795. If assigned(GDBWindow) then
  796. GDBWindow^.Editor^.Lock;
  797. {$ifdef SUPPORT_REMOTE}
  798. if isRemoteDebugging then
  799. begin
  800. inc(init_count);
  801. { pass the stop in start code }
  802. Command('continue');
  803. end else
  804. {$endif SUPPORT_REMOTE}
  805. { Set cwd for debuggee }
  806. SetDir(GetRunDir);
  807. inherited Run;
  808. { Restore cwd for IDE }
  809. SetDir(StartupDir);
  810. DebuggerScreen;
  811. If assigned(GDBWindow) then
  812. GDBWindow^.Editor^.UnLock;
  813. IDEApp.SetCmdState([cmResetDebugger,cmUntilReturn],true);
  814. IDEApp.UpdateRunMenu(true);
  815. UpdateDebugViews;
  816. end;
  817. function TDebugController.IsRunning : boolean;
  818. begin
  819. IsRunning:=debuggee_started;
  820. end;
  821. procedure TDebugController.Continue;
  822. begin
  823. {$ifdef NODEBUG}
  824. NoDebugger;
  825. {$else}
  826. if not debuggee_started then
  827. Run
  828. else
  829. inherited Continue;
  830. UpdateDebugViews;
  831. {$endif NODEBUG}
  832. end;
  833. procedure TDebugController.UntilReturn;
  834. begin
  835. Command('finish');
  836. UpdateDebugViews;
  837. { We could try to get the return value !
  838. Not done yet }
  839. end;
  840. procedure TDebugController.CommandBegin(const s:string);
  841. begin
  842. if assigned(GDBWindow) and (in_command>1) then
  843. begin
  844. { We should do something special for errors !! }
  845. If StrLen(GetError)>0 then
  846. GDBWindow^.WriteErrorText(GetError);
  847. GDBWindow^.WriteOutputText(GetOutput);
  848. end;
  849. if assigned(GDBWindow) then
  850. GDBWindow^.WriteString(S);
  851. end;
  852. procedure TDebugController.CommandEnd(const s:string);
  853. begin
  854. if assigned(GDBWindow) and (in_command<=1) then
  855. begin
  856. { We should do something special for errors !! }
  857. If StrLen(GetError)>0 then
  858. GDBWindow^.WriteErrorText(GetError);
  859. GDBWindow^.WriteOutputText(GetOutput);
  860. GDBWindow^.Editor^.TextEnd;
  861. end;
  862. end;
  863. function TDebugController.AllowQuit : boolean;
  864. begin
  865. if IsRunning then
  866. begin
  867. if ConfirmBox('Really quit GDB window'#13+
  868. 'and kill running program?',nil,true)=cmYes then
  869. begin
  870. Reset;
  871. DoneGDBWindow;
  872. {AllowQuit:=true;}
  873. AllowQuit:=false;
  874. end
  875. else
  876. AllowQuit:=false;
  877. end
  878. else if ConfirmBox('Really quit GDB window?',nil,true)=cmYes then
  879. begin
  880. DoneGDBWindow;
  881. {AllowQuit:=true;}
  882. AllowQuit:=false;
  883. end
  884. else
  885. AllowQuit:=false;
  886. end;
  887. procedure TDebugController.ResetDebuggerRows;
  888. procedure ResetDebuggerRow(P: PView);
  889. begin
  890. if assigned(P) and
  891. (TypeOf(P^)=TypeOf(TSourceWindow)) then
  892. PSourceWindow(P)^.Editor^.SetLineFlagExclusive(lfDebuggerRow,-1);
  893. end;
  894. begin
  895. Desktop^.ForEach(@ResetDebuggerRow);
  896. end;
  897. procedure TDebugController.Reset;
  898. begin
  899. inherited Reset;
  900. { we need to free the executable
  901. if we want to recompile it }
  902. SetExe('');
  903. NoSwitch:=false;
  904. { In case we have something that the compiler touched }
  905. If IDEApp.IsRunning then
  906. begin
  907. IDEApp.SetCmdState([cmResetDebugger,cmUntilReturn],false);
  908. IDEApp.UpdateRunMenu(false);
  909. AskToReloadAllModifiedFiles;
  910. ResetDebuggerRows;
  911. end;
  912. end;
  913. procedure TDebugController.AnnotateError;
  914. var errornb : longint;
  915. begin
  916. if error then
  917. begin
  918. errornb:=error_num;
  919. UpdateDebugViews;
  920. ErrorBox(#3'Error within GDB'#13#3'Error code = %d',@errornb);
  921. end;
  922. end;
  923. function TDebugController.GetValue(Const expr : string) : pchar;
  924. var
  925. p,p2,p3 : pchar;
  926. begin
  927. if WindowWidth<>-1 then
  928. Command('set width 0xffffffff');
  929. Command('p '+expr);
  930. p:=GetOutput;
  931. p3:=nil;
  932. if assigned(p) and (p[strlen(p)-1]=#10) then
  933. begin
  934. p3:=p+strlen(p)-1;
  935. p3^:=#0;
  936. end;
  937. if assigned(p) then
  938. p2:=strpos(p,'=')
  939. else
  940. p2:=nil;
  941. if assigned(p2) then
  942. p:=p2+1;
  943. while p^ in [' ',TAB] do
  944. inc(p);
  945. { get rid of type }
  946. if p^ = '(' then
  947. p:=strpos(p,')')+1;
  948. while p^ in [' ',TAB] do
  949. inc(p);
  950. if assigned(p) then
  951. GetValue:=StrNew(p)
  952. else
  953. GetValue:=StrNew(GetError);
  954. if assigned(p3) then
  955. p3^:=#10;
  956. got_error:=false;
  957. if WindowWidth<>-1 then
  958. Command('set width '+IntToStr(WindowWidth));
  959. end;
  960. function TDebugController.GetFramePointer : CORE_ADDR;
  961. var
  962. st : string;
  963. p : longint;
  964. begin
  965. {$ifdef FrameNameKnown}
  966. Command('p /d '+FrameName);
  967. st:=strpas(GetOutput);
  968. p:=pos('=',st);
  969. while (p<length(st)) and (st[p+1] in [' ',#9]) do
  970. inc(p);
  971. Delete(st,1,p);
  972. p:=1;
  973. while (st[p] in ['0'..'9']) do
  974. inc(p);
  975. Delete(st,p,High(st));
  976. GetFramePointer:=StrToCard(st);
  977. {$else not FrameNameKnown}
  978. GetFramePointer:=0;
  979. {$endif not FrameNameKnown}
  980. end;
  981. function TDebugController.GetLongintAt(addr : CORE_ADDR) : longint;
  982. var
  983. st : string;
  984. p : longint;
  985. begin
  986. Command('x /wd 0x'+hexstr(longint(addr),8));
  987. st:=strpas(GetOutput);
  988. p:=pos(':',st);
  989. while (p<length(st)) and (st[p+1] in [' ',#9]) do
  990. inc(p);
  991. Delete(st,1,p);
  992. p:=1;
  993. while (st[p] in ['0'..'9']) do
  994. inc(p);
  995. Delete(st,p,High(st));
  996. GetLongintAt:=StrToInt(st);
  997. end;
  998. function TDebugController.GetPointerAt(addr : CORE_ADDR) : CORE_ADDR;
  999. var
  1000. st : string;
  1001. p : longint;
  1002. code : integer;
  1003. begin
  1004. Command('x /wx 0x'+hexstr(PtrInt(addr),sizeof(PtrInt)*2));
  1005. st:=strpas(GetOutput);
  1006. p:=pos(':',st);
  1007. while (p<length(st)) and (st[p+1] in [' ',#9]) do
  1008. inc(p);
  1009. if (p<length(st)) and (st[p+1]='$') then
  1010. inc(p);
  1011. Delete(st,1,p);
  1012. p:=1;
  1013. while (st[p] in ['0'..'9','A'..'F','a'..'f']) do
  1014. inc(p);
  1015. Delete(st,p,High(st));
  1016. Val('$'+st,GetPointerAt,code);
  1017. end;
  1018. procedure TDebugController.DoSelectSourceLine(const fn:string;line:longint);
  1019. var
  1020. W: PSourceWindow;
  1021. Found : boolean;
  1022. PB : PBreakpoint;
  1023. S : String;
  1024. BreakIndex : longint;
  1025. stop_addr : CORE_ADDR;
  1026. i,ExitCode : longint;
  1027. ExitAddr,ExitFrame : CORE_ADDR;
  1028. const
  1029. { try to find the parameters }
  1030. FirstArgOffset = -sizeof(pointer);
  1031. SecondArgOffset = 2*-sizeof(pointer);
  1032. ThirdArgOffset = 3*-sizeof(pointer);
  1033. begin
  1034. BreakIndex:=stop_breakpoint_number;
  1035. Desktop^.Lock;
  1036. { 0 based line count in Editor }
  1037. if Line>0 then
  1038. dec(Line);
  1039. S:=fn;
  1040. stop_addr:=current_pc;
  1041. if (BreakIndex=FPCBreakErrorNumber) then
  1042. begin
  1043. { Procedure HandleErrorAddrFrame
  1044. (Errno : longint;addr,frame : longint);
  1045. [public,alias:'FPC_BREAK_ERROR']; }
  1046. {$ifdef FrameNameKnown}
  1047. ExitCode:=GetLongintAt(GetFramePointer+FirstArgOffset);
  1048. ExitAddr:=GetPointerAt(GetFramePointer+SecondArgOffset);
  1049. ExitFrame:=GetPointerAt(GetFramePointer+ThirdArgOffset);
  1050. if (ExitCode=0) and (ExitAddr=0) then
  1051. begin
  1052. Desktop^.Unlock;
  1053. Command('continue');
  1054. exit;
  1055. end;
  1056. { forget all old frames }
  1057. clear_frames;
  1058. { record new frames }
  1059. Command('backtrace');
  1060. for i:=0 to frame_count-1 do
  1061. begin
  1062. with frames[i]^ do
  1063. begin
  1064. if ExitAddr=address then
  1065. begin
  1066. Command('f '+IntToStr(i));
  1067. if assigned(file_name) then
  1068. begin
  1069. s:=strpas(file_name);
  1070. line:=line_number;
  1071. stop_addr:=address;
  1072. end;
  1073. break;
  1074. end;
  1075. end;
  1076. end;
  1077. {$endif FrameNameKnown}
  1078. end;
  1079. { Update Disassembly position }
  1080. if Assigned(DisassemblyWindow) then
  1081. DisassemblyWindow^.SetCurAddress(stop_addr);
  1082. if (fn=LastFileName) then
  1083. begin
  1084. W:=PSourceWindow(LastSource);
  1085. if assigned(W) then
  1086. begin
  1087. W^.Editor^.SetCurPtr(0,Line);
  1088. W^.Editor^.TrackCursor(CenterDebuggerRow);
  1089. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,Line);
  1090. UpdateDebugViews;
  1091. {if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  1092. handled by SelectInDebugSession}
  1093. W^.SelectInDebugSession;
  1094. InvalidSourceLine:=false;
  1095. end
  1096. else
  1097. InvalidSourceLine:=true;
  1098. end
  1099. else
  1100. begin
  1101. if s='' then
  1102. W:=nil
  1103. else
  1104. W:=TryToOpenFile(nil,s,0,Line,false);
  1105. if assigned(W) then
  1106. begin
  1107. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,Line);
  1108. W^.Editor^.TrackCursor(CenterDebuggerRow);
  1109. UpdateDebugViews;
  1110. {if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  1111. handled by SelectInDebugSession}
  1112. W^.SelectInDebugSession;
  1113. LastSource:=W;
  1114. InvalidSourceLine:=false;
  1115. end
  1116. { only search a file once }
  1117. else
  1118. begin
  1119. Desktop^.UnLock;
  1120. if s='' then
  1121. Found:=false
  1122. else
  1123. { it is easier to handle with a * at the end }
  1124. Found:=IDEApp.OpenSearch(s+'*');
  1125. Desktop^.Lock;
  1126. if not Found then
  1127. begin
  1128. InvalidSourceLine:=true;
  1129. LastSource:=Nil;
  1130. { Show the stack in that case }
  1131. InitStackWindow;
  1132. UpdateDebugViews;
  1133. StackWindow^.MakeFirst;
  1134. end
  1135. else
  1136. begin
  1137. { should now be open }
  1138. W:=TryToOpenFile(nil,s,0,Line,true);
  1139. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,Line);
  1140. W^.Editor^.TrackCursor(CenterDebuggerRow);
  1141. UpdateDebugViews;
  1142. {if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  1143. handled by SelectInDebugSession}
  1144. W^.SelectInDebugSession;
  1145. LastSource:=W;
  1146. InvalidSourceLine:=false;
  1147. end;
  1148. end;
  1149. end;
  1150. LastFileName:=s;
  1151. Desktop^.UnLock;
  1152. if BreakIndex>0 then
  1153. begin
  1154. PB:=BreakpointsCollection^.GetGDB(BreakIndex);
  1155. if (BreakIndex=FPCBreakErrorNumber) then
  1156. begin
  1157. if (ExitCode<>0) or (ExitAddr<>0) then
  1158. WarningBox(#3'Run Time Error '+IntToStr(ExitCode)+#13+
  1159. #3'Error address $'+HexStr(ExitAddr,8),nil)
  1160. else
  1161. WarningBox(#3'Run Time Error',nil);
  1162. end
  1163. else if not assigned(PB) then
  1164. begin
  1165. WarningBox(#3'Stopped by breakpoint '+IntToStr(BreakIndex),nil);
  1166. end
  1167. { For watch we should get old and new value !! }
  1168. else if (Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive)) and
  1169. (PB^.typ<>bt_file_line) and (PB^.typ<>bt_function) and
  1170. (PB^.typ<>bt_address) then
  1171. begin
  1172. Command('p '+GetStr(PB^.Name));
  1173. S:=GetPChar(GetOutput);
  1174. got_error:=false;
  1175. If Pos('=',S)>0 then
  1176. S:=Copy(S,Pos('=',S)+1,255);
  1177. If S[Length(S)]=#10 then
  1178. Delete(S,Length(S),1);
  1179. if Assigned(PB^.OldValue) then
  1180. DisposeStr(PB^.OldValue);
  1181. PB^.OldValue:=PB^.CurrentValue;
  1182. PB^.CurrentValue:=NewStr(S);
  1183. If PB^.typ=bt_function then
  1184. WarningBox(#3'GDB stopped due to'#13+
  1185. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name),nil)
  1186. else if (GetStr(PB^.OldValue)<>S) then
  1187. WarningBox(#3'GDB stopped due to'#13+
  1188. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
  1189. #3+'Old value = '+GetStr(PB^.OldValue)+#13+
  1190. #3+'New value = '+GetStr(PB^.CurrentValue),nil)
  1191. else
  1192. WarningBox(#3'GDB stopped due to'#13+
  1193. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
  1194. #3+' value = '+GetStr(PB^.CurrentValue),nil);
  1195. end;
  1196. end;
  1197. end;
  1198. procedure TDebugController.DoUserSignal;
  1199. var P :Array[1..2] of pstring;
  1200. S1, S2 : string;
  1201. begin
  1202. S1:=strpas(signal_name);
  1203. S2:=strpas(signal_string);
  1204. P[1]:=@S1;
  1205. P[2]:=@S2;
  1206. WarningBox(msg_programsignal,@P);
  1207. end;
  1208. procedure TDebugController.DoEndSession(code:longint);
  1209. var P :Array[1..2] of longint;
  1210. begin
  1211. IDEApp.SetCmdState([cmUntilReturn,cmResetDebugger],false);
  1212. IDEApp.UpdateRunMenu(false);
  1213. ResetDebuggerRows;
  1214. LastExitCode:=Code;
  1215. If HiddenStepsCount=0 then
  1216. InformationBox(msg_programexitedwithexitcode,@code)
  1217. else
  1218. begin
  1219. P[1]:=code;
  1220. P[2]:=HiddenStepsCount;
  1221. WarningBox(msg_programexitedwithcodeandsteps,@P);
  1222. end;
  1223. { In case we have something that the compiler touched }
  1224. AskToReloadAllModifiedFiles;
  1225. {$ifdef Windows}
  1226. main_pid_valid:=false;
  1227. {$endif Windows}
  1228. end;
  1229. procedure TDebugController.DoDebuggerScreen;
  1230. {$ifdef Windows}
  1231. var
  1232. IdeMode : DWord;
  1233. {$endif Windows}
  1234. begin
  1235. if NoSwitch then
  1236. begin
  1237. PopStatus;
  1238. end
  1239. else
  1240. begin
  1241. IDEApp.ShowIDEScreen;
  1242. Message(Application,evBroadcast,cmDebuggerStopped,pointer(ptrint(RunCount)));
  1243. PopStatus;
  1244. end;
  1245. {$ifdef Windows}
  1246. if NoSwitch then
  1247. begin
  1248. { Ctrl-C as normal char }
  1249. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @IdeMode);
  1250. IdeMode:=(IdeMode or ENABLE_MOUSE_INPUT or ENABLE_WINDOW_INPUT) and not ENABLE_PROCESSED_INPUT;
  1251. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), IdeMode);
  1252. end;
  1253. ChangeDebuggeeWindowTitleTo(Stopped_State);
  1254. {$endif Windows}
  1255. end;
  1256. procedure TDebugController.DoUserScreen;
  1257. {$ifdef Windows}
  1258. var
  1259. IdeMode : DWord;
  1260. {$endif Windows}
  1261. begin
  1262. Inc(RunCount);
  1263. if NoSwitch then
  1264. begin
  1265. {$ifdef SUPPORT_REMOTE}
  1266. PushStatus(msg_runningremotely+RemoteMachine);
  1267. {$else not SUPPORT_REMOTE}
  1268. {$ifdef Unix}
  1269. PushStatus(msg_runninginanotherwindow+DebuggeeTTY);
  1270. {$else not Unix}
  1271. PushStatus(msg_runninginanotherwindow);
  1272. {$endif Unix}
  1273. {$endif not SUPPORT_REMOTE}
  1274. end
  1275. else
  1276. begin
  1277. PushStatus(msg_runningprogram);
  1278. IDEApp.ShowUserScreen;
  1279. end;
  1280. {$ifdef Windows}
  1281. if NoSwitch then
  1282. begin
  1283. { Ctrl-C as interrupt }
  1284. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @IdeMode);
  1285. IdeMode:=(IdeMode or ENABLE_MOUSE_INPUT or ENABLE_PROCESSED_INPUT or ENABLE_WINDOW_INPUT);
  1286. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), IdeMode);
  1287. end;
  1288. ChangeDebuggeeWindowTitleTo(Running_State);
  1289. {$endif Windows}
  1290. end;
  1291. {$endif NODEBUG}
  1292. {****************************************************************************
  1293. TBreakpoint
  1294. ****************************************************************************}
  1295. function ActiveBreakpoints : boolean;
  1296. var
  1297. IsActive : boolean;
  1298. procedure TestActive(PB : PBreakpoint);
  1299. begin
  1300. If PB^.state=bs_enabled then
  1301. IsActive:=true;
  1302. end;
  1303. begin
  1304. IsActive:=false;
  1305. If assigned(BreakpointsCollection) then
  1306. BreakpointsCollection^.ForEach(@TestActive);
  1307. ActiveBreakpoints:=IsActive;
  1308. end;
  1309. constructor TBreakpoint.Init_function(Const AFunc : String);
  1310. begin
  1311. typ:=bt_function;
  1312. state:=bs_enabled;
  1313. GDBState:=bs_deleted;
  1314. Name:=NewStr(AFunc);
  1315. FileName:=nil;
  1316. Line:=0;
  1317. IgnoreCount:=0;
  1318. Commands:=nil;
  1319. Conditions:=nil;
  1320. OldValue:=nil;
  1321. CurrentValue:=nil;
  1322. end;
  1323. constructor TBreakpoint.Init_Address(Const AAddress : String);
  1324. begin
  1325. typ:=bt_address;
  1326. state:=bs_enabled;
  1327. GDBState:=bs_deleted;
  1328. Name:=NewStr(AAddress);
  1329. FileName:=nil;
  1330. Line:=0;
  1331. IgnoreCount:=0;
  1332. Commands:=nil;
  1333. Conditions:=nil;
  1334. OldValue:=nil;
  1335. CurrentValue:=nil;
  1336. end;
  1337. constructor TBreakpoint.Init_Empty;
  1338. begin
  1339. typ:=bt_function;
  1340. state:=bs_enabled;
  1341. GDBState:=bs_deleted;
  1342. Name:=Nil;
  1343. FileName:=nil;
  1344. Line:=0;
  1345. IgnoreCount:=0;
  1346. Commands:=nil;
  1347. Conditions:=nil;
  1348. OldValue:=nil;
  1349. CurrentValue:=nil;
  1350. end;
  1351. constructor TBreakpoint.Init_type(atyp : BreakpointType;Const AnExpr : String);
  1352. begin
  1353. typ:=atyp;
  1354. state:=bs_enabled;
  1355. GDBState:=bs_deleted;
  1356. Name:=NewStr(AnExpr);
  1357. IgnoreCount:=0;
  1358. Commands:=nil;
  1359. Conditions:=nil;
  1360. OldValue:=nil;
  1361. CurrentValue:=nil;
  1362. end;
  1363. constructor TBreakpoint.Init_file_line(AFile : String; ALine : longint);
  1364. var
  1365. CurDir : String;
  1366. begin
  1367. typ:=bt_file_line;
  1368. state:=bs_enabled;
  1369. GDBState:=bs_deleted;
  1370. AFile:=FEXpand(AFile);
  1371. (*
  1372. { d:test.pas:12 does not work !! }
  1373. { I do not know how to solve this if
  1374. if (Length(AFile)>1) and (AFile[2]=':') then
  1375. AFile:=Copy(AFile,3,255); }
  1376. {$ifdef Unix}
  1377. CurDir:=GetCurDir;
  1378. {$else}
  1379. CurDir:=LowerCaseStr(GetCurDir);
  1380. {$endif Unix}
  1381. if Pos(CurDir,OSFileName(AFile))=1 then
  1382. FileName:=NewStr(Copy(OSFileName(AFile),length(CurDir)+1,255))
  1383. else
  1384. *)
  1385. FileName:=NewStr(OSFileName(AFile));
  1386. Name:=nil;
  1387. Line:=ALine;
  1388. IgnoreCount:=0;
  1389. Commands:=nil;
  1390. Conditions:=nil;
  1391. OldValue:=nil;
  1392. CurrentValue:=nil;
  1393. end;
  1394. constructor TBreakpoint.Load(var S: TStream);
  1395. var
  1396. FName : PString;
  1397. begin
  1398. S.Read(typ,SizeOf(BreakpointType));
  1399. S.Read(state,SizeOf(BreakpointState));
  1400. GDBState:=bs_deleted;
  1401. case typ of
  1402. bt_file_line :
  1403. begin
  1404. { convert to current target }
  1405. FName:=S.ReadStr;
  1406. FileName:=NewStr(OSFileName(GetStr(FName)));
  1407. If Assigned(FName) then
  1408. DisposeStr(FName);
  1409. S.Read(Line,SizeOf(Line));
  1410. Name:=nil;
  1411. end;
  1412. else
  1413. begin
  1414. Name:=S.ReadStr;
  1415. Line:=0;
  1416. FileName:=nil;
  1417. end;
  1418. end;
  1419. S.Read(IgnoreCount,SizeOf(IgnoreCount));
  1420. Commands:=S.StrRead;
  1421. Conditions:=S.ReadStr;
  1422. OldValue:=nil;
  1423. CurrentValue:=nil;
  1424. end;
  1425. procedure TBreakpoint.Store(var S: TStream);
  1426. var
  1427. St : String;
  1428. begin
  1429. S.Write(typ,SizeOf(BreakpointType));
  1430. S.Write(state,SizeOf(BreakpointState));
  1431. case typ of
  1432. bt_file_line :
  1433. begin
  1434. st:=OSFileName(GetStr(FileName));
  1435. S.WriteStr(@St);
  1436. S.Write(Line,SizeOf(Line));
  1437. end;
  1438. else
  1439. begin
  1440. S.WriteStr(Name);
  1441. end;
  1442. end;
  1443. S.Write(IgnoreCount,SizeOf(IgnoreCount));
  1444. S.StrWrite(Commands);
  1445. S.WriteStr(Conditions);
  1446. end;
  1447. procedure TBreakpoint.Insert;
  1448. var
  1449. p,p2 : pchar;
  1450. st : string;
  1451. begin
  1452. {$ifndef NODEBUG}
  1453. If not assigned(Debugger) then Exit;
  1454. Remove;
  1455. Debugger^.last_breakpoint_number:=0;
  1456. if (GDBState=bs_deleted) and (state=bs_enabled) then
  1457. begin
  1458. if (typ=bt_file_line) and assigned(FileName) then
  1459. Debugger^.Command('break '+GDBFileName(NameAndExtOf(GetStr(FileName)))+':'+IntToStr(Line))
  1460. else if (typ=bt_function) and assigned(name) then
  1461. Debugger^.Command('break '+name^)
  1462. else if (typ=bt_address) and assigned(name) then
  1463. Debugger^.Command('break *0x'+name^)
  1464. else if (typ=bt_watch) and assigned(name) then
  1465. Debugger^.Command('watch '+name^)
  1466. else if (typ=bt_awatch) and assigned(name) then
  1467. Debugger^.Command('awatch '+name^)
  1468. else if (typ=bt_rwatch) and assigned(name) then
  1469. Debugger^.Command('rwatch '+name^);
  1470. if Debugger^.last_breakpoint_number<>0 then
  1471. begin
  1472. GDBIndex:=Debugger^.last_breakpoint_number;
  1473. GDBState:=bs_enabled;
  1474. Debugger^.Command('cond '+IntToStr(GDBIndex)+' '+GetStr(Conditions));
  1475. If IgnoreCount>0 then
  1476. Debugger^.Command('ignore '+IntToStr(GDBIndex)+' '+IntToStr(IgnoreCount));
  1477. If Assigned(Commands) then
  1478. begin
  1479. {Commands are not handled yet }
  1480. Debugger^.Command('command '+IntToStr(GDBIndex));
  1481. p:=commands;
  1482. while assigned(p) do
  1483. begin
  1484. p2:=strscan(p,#10);
  1485. if assigned(p2) then
  1486. p2^:=#0;
  1487. st:=strpas(p);
  1488. Debugger^.command(st);
  1489. if assigned(p2) then
  1490. p2^:=#10;
  1491. p:=p2;
  1492. if assigned(p) then
  1493. inc(p);
  1494. end;
  1495. Debugger^.Command('end');
  1496. end;
  1497. end
  1498. else
  1499. { Here there was a problem !! }
  1500. begin
  1501. GDBIndex:=0;
  1502. if not Debugger^.Disableallinvalidbreakpoints then
  1503. begin
  1504. if (typ=bt_file_line) and assigned(FileName) then
  1505. begin
  1506. ClearFormatParams;
  1507. AddFormatParamStr(NameAndExtOf(FileName^));
  1508. AddFormatParamInt(Line);
  1509. if ChoiceBox(msg_couldnotsetbreakpointat,@FormatParams,[btn_ok,button_DisableAllBreakpoints],false)=cmUserBtn2 then
  1510. Debugger^.Disableallinvalidbreakpoints:=true;
  1511. end
  1512. else
  1513. begin
  1514. ClearFormatParams;
  1515. AddFormatParamStr(BreakpointTypeStr[typ]);
  1516. AddFormatParamStr(GetStr(Name));
  1517. if ChoiceBox(msg_couldnotsetbreakpointtype,@FormatParams,[btn_ok,button_DisableAllBreakpoints],false)=cmUserBtn2 then
  1518. Debugger^.Disableallinvalidbreakpoints:=true;
  1519. end;
  1520. end;
  1521. state:=bs_disabled;
  1522. UpdateSource;
  1523. end;
  1524. end
  1525. else if (GDBState=bs_disabled) and (state=bs_enabled) then
  1526. Enable
  1527. else if (GDBState=bs_enabled) and (state=bs_disabled) then
  1528. Disable;
  1529. {$endif NODEBUG}
  1530. end;
  1531. procedure TBreakpoint.Remove;
  1532. begin
  1533. {$ifndef NODEBUG}
  1534. If not assigned(Debugger) then Exit;
  1535. if GDBIndex>0 then
  1536. Debugger^.Command('delete '+IntToStr(GDBIndex));
  1537. GDBIndex:=0;
  1538. GDBState:=bs_deleted;
  1539. {$endif NODEBUG}
  1540. end;
  1541. procedure TBreakpoint.Enable;
  1542. begin
  1543. {$ifndef NODEBUG}
  1544. If not assigned(Debugger) then Exit;
  1545. if GDBIndex>0 then
  1546. Debugger^.Command('enable '+IntToStr(GDBIndex))
  1547. else
  1548. Insert;
  1549. GDBState:=bs_disabled;
  1550. {$endif NODEBUG}
  1551. end;
  1552. procedure TBreakpoint.Disable;
  1553. begin
  1554. {$ifndef NODEBUG}
  1555. If not assigned(Debugger) then Exit;
  1556. if GDBIndex>0 then
  1557. Debugger^.Command('disable '+IntToStr(GDBIndex));
  1558. GDBState:=bs_disabled;
  1559. {$endif NODEBUG}
  1560. end;
  1561. procedure TBreakpoint.ResetValues;
  1562. begin
  1563. if assigned(OldValue) then
  1564. DisposeStr(OldValue);
  1565. OldValue:=nil;
  1566. if assigned(CurrentValue) then
  1567. DisposeStr(CurrentValue);
  1568. CurrentValue:=nil;
  1569. end;
  1570. procedure TBreakpoint.UpdateSource;
  1571. var W: PSourceWindow;
  1572. b : boolean;
  1573. begin
  1574. if typ=bt_file_line then
  1575. begin
  1576. W:=SearchOnDesktop(OSFileName(GetStr(FileName)),false);
  1577. If assigned(W) then
  1578. begin
  1579. if state=bs_enabled then
  1580. b:=true
  1581. else
  1582. b:=false;
  1583. W^.Editor^.SetLineFlagState(Line-1,lfBreakpoint,b);
  1584. end;
  1585. end;
  1586. end;
  1587. destructor TBreakpoint.Done;
  1588. begin
  1589. Remove;
  1590. ResetValues;
  1591. if assigned(Name) then
  1592. DisposeStr(Name);
  1593. if assigned(FileName) then
  1594. DisposeStr(FileName);
  1595. if assigned(Conditions) then
  1596. DisposeStr(Conditions);
  1597. if assigned(Commands) then
  1598. StrDispose(Commands);
  1599. inherited Done;
  1600. end;
  1601. {****************************************************************************
  1602. TBreakpointCollection
  1603. ****************************************************************************}
  1604. function TBreakpointCollection.At(Index: Integer): PBreakpoint;
  1605. begin
  1606. At:=inherited At(Index);
  1607. end;
  1608. procedure TBreakpointCollection.Update;
  1609. begin
  1610. {$ifndef NODEBUG}
  1611. if assigned(Debugger) then
  1612. begin
  1613. Debugger^.RemoveBreakpoints;
  1614. Debugger^.InsertBreakpoints;
  1615. end;
  1616. {$endif NODEBUG}
  1617. if assigned(BreakpointsWindow) then
  1618. BreakpointsWindow^.Update;
  1619. end;
  1620. function TBreakpointCollection.GetGDB(index : longint) : PBreakpoint;
  1621. function IsNum(P : PBreakpoint) : boolean;
  1622. begin
  1623. IsNum:=P^.GDBIndex=index;
  1624. end;
  1625. begin
  1626. if index=0 then
  1627. GetGDB:=nil
  1628. else
  1629. GetGDB:=FirstThat(@IsNum);
  1630. end;
  1631. procedure TBreakpointCollection.ShowBreakpoints(W : PFPWindow);
  1632. procedure SetInSource(P : PBreakpoint);
  1633. begin
  1634. If assigned(P^.FileName) and
  1635. (OSFileName(P^.FileName^)=OSFileName(FExpand(PSourceWindow(W)^.Editor^.FileName))) then
  1636. PSourceWindow(W)^.Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,P^.state=bs_enabled);
  1637. end;
  1638. procedure SetInDisassembly(P : PBreakpoint);
  1639. var
  1640. PDL : PDisasLine;
  1641. S : string;
  1642. ps,qs,i : longint;
  1643. HAddr : PtrInt;
  1644. code : integer;
  1645. begin
  1646. for i:=0 to PDisassemblyWindow(W)^.Editor^.GetLineCount-1 do
  1647. begin
  1648. PDL:=PDisasLine(PDisassemblyWindow(W)^.Editor^.GetLine(i));
  1649. if PDL^.Address=0 then
  1650. begin
  1651. if (P^.typ=bt_file_line) then
  1652. begin
  1653. S:=PDisassemblyWindow(W)^.Editor^.GetDisplayText(i);
  1654. ps:=pos(':',S);
  1655. qs:=pos(' ',copy(S,ps+1,High(S)));
  1656. if (GDBFileName(P^.FileName^)=GDBFileName(FExpand(Copy(S,1,ps-1)))) and
  1657. (StrToInt(copy(S,ps+1,qs-1))=P^.line) then
  1658. PDisassemblyWindow(W)^.Editor^.SetLineFlagState(i,lfBreakpoint,P^.state=bs_enabled);
  1659. end;
  1660. end
  1661. else
  1662. begin
  1663. if assigned(P^.Name) then
  1664. begin
  1665. Val('$'+P^.Name^,HAddr,code);
  1666. If (P^.typ=bt_address) and (PDL^.Address=HAddr) then
  1667. PDisassemblyWindow(W)^.Editor^.SetLineFlagState(i,lfBreakpoint,P^.state=bs_enabled);
  1668. end;
  1669. end;
  1670. end;
  1671. end;
  1672. begin
  1673. if W=PFPWindow(DisassemblyWindow) then
  1674. ForEach(@SetInDisassembly)
  1675. else
  1676. ForEach(@SetInSource);
  1677. end;
  1678. procedure TBreakpointCollection.AdaptBreakpoints(Editor : PSourceEditor; Pos, Change : longint);
  1679. procedure AdaptInSource(P : PBreakpoint);
  1680. begin
  1681. If assigned(P^.FileName) and
  1682. (P^.FileName^=OSFileName(FExpand(Editor^.FileName))) then
  1683. begin
  1684. if P^.state=bs_enabled then
  1685. Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,false);
  1686. if P^.Line-1>=Pos then
  1687. begin
  1688. if (Change>0) or (P^.Line-1>=Pos-Change) then
  1689. P^.line:=P^.Line+Change
  1690. else
  1691. begin
  1692. { removing inside a ForEach call leads to problems }
  1693. { so we do that after PM }
  1694. P^.state:=bs_delete_after;
  1695. end;
  1696. end;
  1697. if P^.state=bs_enabled then
  1698. Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,true);
  1699. end;
  1700. end;
  1701. var
  1702. I : longint;
  1703. begin
  1704. ForEach(@AdaptInSource);
  1705. I:=Count-1;
  1706. While (I>=0) do
  1707. begin
  1708. if At(I)^.state=bs_delete_after then
  1709. AtFree(I);
  1710. Dec(I);
  1711. end;
  1712. end;
  1713. function TBreakpointCollection.FindBreakpointAt(Editor : PSourceEditor; Line : longint) : PBreakpoint;
  1714. function IsAtLine(P : PBreakpoint) : boolean;
  1715. begin
  1716. If assigned(P^.FileName) and
  1717. (P^.FileName^=OSFileName(FExpand(Editor^.FileName))) and
  1718. (Line=P^.Line) then
  1719. IsAtLine:=true
  1720. else
  1721. IsAtLine:=false;
  1722. end;
  1723. begin
  1724. FindBreakpointAt:=FirstThat(@IsAtLine);
  1725. end;
  1726. procedure TBreakpointCollection.ShowAllBreakpoints;
  1727. procedure SetInSource(P : PBreakpoint);
  1728. var
  1729. W : PSourceWindow;
  1730. begin
  1731. If assigned(P^.FileName) then
  1732. begin
  1733. W:=SearchOnDesktop(P^.FileName^,false);
  1734. if assigned(W) then
  1735. W^.Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,P^.state=bs_enabled);
  1736. end;
  1737. end;
  1738. begin
  1739. ForEach(@SetInSource);
  1740. end;
  1741. function TBreakpointCollection.GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
  1742. function IsThis(P : PBreakpoint) : boolean;
  1743. begin
  1744. IsThis:=(P^.typ=typ) and (GetStr(P^.Name)=S);
  1745. end;
  1746. begin
  1747. GetType:=FirstThat(@IsThis);
  1748. end;
  1749. function TBreakpointCollection.ToggleFileLine(FileName: String;LineNr : Longint) : boolean;
  1750. function IsThere(P : PBreakpoint) : boolean;
  1751. begin
  1752. IsThere:=(P^.typ=bt_file_line) and assigned(P^.FileName) and
  1753. (OSFileName(P^.FileName^)=FileName) and (P^.Line=LineNr);
  1754. end;
  1755. var
  1756. PB : PBreakpoint;
  1757. begin
  1758. ToggleFileLine:=false;
  1759. FileName:=OSFileName(FExpand(FileName));
  1760. PB:=FirstThat(@IsThere);
  1761. If Assigned(PB) then
  1762. begin
  1763. { delete it form source window }
  1764. PB^.state:=bs_disabled;
  1765. PB^.UpdateSource;
  1766. { remove from collection }
  1767. BreakpointsCollection^.free(PB);
  1768. end
  1769. else
  1770. begin
  1771. PB:= New(PBreakpoint,Init_file_line(FileName,LineNr));
  1772. if assigned(PB) then
  1773. Begin
  1774. Insert(PB);
  1775. PB^.UpdateSource;
  1776. ToggleFileLine:=true;
  1777. End;
  1778. end;
  1779. Update;
  1780. end;
  1781. {****************************************************************************
  1782. TBreakpointItem
  1783. ****************************************************************************}
  1784. constructor TBreakpointItem.Init(ABreakpoint : PBreakpoint);
  1785. begin
  1786. inherited Init;
  1787. Breakpoint:=ABreakpoint;
  1788. end;
  1789. function TBreakpointItem.GetText(MaxLen: Sw_integer): string;
  1790. var S: string;
  1791. begin
  1792. with Breakpoint^ do
  1793. begin
  1794. S:=BreakpointTypeStr[typ];
  1795. While Length(S)<10 do
  1796. S:=S+' ';
  1797. S:=S+'|';
  1798. S:=S+BreakpointStateStr[state]+' ';
  1799. While Length(S)<20 do
  1800. S:=S+' ';
  1801. S:=S+'|';
  1802. if (typ=bt_file_line) then
  1803. begin
  1804. S:=S+NameAndExtOf(GetStr(FileName))+':'+IntToStr(Line);
  1805. While Length(S)<40 do
  1806. S:=S+' ';
  1807. S:=S+'|';
  1808. S:=S+copy(DirOf(GetStr(FileName)),1,min(length(DirOf(GetStr(FileName))),29));
  1809. end
  1810. else
  1811. S:=S+GetStr(name);
  1812. While Length(S)<70 do
  1813. S:=S+' ';
  1814. S:=S+'|';
  1815. if IgnoreCount>0 then
  1816. S:=S+IntToStr(IgnoreCount);
  1817. While Length(S)<79 do
  1818. S:=S+' ';
  1819. S:=S+'|';
  1820. if assigned(Conditions) then
  1821. S:=S+' '+GetStr(Conditions);
  1822. if length(S)>MaxLen then S:=copy(S,1,MaxLen-2)+'..';
  1823. GetText:=S;
  1824. end;
  1825. end;
  1826. procedure TBreakpointItem.Selected;
  1827. begin
  1828. end;
  1829. function TBreakpointItem.GetModuleName: string;
  1830. begin
  1831. if breakpoint^.typ=bt_file_line then
  1832. GetModuleName:=GetStr(breakpoint^.FileName)
  1833. else
  1834. GetModuleName:='';
  1835. end;
  1836. {****************************************************************************
  1837. TBreakpointsListBox
  1838. ****************************************************************************}
  1839. constructor TBreakpointsListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  1840. begin
  1841. inherited Init(Bounds,1,AHScrollBar, AVScrollBar);
  1842. GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  1843. NoSelection:=true;
  1844. end;
  1845. function TBreakpointsListBox.GetLocalMenu: PMenu;
  1846. var M: PMenu;
  1847. begin
  1848. if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
  1849. M:=NewMenu(
  1850. NewItem(menu_bplocal_gotosource,'',kbNoKey,cmMsgGotoSource,hcMsgGotoSource,
  1851. NewItem(menu_bplocal_editbreakpoint,'',kbNoKey,cmEditBreakpoint,hcEditBreakpoint,
  1852. NewItem(menu_bplocal_newbreakpoint,'',kbNoKey,cmNewBreakpoint,hcNewBreakpoint,
  1853. NewItem(menu_bplocal_deletebreakpoint,'',kbNoKey,cmDeleteBreakpoint,hcDeleteBreakpoint,
  1854. NewItem(menu_bplocal_togglestate,'',kbNoKey,cmToggleBreakpoint,hcToggleBreakpoint,
  1855. nil))))));
  1856. GetLocalMenu:=M;
  1857. end;
  1858. procedure TBreakpointsListBox.HandleEvent(var Event: TEvent);
  1859. var DontClear: boolean;
  1860. begin
  1861. case Event.What of
  1862. evKeyDown :
  1863. begin
  1864. DontClear:=false;
  1865. case Event.KeyCode of
  1866. kbEnd :
  1867. FocusItem(List^.Count-1);
  1868. kbHome :
  1869. FocusItem(0);
  1870. kbEnter :
  1871. Message(@Self,evCommand,cmMsgGotoSource,nil);
  1872. kbIns :
  1873. Message(@Self,evCommand,cmNewBreakpoint,nil);
  1874. kbDel :
  1875. Message(@Self,evCommand,cmDeleteBreakpoint,nil);
  1876. else
  1877. DontClear:=true;
  1878. end;
  1879. if not DontClear then
  1880. ClearEvent(Event);
  1881. end;
  1882. evBroadcast :
  1883. case Event.Command of
  1884. cmListItemSelected :
  1885. if Event.InfoPtr=@Self then
  1886. Message(@Self,evCommand,cmEditBreakpoint,nil);
  1887. end;
  1888. evCommand :
  1889. begin
  1890. DontClear:=false;
  1891. case Event.Command of
  1892. cmMsgTrackSource :
  1893. if Range>0 then
  1894. TrackSource;
  1895. cmEditBreakpoint :
  1896. EditCurrent;
  1897. cmToggleBreakpoint :
  1898. ToggleCurrent;
  1899. cmDeleteBreakpoint :
  1900. DeleteCurrent;
  1901. cmNewBreakpoint :
  1902. EditNew;
  1903. cmMsgClear :
  1904. Clear;
  1905. else
  1906. DontClear:=true;
  1907. end;
  1908. if not DontClear then
  1909. ClearEvent(Event);
  1910. end;
  1911. end;
  1912. inherited HandleEvent(Event);
  1913. end;
  1914. procedure TBreakpointsListBox.AddBreakpoint(P: PBreakpointItem);
  1915. var W : integer;
  1916. begin
  1917. if List=nil then New(List, Init(20,20));
  1918. W:=length(P^.GetText(255));
  1919. if W>MaxWidth then
  1920. begin
  1921. MaxWidth:=W;
  1922. if HScrollBar<>nil then
  1923. HScrollBar^.SetRange(0,MaxWidth);
  1924. end;
  1925. List^.Insert(P);
  1926. SetRange(List^.Count);
  1927. if Focused=List^.Count-1-1 then
  1928. FocusItem(List^.Count-1);
  1929. P^.Breakpoint^.UpdateSource;
  1930. DrawView;
  1931. end;
  1932. function TBreakpointsListBox.GetText(Item,MaxLen: Sw_Integer): String;
  1933. var P: PBreakpointItem;
  1934. S: string;
  1935. begin
  1936. P:=List^.At(Item);
  1937. S:=P^.GetText(MaxLen);
  1938. GetText:=copy(S,1,MaxLen);
  1939. end;
  1940. procedure TBreakpointsListBox.Clear;
  1941. begin
  1942. if assigned(List) then
  1943. Dispose(List, Done);
  1944. List:=nil;
  1945. MaxWidth:=0;
  1946. SetRange(0); DrawView;
  1947. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  1948. end;
  1949. procedure TBreakpointsListBox.TrackSource;
  1950. var W: PSourceWindow;
  1951. P: PBreakpointItem;
  1952. R: TRect;
  1953. begin
  1954. (*Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  1955. if Range=0 then Exit;*)
  1956. P:=List^.At(Focused);
  1957. if P^.GetModuleName='' then Exit;
  1958. Desktop^.Lock;
  1959. GetNextEditorBounds(R);
  1960. R.B.Y:=Owner^.Origin.Y;
  1961. W:=EditorWindowFile(P^.GetModuleName);
  1962. if assigned(W) then
  1963. begin
  1964. W^.GetExtent(R);
  1965. R.B.Y:=Owner^.Origin.Y;
  1966. W^.ChangeBounds(R);
  1967. W^.Editor^.SetCurPtr(1,P^.Breakpoint^.Line);
  1968. end
  1969. else
  1970. W:=TryToOpenFile(@R,P^.GetModuleName,1,P^.Breakpoint^.Line,true);
  1971. if W<>nil then
  1972. begin
  1973. W^.Select;
  1974. W^.Editor^.TrackCursor(do_centre);
  1975. W^.Editor^.SetLineFlagExclusive(lfHighlightRow,P^.Breakpoint^.Line);
  1976. end;
  1977. if Assigned(Owner) then
  1978. Owner^.Select;
  1979. Desktop^.UnLock;
  1980. end;
  1981. procedure TBreakpointsListBox.ToggleCurrent;
  1982. var
  1983. P: PBreakpointItem;
  1984. begin
  1985. if Range=0 then Exit;
  1986. P:=List^.At(Focused);
  1987. if P=nil then Exit;
  1988. if P^.Breakpoint^.state=bs_enabled then
  1989. P^.Breakpoint^.state:=bs_disabled
  1990. else if P^.Breakpoint^.state=bs_disabled then
  1991. P^.Breakpoint^.state:=bs_enabled;
  1992. P^.Breakpoint^.UpdateSource;
  1993. BreakpointsCollection^.Update;
  1994. end;
  1995. procedure TBreakpointsListBox.EditCurrent;
  1996. var
  1997. P: PBreakpointItem;
  1998. begin
  1999. if Range=0 then Exit;
  2000. P:=List^.At(Focused);
  2001. if P=nil then Exit;
  2002. Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P^.Breakpoint)),nil);
  2003. P^.Breakpoint^.UpdateSource;
  2004. BreakpointsCollection^.Update;
  2005. end;
  2006. procedure TBreakpointsListBox.DeleteCurrent;
  2007. var
  2008. P: PBreakpointItem;
  2009. begin
  2010. if Range=0 then Exit;
  2011. P:=List^.At(Focused);
  2012. if P=nil then Exit;
  2013. { delete it form source window }
  2014. P^.Breakpoint^.state:=bs_disabled;
  2015. P^.Breakpoint^.UpdateSource;
  2016. BreakpointsCollection^.free(P^.Breakpoint);
  2017. List^.free(P);
  2018. BreakpointsCollection^.Update;
  2019. end;
  2020. procedure TBreakpointsListBox.EditNew;
  2021. var
  2022. P: PBreakpoint;
  2023. begin
  2024. P:=New(PBreakpoint,Init_Empty);
  2025. if Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P)),nil)<>cmCancel then
  2026. begin
  2027. P^.UpdateSource;
  2028. BreakpointsCollection^.Insert(P);
  2029. BreakpointsCollection^.Update;
  2030. end
  2031. else
  2032. dispose(P,Done);
  2033. end;
  2034. procedure TBreakpointsListBox.Draw;
  2035. var
  2036. I, J, Item: Sw_Integer;
  2037. NormalColor, SelectedColor, FocusedColor, Color: Word;
  2038. ColWidth, CurCol, Indent: Integer;
  2039. B: TDrawBuffer;
  2040. Text: String;
  2041. SCOff: Byte;
  2042. TC: byte;
  2043. procedure MT(var C: word); begin if TC<>0 then C:=(C and $ff0f) or (TC and $f0); end;
  2044. begin
  2045. if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
  2046. if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
  2047. begin
  2048. NormalColor := GetColor(1);
  2049. FocusedColor := GetColor(3);
  2050. SelectedColor := GetColor(4);
  2051. end else
  2052. begin
  2053. NormalColor := GetColor(2);
  2054. SelectedColor := GetColor(4);
  2055. end;
  2056. if Transparent then
  2057. begin MT(NormalColor); MT(SelectedColor); end;
  2058. if NoSelection then
  2059. SelectedColor:=NormalColor;
  2060. if HScrollBar <> nil then Indent := HScrollBar^.Value
  2061. else Indent := 0;
  2062. ColWidth := Size.X div NumCols + 1;
  2063. for I := 0 to Size.Y - 1 do
  2064. begin
  2065. for J := 0 to NumCols-1 do
  2066. begin
  2067. Item := J*Size.Y + I + TopItem;
  2068. CurCol := J*ColWidth;
  2069. if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
  2070. (Focused = Item) and (Range > 0) then
  2071. begin
  2072. Color := FocusedColor;
  2073. SetCursor(CurCol+1,I);
  2074. SCOff := 0;
  2075. end
  2076. else if (Item < Range) and IsSelected(Item) then
  2077. begin
  2078. Color := SelectedColor;
  2079. SCOff := 2;
  2080. end
  2081. else
  2082. begin
  2083. Color := NormalColor;
  2084. SCOff := 4;
  2085. end;
  2086. MoveChar(B[CurCol], ' ', Color, ColWidth);
  2087. if Item < Range then
  2088. begin
  2089. Text := GetText(Item, ColWidth + Indent);
  2090. Text := Copy(Text,Indent,ColWidth);
  2091. MoveStr(B[CurCol+1], Text, Color);
  2092. if ShowMarkers then
  2093. begin
  2094. WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
  2095. WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
  2096. end;
  2097. end;
  2098. MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
  2099. end;
  2100. WriteLine(0, I, Size.X, 1, B);
  2101. end;
  2102. end;
  2103. constructor TBreakpointsListBox.Load(var S: TStream);
  2104. begin
  2105. inherited Load(S);
  2106. end;
  2107. procedure TBreakpointsListBox.Store(var S: TStream);
  2108. var OL: PCollection;
  2109. OldR : integer;
  2110. begin
  2111. OL:=List;
  2112. OldR:=Range;
  2113. Range:=0;
  2114. New(List, Init(1,1));
  2115. inherited Store(S);
  2116. Dispose(List, Done);
  2117. Range:=OldR;
  2118. List:=OL;
  2119. { ^^^ nasty trick - has anyone a better idea how to avoid storing the
  2120. collection? Pasting here a modified version of TListBox.Store+
  2121. TAdvancedListBox.Store isn't a better solution, since by eventually
  2122. changing the obj-hierarchy you'll always have to modify this, too - BG }
  2123. end;
  2124. destructor TBreakpointsListBox.Done;
  2125. begin
  2126. inherited Done;
  2127. if List<>nil then Dispose(List, Done);
  2128. end;
  2129. {****************************************************************************
  2130. TBreakpointsWindow
  2131. ****************************************************************************}
  2132. constructor TBreakpointsWindow.Init;
  2133. var R,R2: TRect;
  2134. HSB,VSB: PScrollBar;
  2135. ST: PStaticText;
  2136. S: String;
  2137. X,X1 : Sw_integer;
  2138. Btn: PButton;
  2139. const
  2140. NumButtons = 5;
  2141. begin
  2142. Desktop^.GetExtent(R); R.A.Y:=R.B.Y-18;
  2143. inherited Init(R, dialog_breakpointlist, wnNoNumber);
  2144. HelpCtx:=hcBreakpointListWindow;
  2145. GetExtent(R); R.Grow(-1,-1); R.B.Y:=R.A.Y+1;
  2146. S:=label_breakpointpropheader;
  2147. New(ST, Init(R,S));
  2148. ST^.GrowMode:=gfGrowHiX;
  2149. Insert(ST);
  2150. GetExtent(R); R.Grow(-1,-1); Inc(R.A.Y,1); R.B.Y:=R.A.Y+1;
  2151. New(ST, Init(R, CharStr('Ä', MaxViewWidth)));
  2152. ST^.GrowMode:=gfGrowHiX;
  2153. Insert(ST);
  2154. GetExtent(R); R.Grow(-1,-1); Inc(R.A.Y,2);Dec(R.B.Y,5);
  2155. R2.Copy(R); Inc(R2.B.Y); R2.A.Y:=R2.B.Y-1;
  2156. New(HSB, Init(R2)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX; Insert(HSB);
  2157. HSB^.SetStep(R.B.X-R.A.X-2,1);
  2158. R2.Copy(R); Inc(R2.B.X); R2.A.X:=R2.B.X-1;
  2159. New(VSB, Init(R2)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY; Insert(VSB);
  2160. VSB^.SetStep(R.B.Y-R.A.Y-2,1);
  2161. New(BreakLB, Init(R,HSB,VSB));
  2162. BreakLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  2163. BreakLB^.Transparent:=true;
  2164. Insert(BreakLB);
  2165. GetExtent(R);R.Grow(-1,-1);
  2166. Dec(R.B.Y);
  2167. R.A.Y:=R.B.Y-2;
  2168. X:=(R.B.X-R.A.X) div NumButtons;
  2169. X1:=R.A.X+(X div 2);
  2170. R.A.X:=X1-3;R.B.X:=X1+7;
  2171. New(Btn, Init(R, button_Close, cmClose, bfDefault));
  2172. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2173. Insert(Btn);
  2174. X1:=X1+X;
  2175. R.A.X:=X1-3;R.B.X:=X1+7;
  2176. New(Btn, Init(R, button_New, cmNewBreakpoint, bfNormal));
  2177. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2178. Insert(Btn);
  2179. X1:=X1+X;
  2180. R.A.X:=X1-3;R.B.X:=X1+7;
  2181. New(Btn, Init(R, button_Edit, cmEditBreakpoint, bfNormal));
  2182. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2183. Insert(Btn);
  2184. X1:=X1+X;
  2185. R.A.X:=X1-3;R.B.X:=X1+7;
  2186. New(Btn, Init(R, button_ToggleButton, cmToggleBreakInList, bfNormal));
  2187. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2188. Insert(Btn);
  2189. X1:=X1+X;
  2190. R.A.X:=X1-3;R.B.X:=X1+7;
  2191. New(Btn, Init(R, button_Delete, cmDeleteBreakpoint, bfNormal));
  2192. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2193. Insert(Btn);
  2194. BreakLB^.Select;
  2195. Update;
  2196. BreakpointsWindow:=@self;
  2197. end;
  2198. constructor TBreakpointsWindow.Load(var S: TStream);
  2199. begin
  2200. inherited Load(S);
  2201. GetSubViewPtr(S,BreakLB);
  2202. end;
  2203. procedure TBreakpointsWindow.Store(var S: TStream);
  2204. begin
  2205. inherited Store(S);
  2206. PutSubViewPtr(S,BreakLB);
  2207. end;
  2208. procedure TBreakpointsWindow.AddBreakpoint(ABreakpoint : PBreakpoint);
  2209. begin
  2210. BreakLB^.AddBreakpoint(New(PBreakpointItem, Init(ABreakpoint)));
  2211. end;
  2212. procedure TBreakpointsWindow.ClearBreakpoints;
  2213. begin
  2214. BreakLB^.Clear;
  2215. ReDraw;
  2216. end;
  2217. procedure TBreakpointsWindow.ReloadBreakpoints;
  2218. procedure InsertInBreakLB(P : PBreakpoint);
  2219. begin
  2220. BreakLB^.AddBreakpoint(New(PBreakpointItem, Init(P)));
  2221. end;
  2222. begin
  2223. If not assigned(BreakpointsCollection) then
  2224. exit;
  2225. BreakpointsCollection^.ForEach(@InsertInBreakLB);
  2226. ReDraw;
  2227. end;
  2228. procedure TBreakpointsWindow.SizeLimits(var Min, Max: TPoint);
  2229. begin
  2230. inherited SizeLimits(Min,Max);
  2231. Min.X:=40; Min.Y:=18;
  2232. end;
  2233. procedure TBreakpointsWindow.Close;
  2234. begin
  2235. Hide;
  2236. end;
  2237. procedure TBreakpointsWindow.HandleEvent(var Event: TEvent);
  2238. var DontClear : boolean;
  2239. begin
  2240. case Event.What of
  2241. evKeyDown :
  2242. begin
  2243. if (Event.KeyCode=kbEnter) or (Event.KeyCode=kbEsc) then
  2244. begin
  2245. ClearEvent(Event);
  2246. Hide;
  2247. end;
  2248. end;
  2249. evCommand :
  2250. begin
  2251. DontClear:=False;
  2252. case Event.Command of
  2253. cmNewBreakpoint :
  2254. BreakLB^.EditNew;
  2255. cmEditBreakpoint :
  2256. BreakLB^.EditCurrent;
  2257. cmDeleteBreakpoint :
  2258. BreakLB^.DeleteCurrent;
  2259. cmToggleBreakInList :
  2260. BreakLB^.ToggleCurrent;
  2261. cmClose :
  2262. Hide;
  2263. else
  2264. DontClear:=true;
  2265. end;
  2266. if not DontClear then
  2267. ClearEvent(Event);
  2268. end;
  2269. evBroadcast :
  2270. case Event.Command of
  2271. cmUpdate :
  2272. Update;
  2273. end;
  2274. end;
  2275. inherited HandleEvent(Event);
  2276. end;
  2277. procedure TBreakpointsWindow.Update;
  2278. var
  2279. StoreFocus : longint;
  2280. begin
  2281. StoreFocus:=BreakLB^.Focused;
  2282. ClearBreakpoints;
  2283. ReloadBreakpoints;
  2284. If StoreFocus<BreakLB^.Range then
  2285. BreakLB^.FocusItem(StoreFocus);
  2286. end;
  2287. destructor TBreakpointsWindow.Done;
  2288. begin
  2289. inherited Done;
  2290. BreakpointsWindow:=nil;
  2291. end;
  2292. {****************************************************************************
  2293. TBreakpointItemDialog
  2294. ****************************************************************************}
  2295. constructor TBreakpointItemDialog.Init(ABreakpoint: PBreakpoint);
  2296. var R,R2,R3: TRect;
  2297. Items: PSItem;
  2298. I : BreakpointType;
  2299. KeyCount: sw_integer;
  2300. begin
  2301. KeyCount:=longint(high(BreakpointType));
  2302. R.Assign(0,0,60,Max(9+KeyCount,18));
  2303. inherited Init(R,dialog_modifynewbreakpoint);
  2304. Breakpoint:=ABreakpoint;
  2305. GetExtent(R); R.Grow(-3,-2); R3.Copy(R);
  2306. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.B.X-3;
  2307. New(NameIL, Init(R, 255)); Insert(NameIL);
  2308. R2.Copy(R); R2.A.X:=R2.B.X; R2.B.X:=R2.A.X+3;
  2309. Insert(New(PHistory, Init(R2, NameIL, hidBreakPointDialogName)));
  2310. R.Copy(R3); Inc(R.A.Y); R.B.Y:=R.A.Y+1;
  2311. R2.Copy(R); R2.Move(-1,-1);
  2312. Insert(New(PLabel, Init(R2, label_breakpoint_name, NameIL)));
  2313. R.Move(0,3);
  2314. R.B.X:=R.B.X-3;
  2315. New(ConditionsIL, Init(R, 255)); Insert(ConditionsIL);
  2316. R2.Copy(R); R2.A.X:=R2.B.X; R2.B.X:=R2.A.X+3;
  2317. Insert(New(PHistory, Init(R2, ConditionsIL, hidBreakPointDialogCond)));
  2318. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_breakpoint_conditions, ConditionsIL)));
  2319. R.Move(0,3); R.B.X:=R.A.X+36;
  2320. New(LineIL, Init(R, 128)); Insert(LineIL);
  2321. LineIL^.SetValidator(New(PRangeValidator, Init(0,MaxInt)));
  2322. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_breakpoint_line, LineIL)));
  2323. R.Move(0,3);
  2324. New(IgnoreIL, Init(R, 128)); Insert(IgnoreIL);
  2325. IgnoreIL^.SetValidator(New(PRangeValidator, Init(0,MaxInt)));
  2326. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_breakpoint_ignorecount, IgnoreIL)));
  2327. R.Copy(R3); Inc(R.A.X,38); Inc(R.A.Y,7); R.B.Y:=R.A.Y+KeyCount;
  2328. Items:=nil;
  2329. { don't use invalid type }
  2330. for I:=pred(high(BreakpointType)) downto low(BreakpointType) do
  2331. Items:=NewSItem(BreakpointTypeStr[I], Items);
  2332. New(TypeRB, Init(R, Items));
  2333. R2.Copy(R); R2.Move(-1,-1); R2.B.Y:=R2.A.Y+1;
  2334. Insert(New(PLabel, Init(R2, label_breakpoint_type, TypeRB)));
  2335. Insert(TypeRB);
  2336. InsertButtons(@Self);
  2337. NameIL^.Select;
  2338. end;
  2339. function TBreakpointItemDialog.Execute: Word;
  2340. var R: sw_word;
  2341. S1: string;
  2342. err: word;
  2343. L: longint;
  2344. begin
  2345. R:=sw_word(Breakpoint^.typ);
  2346. TypeRB^.SetData(R);
  2347. If Breakpoint^.typ=bt_file_line then
  2348. S1:=GetStr(Breakpoint^.FileName)
  2349. else
  2350. S1:=GetStr(Breakpoint^.name);
  2351. NameIL^.SetData(S1);
  2352. If Breakpoint^.typ=bt_file_line then
  2353. S1:=IntToStr(Breakpoint^.Line)
  2354. else
  2355. S1:='0';
  2356. LineIL^.SetData(S1);
  2357. S1:=IntToStr(Breakpoint^.IgnoreCount);
  2358. IgnoreIL^.SetData(S1);
  2359. S1:=GetStr(Breakpoint^.Conditions);
  2360. ConditionsIL^.SetData(S1);
  2361. if assigned(FirstEditorWindow) then
  2362. FindReplaceEditor:=FirstEditorWindow^.Editor;
  2363. R:=inherited Execute;
  2364. FindReplaceEditor:=nil;
  2365. if R=cmOK then
  2366. begin
  2367. TypeRB^.GetData(R);
  2368. L:=R;
  2369. Breakpoint^.typ:=BreakpointType(L);
  2370. NameIL^.GetData(S1);
  2371. If Breakpoint^.typ=bt_file_line then
  2372. begin
  2373. If assigned(Breakpoint^.FileName) then
  2374. DisposeStr(Breakpoint^.FileName);
  2375. Breakpoint^.FileName:=NewStr(S1);
  2376. end
  2377. else
  2378. begin
  2379. If assigned(Breakpoint^.Name) then
  2380. DisposeStr(Breakpoint^.Name);
  2381. Breakpoint^.name:=NewStr(S1);
  2382. end;
  2383. If Breakpoint^.typ=bt_file_line then
  2384. begin
  2385. LineIL^.GetData(S1);
  2386. Val(S1,L,err);
  2387. Breakpoint^.Line:=L;
  2388. end;
  2389. IgnoreIL^.GetData(S1);
  2390. Val(S1,L,err);
  2391. Breakpoint^.IgnoreCount:=L;
  2392. ConditionsIL^.GetData(S1);
  2393. If assigned(Breakpoint^.Conditions) then
  2394. DisposeStr(Breakpoint^.Conditions);
  2395. Breakpoint^.Conditions:=NewStr(S1);
  2396. end;
  2397. Execute:=R;
  2398. end;
  2399. {****************************************************************************
  2400. TWatch
  2401. ****************************************************************************}
  2402. constructor TWatch.Init(s : string);
  2403. begin
  2404. expr:=NewStr(s);
  2405. last_value:=nil;
  2406. current_value:=nil;
  2407. Get_new_value;
  2408. GDBRunCount:=-1;
  2409. end;
  2410. constructor TWatch.Load(var S: TStream);
  2411. begin
  2412. expr:=S.ReadStr;
  2413. last_value:=nil;
  2414. current_value:=nil;
  2415. Get_new_value;
  2416. GDBRunCount:=-1;
  2417. end;
  2418. procedure TWatch.Store(var S: TStream);
  2419. begin
  2420. S.WriteStr(expr);
  2421. end;
  2422. procedure TWatch.rename(s : string);
  2423. begin
  2424. if assigned(expr) then
  2425. begin
  2426. if GetStr(expr)=S then
  2427. exit;
  2428. DisposeStr(expr);
  2429. end;
  2430. expr:=NewStr(s);
  2431. if assigned(last_value) then
  2432. StrDispose(last_value);
  2433. last_value:=nil;
  2434. if assigned(current_value) then
  2435. StrDispose(current_value);
  2436. current_value:=nil;
  2437. GDBRunCount:=-1;
  2438. Get_new_value;
  2439. end;
  2440. procedure TWatch.Get_new_value;
  2441. {$ifndef NODEBUG}
  2442. var p, q : pchar;
  2443. i, j, curframe, startframe : longint;
  2444. s,s2 : string;
  2445. loop_higher, found : boolean;
  2446. last_removed : char;
  2447. function GetValue(var s : string) : boolean;
  2448. begin
  2449. Debugger^.command('p '+s);
  2450. if not Debugger^.Error then
  2451. begin
  2452. s:=StrPas(Debugger^.GetOutput);
  2453. GetValue:=true;
  2454. end
  2455. else
  2456. begin
  2457. s:=StrPas(Debugger^.GetError);
  2458. GetValue:=false;
  2459. { do not open a messagebox for such errors }
  2460. Debugger^.got_error:=false;
  2461. end;
  2462. end;
  2463. begin
  2464. If not assigned(Debugger) or Not Debugger^.HasExe or
  2465. (GDBRunCount=Debugger^.RunCount) then
  2466. exit;
  2467. GDBRunCount:=Debugger^.RunCount;
  2468. if assigned(last_value) then
  2469. strdispose(last_value);
  2470. last_value:=current_value;
  2471. s:=GetStr(expr);
  2472. { Fix 2d array indexing, change [x,x] to [x][x] }
  2473. i:=pos('[',s);
  2474. if i>0 then
  2475. begin
  2476. while i<length(s) do
  2477. begin
  2478. if s[i]=',' then
  2479. begin
  2480. s[i]:='[';
  2481. insert(']',s,i);
  2482. inc(i);
  2483. end;
  2484. inc(i);
  2485. end;
  2486. end;
  2487. found:=GetValue(s);
  2488. Debugger^.got_error:=false;
  2489. loop_higher:=not found;
  2490. if not found then
  2491. begin
  2492. curframe:=Debugger^.get_current_frame;
  2493. startframe:=curframe;
  2494. end
  2495. else
  2496. begin
  2497. curframe:=0;
  2498. startframe:=0;
  2499. end;
  2500. while loop_higher do
  2501. begin
  2502. s:='parentfp';
  2503. if GetValue(s) then
  2504. begin
  2505. repeat
  2506. inc(curframe);
  2507. if not Debugger^.set_current_frame(curframe) then
  2508. loop_higher:=false;
  2509. {$ifdef FrameNameKnown}
  2510. s2:='/x '+FrameName;
  2511. {$else not FrameNameKnown}
  2512. s2:='/x $ebp';
  2513. {$endif FrameNameKnown}
  2514. getValue(s2);
  2515. j:=pos('=',s2);
  2516. if j>0 then
  2517. s2:=copy(s2,j+1,length(s2));
  2518. while s2[1] in [' ',TAB] do
  2519. delete(s2,1,1);
  2520. if pos(s2,s)>0 then
  2521. loop_higher :=false;
  2522. until not loop_higher;
  2523. { try again at that level }
  2524. s:=GetStr(expr);
  2525. found:=GetValue(s);
  2526. loop_higher:=not found;
  2527. end
  2528. else
  2529. loop_higher:=false;
  2530. end;
  2531. if found then
  2532. p:=StrNew(Debugger^.GetOutput)
  2533. else
  2534. begin
  2535. { get a reasonable output at least }
  2536. s:=GetStr(expr);
  2537. GetValue(s);
  2538. p:=StrNew(Debugger^.GetError);
  2539. end;
  2540. Debugger^.got_error:=false;
  2541. { We should try here to find the expr in parent
  2542. procedure if there are
  2543. I will implement this as I added a
  2544. parent_ebp pseudo local var to local procedure
  2545. in stabs debug info PM }
  2546. { But there are some pitfalls like
  2547. locals redefined in other sublocals that call the function }
  2548. if curframe<>startframe then
  2549. Debugger^.set_current_frame(startframe);
  2550. q:=nil;
  2551. if assigned(p) and (p[0]='$') then
  2552. q:=StrPos(p,'=');
  2553. if not assigned(q) then
  2554. q:=p;
  2555. if assigned(q) then
  2556. i:=strlen(q)
  2557. else
  2558. i:=0;
  2559. if (i>0) and (q[i-1]=#10) then
  2560. begin
  2561. while (i>1) and ((q[i-2]=' ') or (q[i-2]=#9)) do
  2562. dec(i);
  2563. last_removed:=q[i-1];
  2564. q[i-1]:=#0;
  2565. end
  2566. else
  2567. last_removed:=#0;
  2568. if assigned(q) then
  2569. current_value:=strnew(q)
  2570. else
  2571. current_value:=strnew('');
  2572. if last_removed<>#0 then
  2573. q[i-1]:=last_removed;
  2574. strdispose(p);
  2575. GDBRunCount:=Debugger^.RunCount;
  2576. end;
  2577. {$else NODEBUG}
  2578. begin
  2579. end;
  2580. {$endif NODEBUG}
  2581. procedure TWatch.Force_new_value;
  2582. begin
  2583. GDBRunCount:=-1;
  2584. Get_new_value;
  2585. end;
  2586. destructor TWatch.Done;
  2587. begin
  2588. if assigned(expr) then
  2589. disposestr(expr);
  2590. if assigned(last_value) then
  2591. strdispose(last_value);
  2592. if assigned(current_value) then
  2593. strdispose(current_value);
  2594. inherited done;
  2595. end;
  2596. {****************************************************************************
  2597. TWatchesCollection
  2598. ****************************************************************************}
  2599. constructor TWatchesCollection.Init;
  2600. begin
  2601. inherited Init(10,10);
  2602. end;
  2603. procedure TWatchesCollection.Insert(Item: Pointer);
  2604. begin
  2605. PWatch(Item)^.Get_new_value;
  2606. Inherited Insert(Item);
  2607. Update;
  2608. end;
  2609. procedure TWatchesCollection.Update;
  2610. var
  2611. W,W1 : integer;
  2612. procedure GetMax(P : PWatch);
  2613. begin
  2614. if assigned(P^.Current_value) then
  2615. W1:=StrLen(P^.Current_value)+3+Length(GetStr(P^.expr))
  2616. else
  2617. W1:=2+Length(GetStr(P^.expr));
  2618. if W1>W then
  2619. W:=W1;
  2620. end;
  2621. begin
  2622. W:=0;
  2623. ForEach(@GetMax);
  2624. MaxW:=W;
  2625. If assigned(WatchesWindow) then
  2626. WatchesWindow^.WLB^.Update(MaxW);
  2627. end;
  2628. function TWatchesCollection.At(Index: Integer): PWatch;
  2629. begin
  2630. At:=Inherited At(Index);
  2631. end;
  2632. {****************************************************************************
  2633. TWatchesListBox
  2634. ****************************************************************************}
  2635. constructor TWatchesListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  2636. begin
  2637. inherited Init(Bounds,1,AHScrollBar,AVScrollBar);
  2638. If assigned(List) then
  2639. dispose(list,done);
  2640. List:=WatchesCollection;
  2641. end;
  2642. procedure TWatchesListBox.Update(AMaxWidth : integer);
  2643. var R : TRect;
  2644. begin
  2645. GetExtent(R);
  2646. MaxWidth:=AMaxWidth;
  2647. if (HScrollBar<>nil) and (R.B.X-R.A.X<MaxWidth) then
  2648. HScrollBar^.SetRange(0,MaxWidth-(R.B.X-R.A.X))
  2649. else
  2650. HScrollBar^.SetRange(0,0);
  2651. if R.B.X-R.A.X>MaxWidth then
  2652. HScrollBar^.Hide
  2653. else
  2654. HScrollBar^.Show;
  2655. SetRange(List^.Count+1);
  2656. if R.B.Y-R.A.Y>Range then
  2657. VScrollBar^.Hide
  2658. else
  2659. VScrollBar^.Show;
  2660. {if Focused=List^.Count-1-1 then
  2661. FocusItem(List^.Count-1);
  2662. What was that for ?? PM }
  2663. DrawView;
  2664. end;
  2665. function TWatchesListBox.GetIndentedText(Item,Indent,MaxLen: Sw_Integer;var Modified : boolean): String;
  2666. var
  2667. PW : PWatch;
  2668. ValOffset : Sw_integer;
  2669. S : String;
  2670. begin
  2671. Modified:=false;
  2672. if Item>=WatchesCollection^.Count then
  2673. begin
  2674. GetIndentedText:='';
  2675. exit;
  2676. end;
  2677. PW:=WatchesCollection^.At(Item);
  2678. ValOffset:=Length(GetStr(PW^.Expr))+2;
  2679. if not assigned(PW^.expr) then
  2680. GetIndentedText:=''
  2681. else if Indent<ValOffset then
  2682. begin
  2683. S:=GetStr(PW^.Expr);
  2684. if Indent=0 then
  2685. S:=' '+S
  2686. else
  2687. S:=Copy(S,Indent,High(S));
  2688. if not assigned(PW^.current_value) then
  2689. S:=S+' <Unknown value>'
  2690. else
  2691. S:=S+' '+GetPChar(PW^.Current_value);
  2692. GetIndentedText:=Copy(S,1,MaxLen);
  2693. end
  2694. else
  2695. begin
  2696. if not assigned(PW^.Current_value) or
  2697. (StrLen(PW^.Current_value)<Indent-Valoffset) then
  2698. S:=''
  2699. else
  2700. S:=GetPchar(@(PW^.Current_Value[Indent-Valoffset]));
  2701. GetIndentedText:=Copy(S,1,MaxLen);
  2702. end;
  2703. if assigned(PW^.current_value) and
  2704. assigned(PW^.last_value) and
  2705. (strcomp(PW^.Last_value,PW^.Current_value)<>0) then
  2706. Modified:=true;
  2707. end;
  2708. procedure TWatchesListBox.EditCurrent;
  2709. var
  2710. P: PWatch;
  2711. begin
  2712. if Range=0 then Exit;
  2713. if Focused<WatchesCollection^.Count then
  2714. P:=WatchesCollection^.At(Focused)
  2715. else
  2716. P:=New(PWatch,Init(''));
  2717. Application^.ExecuteDialog(New(PWatchItemDialog,Init(P)),nil);
  2718. WatchesCollection^.Update;
  2719. end;
  2720. function TWatchesListBox.GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String;
  2721. var
  2722. Dummy_Modified : boolean;
  2723. begin
  2724. GetText:=GetIndentedText(Item, 0, MaxLen, Dummy_Modified);
  2725. end;
  2726. procedure TWatchesListBox.DeleteCurrent;
  2727. var
  2728. P: PWatch;
  2729. begin
  2730. if (Range=0) or
  2731. (Focused>=WatchesCollection^.Count) then
  2732. exit;
  2733. P:=WatchesCollection^.At(Focused);
  2734. WatchesCollection^.free(P);
  2735. WatchesCollection^.Update;
  2736. end;
  2737. procedure TWatchesListBox.EditNew;
  2738. var
  2739. P: PWatch;
  2740. S : string;
  2741. begin
  2742. if Focused<WatchesCollection^.Count then
  2743. begin
  2744. P:=WatchesCollection^.At(Focused);
  2745. S:=GetStr(P^.expr);
  2746. end
  2747. else
  2748. S:='';
  2749. P:=New(PWatch,Init(S));
  2750. if Application^.ExecuteDialog(New(PWatchItemDialog,Init(P)),nil)<>cmCancel then
  2751. begin
  2752. WatchesCollection^.AtInsert(Focused,P);
  2753. WatchesCollection^.Update;
  2754. end
  2755. else
  2756. dispose(P,Done);
  2757. end;
  2758. procedure TWatchesListBox.Draw;
  2759. var
  2760. I, J, Item: Sw_Integer;
  2761. NormalColor, SelectedColor, FocusedColor, Color: Word;
  2762. ColWidth, CurCol, Indent: Integer;
  2763. B: TDrawBuffer;
  2764. Modified : boolean;
  2765. Text: String;
  2766. SCOff: Byte;
  2767. TC: byte;
  2768. procedure MT(var C: word);
  2769. begin
  2770. if TC<>0 then C:=(C and $ff0f) or (TC and $f0);
  2771. end;
  2772. begin
  2773. if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
  2774. if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
  2775. begin
  2776. NormalColor := GetColor(1);
  2777. FocusedColor := GetColor(3);
  2778. SelectedColor := GetColor(4);
  2779. end else
  2780. begin
  2781. NormalColor := GetColor(2);
  2782. SelectedColor := GetColor(4);
  2783. end;
  2784. if Transparent then
  2785. begin MT(NormalColor); MT(SelectedColor); end;
  2786. (* if NoSelection then
  2787. SelectedColor:=NormalColor;*)
  2788. if HScrollBar <> nil then Indent := HScrollBar^.Value
  2789. else Indent := 0;
  2790. ColWidth := Size.X div NumCols + 1;
  2791. for I := 0 to Size.Y - 1 do
  2792. begin
  2793. for J := 0 to NumCols-1 do
  2794. begin
  2795. Item := J*Size.Y + I + TopItem;
  2796. CurCol := J*ColWidth;
  2797. if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
  2798. (Focused = Item) and (Range > 0) then
  2799. begin
  2800. Color := FocusedColor;
  2801. SetCursor(CurCol+1,I);
  2802. SCOff := 0;
  2803. end
  2804. else if (Item < Range) and IsSelected(Item) then
  2805. begin
  2806. Color := SelectedColor;
  2807. SCOff := 2;
  2808. end
  2809. else
  2810. begin
  2811. Color := NormalColor;
  2812. SCOff := 4;
  2813. end;
  2814. MoveChar(B[CurCol], ' ', Color, ColWidth);
  2815. if Item < Range then
  2816. begin
  2817. (* Text := GetText(Item, ColWidth + Indent);
  2818. Text := Copy(Text,Indent,ColWidth); *)
  2819. Text:=GetIndentedText(Item,Indent,ColWidth,Modified);
  2820. if modified then
  2821. begin
  2822. SCOff:=0;
  2823. Color:=(Color and $fff0) or Red;
  2824. end;
  2825. MoveStr(B[CurCol], Text, Color);
  2826. if {ShowMarkers or } Modified then
  2827. begin
  2828. WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
  2829. WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
  2830. WordRec(B[CurCol+ColWidth-2]).Hi := Color and $ff;
  2831. end;
  2832. end;
  2833. MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
  2834. end;
  2835. WriteLine(0, I, Size.X, 1, B);
  2836. end;
  2837. end;
  2838. function TWatchesListBox.GetLocalMenu: PMenu;
  2839. var M: PMenu;
  2840. begin
  2841. if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
  2842. M:=NewMenu(
  2843. NewItem(menu_watchlocal_edit,'',kbNoKey,cmEdit,hcNoContext,
  2844. NewItem(menu_watchlocal_new,'',kbNoKey,cmNew,hcNoContext,
  2845. NewItem(menu_watchlocal_delete,'',kbNoKey,cmDelete,hcNoContext,
  2846. NewLine(
  2847. NewItem(menu_msglocal_saveas,'',kbNoKey,cmSaveAs,hcSaveAs,
  2848. nil))))));
  2849. GetLocalMenu:=M;
  2850. end;
  2851. procedure TWatchesListBox.HandleEvent(var Event: TEvent);
  2852. var DontClear: boolean;
  2853. begin
  2854. case Event.What of
  2855. evKeyDown :
  2856. begin
  2857. DontClear:=false;
  2858. case Event.KeyCode of
  2859. kbEnter :
  2860. Message(@Self,evCommand,cmEdit,nil);
  2861. kbIns :
  2862. Message(@Self,evCommand,cmNew,nil);
  2863. kbDel :
  2864. Message(@Self,evCommand,cmDelete,nil);
  2865. else
  2866. DontClear:=true;
  2867. end;
  2868. if not DontClear then
  2869. ClearEvent(Event);
  2870. end;
  2871. evBroadcast :
  2872. case Event.Command of
  2873. cmListItemSelected :
  2874. if Event.InfoPtr=@Self then
  2875. Message(@Self,evCommand,cmEdit,nil);
  2876. end;
  2877. evCommand :
  2878. begin
  2879. DontClear:=false;
  2880. case Event.Command of
  2881. cmEdit :
  2882. EditCurrent;
  2883. cmDelete :
  2884. DeleteCurrent;
  2885. cmNew :
  2886. EditNew;
  2887. else
  2888. DontClear:=true;
  2889. end;
  2890. if not DontClear then
  2891. ClearEvent(Event);
  2892. end;
  2893. end;
  2894. inherited HandleEvent(Event);
  2895. end;
  2896. constructor TWatchesListBox.Load(var S: TStream);
  2897. begin
  2898. inherited Load(S);
  2899. If assigned(List) then
  2900. dispose(list,done);
  2901. List:=WatchesCollection;
  2902. { we must set Range PM }
  2903. SetRange(List^.count+1);
  2904. end;
  2905. procedure TWatchesListBox.Store(var S: TStream);
  2906. var OL: PCollection;
  2907. OldRange : Sw_integer;
  2908. begin
  2909. OL:=List;
  2910. OldRange:=Range;
  2911. Range:=0;
  2912. New(List, Init(1,1));
  2913. inherited Store(S);
  2914. Dispose(List, Done);
  2915. List:=OL;
  2916. { ^^^ nasty trick - has anyone a better idea how to avoid storing the
  2917. collection? Pasting here a modified version of TListBox.Store+
  2918. TAdvancedListBox.Store isn't a better solution, since by eventually
  2919. changing the obj-hierarchy you'll always have to modify this, too - BG }
  2920. SetRange(OldRange);
  2921. end;
  2922. destructor TWatchesListBox.Done;
  2923. begin
  2924. List:=nil;
  2925. inherited Done;
  2926. end;
  2927. {****************************************************************************
  2928. TWatchesWindow
  2929. ****************************************************************************}
  2930. Constructor TWatchesWindow.Init;
  2931. var
  2932. HSB,VSB: PScrollBar;
  2933. R,R2 : trect;
  2934. begin
  2935. Desktop^.GetExtent(R);
  2936. R.A.Y:=R.B.Y-7;
  2937. inherited Init(R, dialog_watches,SearchFreeWindowNo);
  2938. Palette:=wpCyanWindow;
  2939. GetExtent(R);
  2940. HelpCtx:=hcWatchesWindow;
  2941. R.Grow(-1,-1);
  2942. R2.Copy(R);
  2943. Inc(R2.B.Y);
  2944. R2.A.Y:=R2.B.Y-1;
  2945. New(HSB, Init(R2));
  2946. HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX;
  2947. HSB^.SetStep(R.B.X-R.A.X,1);
  2948. Insert(HSB);
  2949. R2.Copy(R);
  2950. Inc(R2.B.X);
  2951. R2.A.X:=R2.B.X-1;
  2952. New(VSB, Init(R2));
  2953. VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  2954. Insert(VSB);
  2955. New(WLB,Init(R,HSB,VSB));
  2956. WLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  2957. WLB^.Transparent:=true;
  2958. Insert(WLB);
  2959. If assigned(WatchesWindow) then
  2960. dispose(WatchesWindow,done);
  2961. WatchesWindow:=@Self;
  2962. Update;
  2963. end;
  2964. procedure TWatchesWindow.Update;
  2965. begin
  2966. WatchesCollection^.Update;
  2967. Draw;
  2968. end;
  2969. constructor TWatchesWindow.Load(var S: TStream);
  2970. begin
  2971. inherited Load(S);
  2972. GetSubViewPtr(S,WLB);
  2973. If assigned(WatchesWindow) then
  2974. dispose(WatchesWindow,done);
  2975. WatchesWindow:=@Self;
  2976. end;
  2977. procedure TWatchesWindow.Store(var S: TStream);
  2978. begin
  2979. inherited Store(S);
  2980. PutSubViewPtr(S,WLB);
  2981. end;
  2982. Destructor TWatchesWindow.Done;
  2983. begin
  2984. WatchesWindow:=nil;
  2985. Dispose(WLB,done);
  2986. inherited done;
  2987. end;
  2988. {****************************************************************************
  2989. TWatchItemDialog
  2990. ****************************************************************************}
  2991. constructor TWatchItemDialog.Init(AWatch: PWatch);
  2992. var R,R2: TRect;
  2993. begin
  2994. R.Assign(0,0,50,10);
  2995. inherited Init(R,'Edit Watch');
  2996. Watch:=AWatch;
  2997. GetExtent(R); R.Grow(-3,-2);
  2998. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+36;
  2999. New(NameIL, Init(R, 255)); Insert(NameIL);
  3000. R2.Copy(R); R2.A.X:=R2.B.X; R2.B.X:=R2.A.X+3;
  3001. Insert(New(PHistory, Init(R2, NameIL, hidWatchDialog)));
  3002. R2.Copy(R); R2.Move(-1,-1);
  3003. Insert(New(PLabel, Init(R2, label_watch_expressiontowatch, NameIL)));
  3004. GetExtent(R);
  3005. R.Grow(-3,-1);
  3006. R.A.Y:=R.A.Y+3;
  3007. TextST:=New(PAdvancedStaticText, Init(R, label_watch_values));
  3008. Insert(TextST);
  3009. InsertButtons(@Self);
  3010. NameIL^.Select;
  3011. end;
  3012. function TWatchItemDialog.Execute: Word;
  3013. var R: word;
  3014. S1,S2: string;
  3015. begin
  3016. S1:=GetStr(Watch^.expr);
  3017. NameIL^.SetData(S1);
  3018. S1:=GetPChar(Watch^.Current_value);
  3019. S2:=GetPChar(Watch^.Last_value);
  3020. ClearFormatParams;
  3021. AddFormatParamStr(S1);
  3022. AddFormatParamStr(S2);
  3023. if assigned(Watch^.Last_value) and
  3024. assigned(Watch^.Current_value) and
  3025. (strcomp(Watch^.Last_value,Watch^.Current_value)=0) then
  3026. S1:=FormatStrF(msg_watch_currentvalue,FormatParams)
  3027. else
  3028. S1:=FormatStrF(msg_watch_currentandpreviousvalue,FormatParams);
  3029. TextST^.SetText(S1);
  3030. if assigned(FirstEditorWindow) then
  3031. FindReplaceEditor:=FirstEditorWindow^.Editor;
  3032. R:=inherited Execute;
  3033. FindReplaceEditor:=nil;
  3034. if R=cmOK then
  3035. begin
  3036. NameIL^.GetData(S1);
  3037. Watch^.Rename(S1);
  3038. {$ifndef NODEBUG}
  3039. If assigned(Debugger) then
  3040. Debugger^.ReadWatches;
  3041. {$endif NODEBUG}
  3042. end;
  3043. Execute:=R;
  3044. end;
  3045. {****************************************************************************
  3046. TStackWindow
  3047. ****************************************************************************}
  3048. constructor TFramesListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  3049. begin
  3050. Inherited Init(Bounds,AHScrollBar,AVScrollBar);
  3051. end;
  3052. procedure TFramesListBox.Update;
  3053. var i : longint;
  3054. W : PSourceWindow;
  3055. begin
  3056. {$ifndef NODEBUG}
  3057. { call backtrace command }
  3058. If not assigned(Debugger) then
  3059. exit;
  3060. DeskTop^.Lock;
  3061. Clear;
  3062. { forget all old frames }
  3063. Debugger^.clear_frames;
  3064. if Debugger^.WindowWidth<>-1 then
  3065. Debugger^.Command('set width 0xffffffff');
  3066. Debugger^.Command('backtrace');
  3067. { generate list }
  3068. { all is in tframeentry }
  3069. for i:=0 to Debugger^.frame_count-1 do
  3070. begin
  3071. with Debugger^.frames[i]^ do
  3072. begin
  3073. if assigned(file_name) then
  3074. AddItem(new(PMessageItem,init(0,GetPChar(function_name)+GetPChar(args),
  3075. AddModuleName(GetPChar(file_name)),line_number,1)))
  3076. else
  3077. AddItem(new(PMessageItem,init(0,HexStr(address,8)+' '+GetPChar(function_name)+GetPChar(args),
  3078. AddModuleName(''),line_number,1)));
  3079. W:=SearchOnDesktop(GetPChar(file_name),false);
  3080. { First reset all Debugger rows }
  3081. If assigned(W) then
  3082. begin
  3083. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,-1);
  3084. W^.Editor^.DebuggerRow:=-1;
  3085. end;
  3086. end;
  3087. end;
  3088. { Now set all Debugger rows }
  3089. for i:=0 to Debugger^.frame_count-1 do
  3090. begin
  3091. with Debugger^.frames[i]^ do
  3092. begin
  3093. W:=SearchOnDesktop(GetPChar(file_name),false);
  3094. If assigned(W) then
  3095. begin
  3096. If W^.Editor^.DebuggerRow=-1 then
  3097. begin
  3098. W^.Editor^.SetLineFlagState(line_number-1,lfDebuggerRow,true);
  3099. W^.Editor^.DebuggerRow:=line_number-1;
  3100. end;
  3101. end;
  3102. end;
  3103. end;
  3104. if Assigned(list) and (List^.Count > 0) then
  3105. FocusItem(0);
  3106. if Debugger^.WindowWidth<>-1 then
  3107. Debugger^.Command('set width '+IntToStr(Debugger^.WindowWidth));
  3108. DeskTop^.Unlock;
  3109. {$endif NODEBUG}
  3110. end;
  3111. function TFramesListBox.GetLocalMenu: PMenu;
  3112. begin
  3113. GetLocalMenu:=Inherited GetLocalMenu;
  3114. end;
  3115. procedure TFramesListBox.GotoSource;
  3116. begin
  3117. {$ifndef NODEBUG}
  3118. { select frame for watches }
  3119. If not assigned(Debugger) then
  3120. exit;
  3121. Debugger^.Command('f '+IntToStr(Focused));
  3122. { for local vars }
  3123. Debugger^.RereadWatches;
  3124. {$endif NODEBUG}
  3125. { goto source }
  3126. inherited GotoSource;
  3127. end;
  3128. procedure TFramesListBox.GotoAssembly;
  3129. begin
  3130. {$ifndef NODEBUG}
  3131. { select frame for watches }
  3132. If not assigned(Debugger) then
  3133. exit;
  3134. Debugger^.Command('f '+IntToStr(Focused));
  3135. { for local vars }
  3136. Debugger^.RereadWatches;
  3137. {$endif}
  3138. { goto source/assembly mixture }
  3139. InitDisassemblyWindow;
  3140. DisassemblyWindow^.LoadFunction('');
  3141. {$ifndef NODEBUG}
  3142. DisassemblyWindow^.SetCurAddress(Debugger^.frames[Focused]^.address);
  3143. DisassemblyWindow^.SelectInDebugSession;
  3144. {$endif NODEBUG}
  3145. end;
  3146. procedure TFramesListBox.HandleEvent(var Event: TEvent);
  3147. begin
  3148. if ((Event.What=EvKeyDown) and (Event.CharCode='i')) or
  3149. ((Event.What=EvCommand) and (Event.Command=cmDisassemble)) then
  3150. GotoAssembly;
  3151. inherited HandleEvent(Event);
  3152. end;
  3153. destructor TFramesListBox.Done;
  3154. begin
  3155. Inherited Done;
  3156. end;
  3157. Constructor TStackWindow.Init;
  3158. var
  3159. HSB,VSB: PScrollBar;
  3160. R,R2 : trect;
  3161. begin
  3162. Desktop^.GetExtent(R);
  3163. R.A.Y:=R.B.Y-5;
  3164. inherited Init(R, dialog_callstack, wnNoNumber);
  3165. Palette:=wpCyanWindow;
  3166. GetExtent(R);
  3167. HelpCtx:=hcStackWindow;
  3168. R.Grow(-1,-1);
  3169. R2.Copy(R);
  3170. Inc(R2.B.Y);
  3171. R2.A.Y:=R2.B.Y-1;
  3172. New(HSB, Init(R2));
  3173. HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX;
  3174. Insert(HSB);
  3175. R2.Copy(R);
  3176. Inc(R2.B.X);
  3177. R2.A.X:=R2.B.X-1;
  3178. New(VSB, Init(R2));
  3179. VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  3180. Insert(VSB);
  3181. New(FLB,Init(R,HSB,VSB));
  3182. FLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  3183. Insert(FLB);
  3184. If assigned(StackWindow) then
  3185. dispose(StackWindow,done);
  3186. StackWindow:=@Self;
  3187. Update;
  3188. end;
  3189. procedure TStackWindow.Update;
  3190. begin
  3191. FLB^.Update;
  3192. DrawView;
  3193. end;
  3194. constructor TStackWindow.Load(var S: TStream);
  3195. begin
  3196. inherited Load(S);
  3197. GetSubViewPtr(S,FLB);
  3198. If assigned(StackWindow) then
  3199. dispose(StackWindow,done);
  3200. StackWindow:=@Self;
  3201. end;
  3202. procedure TStackWindow.Store(var S: TStream);
  3203. begin
  3204. inherited Store(S);
  3205. PutSubViewPtr(S,FLB);
  3206. end;
  3207. Destructor TStackWindow.Done;
  3208. begin
  3209. StackWindow:=nil;
  3210. Dispose(FLB,done);
  3211. inherited done;
  3212. end;
  3213. {****************************************************************************
  3214. Init/Final
  3215. ****************************************************************************}
  3216. function GetGDBTargetShortName : string;
  3217. begin
  3218. {$ifdef SUPPORT_REMOTE}
  3219. {$ifdef PALMOSGDB}
  3220. GetGDBTargetShortName:='palmos';
  3221. {$else}
  3222. GetGDBTargetShortName:='linux';
  3223. {$endif PALMOSGDB}
  3224. {$else not SUPPORT_REMOTE}
  3225. GetGDBTargetShortName:=source_info.shortname
  3226. {$endif not SUPPORT_REMOTE}
  3227. end;
  3228. procedure InitDebugger;
  3229. {$ifdef DEBUG}
  3230. var s : string;
  3231. i,p : longint;
  3232. {$endif DEBUG}
  3233. var
  3234. NeedRecompileExe : boolean;
  3235. cm : longint;
  3236. begin
  3237. {$ifdef DEBUG}
  3238. if not use_gdb_file then
  3239. begin
  3240. Assign(gdb_file,GDBOutFileName);
  3241. {$I-}
  3242. Rewrite(gdb_file);
  3243. if InOutRes<>0 then
  3244. begin
  3245. s:=GDBOutFileName;
  3246. p:=pos('.',s);
  3247. if p>1 then
  3248. for i:=0 to 9 do
  3249. begin
  3250. s:=copy(s,1,p-2)+chr(i+ord('0'))+copy(s,p,length(s));
  3251. InOutRes:=0;
  3252. Assign(gdb_file,s);
  3253. rewrite(gdb_file);
  3254. if InOutRes=0 then
  3255. break;
  3256. end;
  3257. end;
  3258. if IOResult=0 then
  3259. Use_gdb_file:=true;
  3260. end;
  3261. {$I+}
  3262. {$endif}
  3263. NeedRecompileExe:=false;
  3264. if UpCaseStr(TargetSwitches^.GetCurrSelParam)<>UpCaseStr(GetGDBTargetShortName) then
  3265. begin
  3266. ClearFormatParams;
  3267. AddFormatParamStr(TargetSwitches^.GetCurrSelParam);
  3268. AddFormatParamStr(GetGDBTargetShortName);
  3269. cm:=ConfirmBox(msg_cantdebugchangetargetto,@FormatParams,true);
  3270. if cm=cmCancel then
  3271. Exit;
  3272. if cm=cmYes then
  3273. begin
  3274. { force recompilation }
  3275. PrevMainFile:='';
  3276. NeedRecompileExe:=true;
  3277. TargetSwitches^.SetCurrSelParam(GetGDBTargetShortName);
  3278. If DebugInfoSwitches^.GetCurrSelParam='-' then
  3279. DebugInfoSwitches^.SetCurrSelParam('l');
  3280. IDEApp.UpdateTarget;
  3281. end;
  3282. end;
  3283. if not NeedRecompileExe then
  3284. NeedRecompileExe:=(not ExistsFile(ExeFile)) or (CompilationPhase<>cpDone) or
  3285. (PrevMainFile<>MainFile) or NeedRecompile(cRun,false);
  3286. if Not NeedRecompileExe and Not MainHasDebugInfo then
  3287. begin
  3288. ClearFormatParams;
  3289. cm:=ConfirmBox(msg_compiledwithoutdebuginforecompile,nil,true);
  3290. if cm=cmCancel then
  3291. Exit;
  3292. if cm=cmYes then
  3293. begin
  3294. { force recompilation }
  3295. PrevMainFile:='';
  3296. NeedRecompileExe:=true;
  3297. DebugInfoSwitches^.SetCurrSelParam('l');
  3298. end;
  3299. end;
  3300. if NeedRecompileExe then
  3301. DoCompile(cRun);
  3302. if CompilationPhase<>cpDone then
  3303. Exit;
  3304. if (EXEFile='') then
  3305. begin
  3306. ErrorBox(msg_nothingtodebug,nil);
  3307. Exit;
  3308. end;
  3309. { init debugcontroller }
  3310. {$ifndef NODEBUG}
  3311. if not assigned(Debugger) then
  3312. begin
  3313. PushStatus(msg_startingdebugger);
  3314. new(Debugger,Init);
  3315. PopStatus;
  3316. end;
  3317. Debugger^.SetExe(ExeFile);
  3318. {$endif NODEBUG}
  3319. {$ifdef GDBWINDOW}
  3320. InitGDBWindow;
  3321. {$endif def GDBWINDOW}
  3322. end;
  3323. procedure DoneDebugger;
  3324. begin
  3325. {$ifdef DEBUG}
  3326. If IDEApp.IsRunning then
  3327. PushStatus('Closing debugger');
  3328. {$endif}
  3329. {$ifndef NODEBUG}
  3330. if assigned(Debugger) then
  3331. dispose(Debugger,Done);
  3332. Debugger:=nil;
  3333. {$endif NODEBUG}
  3334. {$ifdef DOS}
  3335. If assigned(UserScreen) then
  3336. PDosScreen(UserScreen)^.FreeGraphBuffer;
  3337. {$endif DOS}
  3338. {$ifdef DEBUG}
  3339. If Use_gdb_file then
  3340. begin
  3341. Use_gdb_file:=false;
  3342. Close(GDB_file);
  3343. end;
  3344. If IDEApp.IsRunning then
  3345. PopStatus;
  3346. {$endif DEBUG}
  3347. end;
  3348. procedure InitGDBWindow;
  3349. var
  3350. R : TRect;
  3351. begin
  3352. if GDBWindow=nil then
  3353. begin
  3354. DeskTop^.GetExtent(R);
  3355. new(GDBWindow,init(R));
  3356. DeskTop^.Insert(GDBWindow);
  3357. end;
  3358. end;
  3359. procedure DoneGDBWindow;
  3360. begin
  3361. If IDEApp.IsRunning and
  3362. assigned(GDBWindow) then
  3363. begin
  3364. DeskTop^.Delete(GDBWindow);
  3365. end;
  3366. GDBWindow:=nil;
  3367. end;
  3368. procedure InitDisassemblyWindow;
  3369. var
  3370. R : TRect;
  3371. begin
  3372. if DisassemblyWindow=nil then
  3373. begin
  3374. DeskTop^.GetExtent(R);
  3375. new(DisassemblyWindow,init(R));
  3376. DeskTop^.Insert(DisassemblyWindow);
  3377. end;
  3378. end;
  3379. procedure DoneDisassemblyWindow;
  3380. begin
  3381. if assigned(DisassemblyWindow) then
  3382. begin
  3383. DeskTop^.Delete(DisassemblyWindow);
  3384. Dispose(DisassemblyWindow,Done);
  3385. DisassemblyWindow:=nil;
  3386. end;
  3387. end;
  3388. procedure InitStackWindow;
  3389. begin
  3390. if StackWindow=nil then
  3391. begin
  3392. new(StackWindow,init);
  3393. DeskTop^.Insert(StackWindow);
  3394. end;
  3395. end;
  3396. procedure DoneStackWindow;
  3397. begin
  3398. if assigned(StackWindow) then
  3399. begin
  3400. DeskTop^.Delete(StackWindow);
  3401. StackWindow:=nil;
  3402. end;
  3403. end;
  3404. procedure InitBreakpoints;
  3405. begin
  3406. New(BreakpointsCollection,init(10,10));
  3407. end;
  3408. procedure DoneBreakpoints;
  3409. begin
  3410. Dispose(BreakpointsCollection,Done);
  3411. BreakpointsCollection:=nil;
  3412. end;
  3413. procedure InitWatches;
  3414. begin
  3415. New(WatchesCollection,init);
  3416. end;
  3417. procedure DoneWatches;
  3418. begin
  3419. Dispose(WatchesCollection,Done);
  3420. WatchesCollection:=nil;
  3421. end;
  3422. procedure RegisterFPDebugViews;
  3423. begin
  3424. RegisterType(RWatchesWindow);
  3425. RegisterType(RBreakpointsWindow);
  3426. RegisterType(RWatchesListBox);
  3427. RegisterType(RBreakpointsListBox);
  3428. RegisterType(RStackWindow);
  3429. RegisterType(RFramesListBox);
  3430. RegisterType(RBreakpoint);
  3431. RegisterType(RWatch);
  3432. RegisterType(RBreakpointCollection);
  3433. RegisterType(RWatchesCollection);
  3434. end;
  3435. end.
  3436. {$endif NODEBUG}