fpdebug.pas 123 KB

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