fpdebug.pas 124 KB

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