fpdebug.pas 99 KB

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