fpdebug.pas 125 KB

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