fpdebug.pas 126 KB

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