fpdebug.pas 118 KB

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