fpdebug.pas 99 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825
  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. {$ifdef NODEBUG}
  14. interface
  15. implementation
  16. end.
  17. {$else}
  18. interface
  19. {$i globdir.inc}
  20. uses
  21. {$ifdef win32}
  22. Windows,
  23. {$endif win32}
  24. Objects,Dialogs,Drivers,Views,
  25. {$ifndef NODEBUG}
  26. GDBCon,GDBInt,
  27. {$endif NODEBUG}
  28. Menus,
  29. WViews,WEditor,
  30. FPViews;
  31. type
  32. {$ifndef NODEBUG}
  33. PDebugController=^TDebugController;
  34. TDebugController=object(TGDBController)
  35. InvalidSourceLine : boolean;
  36. { if true the current debugger raw will stay in middle of
  37. editor window when debugging PM }
  38. CenterDebuggerRow : boolean;
  39. Disableallinvalidbreakpoints : boolean;
  40. OrigPwd, { pwd at startup }
  41. LastFileName : string;
  42. LastSource : PView; {PsourceWindow !! }
  43. HiddenStepsCount : longint;
  44. { no need to switch if using another terminal }
  45. NoSwitch : boolean;
  46. HasExe : boolean;
  47. RunCount : longint;
  48. WindowWidth : longint;
  49. FPCBreakErrorNumber : longint;
  50. {$ifdef SUPPORT_REMOTE}
  51. isRemoteDebugging:boolean;
  52. {$endif SUPPORT_REMOTE}
  53. constructor Init;
  54. procedure SetExe(const exefn:string);
  55. procedure SetWidth(AWidth : longint);
  56. procedure SetSourceDirs;
  57. destructor Done;
  58. procedure DoSelectSourceline(const fn:string;line:longint);virtual;
  59. { procedure DoStartSession;virtual;
  60. procedure DoBreakSession;virtual;}
  61. procedure DoEndSession(code:longint);virtual;
  62. procedure DoUserSignal;virtual;
  63. procedure AnnotateError;
  64. procedure InsertBreakpoints;
  65. procedure RemoveBreakpoints;
  66. procedure ReadWatches;
  67. procedure RereadWatches;
  68. procedure ResetBreakpointsValues;
  69. procedure DoDebuggerScreen;virtual;
  70. procedure DoUserScreen;virtual;
  71. procedure Reset;virtual;
  72. procedure ResetDebuggerRows;
  73. procedure Run;virtual;
  74. procedure Continue;virtual;
  75. procedure UntilReturn;virtual;
  76. procedure CommandBegin(const s:string);virtual;
  77. procedure CommandEnd(const s:string);virtual;
  78. function IsRunning : boolean;
  79. function AllowQuit : boolean;virtual;
  80. function GetValue(Const expr : string) : pchar;
  81. function GetFramePointer : CORE_ADDR;
  82. function GetLongintAt(addr : CORE_ADDR) : longint;
  83. function GetPointerAt(addr : CORE_ADDR) : CORE_ADDR;
  84. end;
  85. {$endif NODEBUG}
  86. BreakpointType = (bt_function,bt_file_line,bt_watch,
  87. bt_awatch,bt_rwatch,bt_address,bt_invalid);
  88. BreakpointState = (bs_enabled,bs_disabled,bs_deleted,bs_delete_after);
  89. PBreakpointCollection=^TBreakpointCollection;
  90. PBreakpoint=^TBreakpoint;
  91. TBreakpoint=object(TObject)
  92. typ : BreakpointType;
  93. state : BreakpointState;
  94. owner : PBreakpointCollection;
  95. Name : PString; { either function name or expr to watch }
  96. FileName : PString;
  97. OldValue,CurrentValue : Pstring;
  98. Line : Longint; { only used for bt_file_line type }
  99. Conditions : PString; { conditions relative to that breakpoint }
  100. IgnoreCount : Longint; { how many counts should be ignored }
  101. Commands : pchar; { commands that should be executed on breakpoint }
  102. GDBIndex : longint;
  103. GDBState : BreakpointState;
  104. constructor Init_function(Const AFunc : String);
  105. constructor Init_Address(Const AAddress : String);
  106. constructor Init_Empty;
  107. constructor Init_file_line(AFile : String; ALine : longint);
  108. constructor Init_type(atyp : BreakpointType;Const AnExpr : String);
  109. constructor Load(var S: TStream);
  110. procedure Store(var S: TStream);
  111. procedure Insert;
  112. procedure Remove;
  113. procedure Enable;
  114. procedure Disable;
  115. procedure UpdateSource;
  116. procedure ResetValues;
  117. destructor Done;virtual;
  118. end;
  119. TBreakpointCollection=object(TCollection)
  120. function At(Index: Integer): PBreakpoint;
  121. function GetGDB(index : longint) : PBreakpoint;
  122. function GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
  123. function ToggleFileLine(FileName: String;LineNr : Longint) : boolean;
  124. procedure Update;
  125. procedure ShowBreakpoints(W : PFPWindow);
  126. function FindBreakpointAt(Editor : PSourceEditor; Line : longint) : PBreakpoint;
  127. procedure AdaptBreakpoints(Editor : PSourceEditor; Pos, Change : longint);
  128. procedure ShowAllBreakpoints;
  129. end;
  130. PBreakpointItem = ^TBreakpointItem;
  131. TBreakpointItem = object(TObject)
  132. Breakpoint : PBreakpoint;
  133. constructor Init(ABreakpoint : PBreakpoint);
  134. function GetText(MaxLen: Sw_integer): string; virtual;
  135. procedure Selected; virtual;
  136. function GetModuleName: string; virtual;
  137. end;
  138. PBreakpointsListBox = ^TBreakpointsListBox;
  139. TBreakpointsListBox = object(THSListBox)
  140. Transparent : boolean;
  141. NoSelection : boolean;
  142. MaxWidth : Sw_integer;
  143. (* ModuleNames : PStoreCollection; *)
  144. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  145. procedure AddBreakpoint(P: PBreakpointItem); virtual;
  146. function GetText(Item,MaxLen: Sw_Integer): String; virtual;
  147. function GetLocalMenu: PMenu;virtual;
  148. procedure Clear; virtual;
  149. procedure TrackSource; virtual;
  150. procedure EditNew; virtual;
  151. procedure EditCurrent; virtual;
  152. procedure DeleteCurrent; virtual;
  153. procedure ToggleCurrent;
  154. procedure Draw; virtual;
  155. procedure HandleEvent(var Event: TEvent); virtual;
  156. constructor Load(var S: TStream);
  157. procedure Store(var S: TStream);
  158. destructor Done; virtual;
  159. end;
  160. PBreakpointsWindow = ^TBreakpointsWindow;
  161. TBreakpointsWindow = object(TFPDlgWindow)
  162. BreakLB : PBreakpointsListBox;
  163. constructor Init;
  164. procedure AddBreakpoint(ABreakpoint : PBreakpoint);
  165. procedure ClearBreakpoints;
  166. procedure ReloadBreakpoints;
  167. procedure Close; virtual;
  168. procedure SizeLimits(var Min, Max: TPoint);virtual;
  169. procedure HandleEvent(var Event: TEvent); virtual;
  170. procedure Update; virtual;
  171. constructor Load(var S: TStream);
  172. procedure Store(var S: TStream);
  173. destructor Done; virtual;
  174. end;
  175. PBreakpointItemDialog = ^TBreakpointItemDialog;
  176. TBreakpointItemDialog = object(TCenterDialog)
  177. constructor Init(ABreakpoint: PBreakpoint);
  178. function Execute: Word; virtual;
  179. private
  180. Breakpoint : PBreakpoint;
  181. TypeRB : PRadioButtons;
  182. NameIL : PEditorInputLine;
  183. ConditionsIL: PEditorInputLine;
  184. LineIL : PEditorInputLine;
  185. IgnoreIL : PEditorInputLine;
  186. end;
  187. PWatch = ^TWatch;
  188. TWatch = Object(TObject)
  189. constructor Init(s : string);
  190. constructor Load(var S: TStream);
  191. procedure Store(var S: TStream);
  192. procedure rename(s : string);
  193. procedure Get_new_value;
  194. procedure Force_new_value;
  195. destructor done;virtual;
  196. expr : pstring;
  197. private
  198. GDBRunCount : longint;
  199. last_value,current_value : pchar;
  200. end;
  201. PWatchesCollection = ^TWatchesCollection;
  202. TWatchesCollection = Object(TCollection)
  203. constructor Init;
  204. procedure Insert(Item: Pointer); virtual;
  205. function At(Index: Integer): PWatch;
  206. procedure Update;
  207. private
  208. MaxW : integer;
  209. end;
  210. PWatchesListBox = ^TWatchesListBox;
  211. TWatchesListBox = object(THSListBox)
  212. Transparent : boolean;
  213. MaxWidth : Sw_integer;
  214. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  215. (* procedure AddWatch(P: PWatch); virtual; *)
  216. procedure Update(AMaxWidth : integer);
  217. function GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String; Virtual;
  218. function GetIndentedText(Item,Indent,MaxLen: Sw_Integer;var Modified : boolean): String; virtual;
  219. function GetLocalMenu: PMenu;virtual;
  220. (* procedure Clear; virtual;
  221. procedure TrackSource; virtual;*)
  222. procedure EditNew; virtual;
  223. procedure EditCurrent; virtual;
  224. procedure DeleteCurrent; virtual;
  225. (*procedure ToggleCurrent; *)
  226. procedure Draw; virtual;
  227. procedure HandleEvent(var Event: TEvent); virtual;
  228. constructor Load(var S: TStream);
  229. procedure Store(var S: TStream);
  230. destructor Done; virtual;
  231. end;
  232. PWatchItemDialog = ^TWatchItemDialog;
  233. TWatchItemDialog = object(TCenterDialog)
  234. constructor Init(AWatch: PWatch);
  235. function Execute: Word; virtual;
  236. private
  237. Watch : PWatch;
  238. NameIL : PEditorInputLine;
  239. TextST : PAdvancedStaticText;
  240. end;
  241. PWatchesWindow = ^TWatchesWindow;
  242. TWatchesWindow = Object(TFPDlgWindow)
  243. WLB : PWatchesListBox;
  244. Constructor Init;
  245. constructor Load(var S: TStream);
  246. procedure Store(var S: TStream);
  247. procedure Update; virtual;
  248. destructor Done; virtual;
  249. end;
  250. PFramesListBox = ^TFramesListBox;
  251. TFramesListBox = object(TMessageListBox)
  252. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  253. procedure Update;
  254. function GetLocalMenu: PMenu;virtual;
  255. procedure GotoSource; virtual;
  256. procedure GotoAssembly; virtual;
  257. procedure HandleEvent(var Event: TEvent); virtual;
  258. destructor Done; virtual;
  259. end;
  260. PStackWindow = ^TStackWindow;
  261. TStackWindow = Object(TFPDlgWindow)
  262. FLB : PFramesListBox;
  263. Constructor Init;
  264. constructor Load(var S: TStream);
  265. procedure Store(var S: TStream);
  266. procedure Update; virtual;
  267. destructor Done; virtual;
  268. end;
  269. procedure InitStackWindow;
  270. procedure DoneStackWindow;
  271. function ActiveBreakpoints : boolean;
  272. function GDBFileName(st : string) : string;
  273. function OSFileName(st : string) : string;
  274. const
  275. BreakpointTypeStr : Array[BreakpointType] of String[9]
  276. = ( 'function','file-line','watch','awatch','rwatch','address','invalid');
  277. BreakpointStateStr : Array[BreakpointState] of String[8]
  278. = ( 'enabled','disabled','invalid',''{'to be deleted' should never be used});
  279. var
  280. {$ifndef NODEBUG}
  281. Debugger : PDebugController;
  282. {$endif NODEBUG}
  283. BreakpointsCollection : PBreakpointCollection;
  284. WatchesCollection : PwatchesCollection;
  285. procedure InitDebugger;
  286. procedure DoneDebugger;
  287. procedure InitGDBWindow;
  288. procedure DoneGDBWindow;
  289. procedure InitDisassemblyWindow;
  290. procedure DoneDisassemblyWindow;
  291. procedure InitBreakpoints;
  292. procedure DoneBreakpoints;
  293. procedure InitWatches;
  294. procedure DoneWatches;
  295. procedure RegisterFPDebugViews;
  296. procedure UpdateDebugViews;
  297. implementation
  298. uses
  299. Dos,
  300. {$ifdef fpc}
  301. Video,
  302. {$endif fpc}
  303. {$ifdef DOS}
  304. fpusrscr,
  305. {$endif DOS}
  306. App,Strings,
  307. FVConsts,
  308. {$ifdef win32}
  309. Windebug,
  310. {$endif win32}
  311. {$ifdef Unix}
  312. {$ifdef VER1_0}
  313. Linux,
  314. {$else}
  315. termio,
  316. {$endif}
  317. {$endif Unix}
  318. Systems,Globals,
  319. FPRegs,
  320. FPString,FPVars,FPUtils,FPConst,FPSwitch,
  321. FPIntf,FPCompil,FPIde,FPHelp,
  322. Validate,WUtils,Wconsts;
  323. const
  324. RBreakpointsWindow: TStreamRec = (
  325. ObjType: 1701;
  326. VmtLink: Ofs(TypeOf(TBreakpointsWindow)^);
  327. Load: @TBreakpointsWindow.Load;
  328. Store: @TBreakpointsWindow.Store
  329. );
  330. RBreakpointsListBox : TStreamRec = (
  331. ObjType: 1702;
  332. VmtLink: Ofs(TypeOf(TBreakpointsListBox)^);
  333. Load: @TBreakpointsListBox.Load;
  334. Store: @TBreakpointsListBox.Store
  335. );
  336. RWatchesWindow: TStreamRec = (
  337. ObjType: 1703;
  338. VmtLink: Ofs(TypeOf(TWatchesWindow)^);
  339. Load: @TWatchesWindow.Load;
  340. Store: @TWatchesWindow.Store
  341. );
  342. RWatchesListBox: TStreamRec = (
  343. ObjType: 1704;
  344. VmtLink: Ofs(TypeOf(TWatchesListBox)^);
  345. Load: @TWatchesListBox.Load;
  346. Store: @TWatchesListBox.Store
  347. );
  348. RStackWindow: TStreamRec = (
  349. ObjType: 1705;
  350. VmtLink: Ofs(TypeOf(TStackWindow)^);
  351. Load: @TStackWindow.Load;
  352. Store: @TStackWindow.Store
  353. );
  354. RFramesListBox: TStreamRec = (
  355. ObjType: 1706;
  356. VmtLink: Ofs(TypeOf(TFramesListBox)^);
  357. Load: @TFramesListBox.Load;
  358. Store: @TFramesListBox.Store
  359. );
  360. RBreakpoint: TStreamRec = (
  361. ObjType: 1707;
  362. VmtLink: Ofs(TypeOf(TBreakpoint)^);
  363. Load: @TBreakpoint.Load;
  364. Store: @TBreakpoint.Store
  365. );
  366. RWatch: TStreamRec = (
  367. ObjType: 1708;
  368. VmtLink: Ofs(TypeOf(TWatch)^);
  369. Load: @TWatch.Load;
  370. Store: @TWatch.Store
  371. );
  372. RBreakpointCollection: TStreamRec = (
  373. ObjType: 1709;
  374. VmtLink: Ofs(TypeOf(TBreakpointCollection)^);
  375. Load: @TBreakpointCollection.Load;
  376. Store: @TBreakpointCollection.Store
  377. );
  378. RWatchesCollection: TStreamRec = (
  379. ObjType: 1710;
  380. VmtLink: Ofs(TypeOf(TWatchesCollection)^);
  381. Load: @TWatchesCollection.Load;
  382. Store: @TWatchesCollection.Store
  383. );
  384. {$ifdef I386}
  385. const
  386. FrameName = '$ebp';
  387. {$define FrameNameKnown}
  388. {$endif i386}
  389. {$ifdef m68k}
  390. const
  391. FrameName = '$fp';
  392. {$define FrameNameKnown}
  393. {$endif m68k}
  394. {$ifdef powerpc}
  395. { stack and frame registers are the same on powerpc,
  396. so I am not sure that this will work PM }
  397. const
  398. FrameName = '$r1';
  399. {$define FrameNameKnown}
  400. {$endif powerpc}
  401. {$ifdef TP}
  402. function HexStr(Value: longint; Len: byte): string;
  403. begin
  404. HexStr:=IntToHex(Value,Len);
  405. end;
  406. {$endif}
  407. function GDBFileName(st : string) : string;
  408. {$ifndef Unix}
  409. var i : longint;
  410. {$endif Unix}
  411. begin
  412. {$ifdef NODEBUG}
  413. GDBFileName:=st;
  414. {$else NODEBUG}
  415. {$ifdef Unix}
  416. GDBFileName:=st;
  417. {$else}
  418. { should we also use / chars ? }
  419. for i:=1 to Length(st) do
  420. if st[i]='\' then
  421. {$ifdef win32}
  422. { Don't touch at '\ ' used to escapes spaces in windows file names PM }
  423. if (i=length(st)) or (st[i+1]<>' ') then
  424. {$endif win32}
  425. st[i]:='/';
  426. {$ifdef win32}
  427. { for win32 we should convert e:\ into //e/ PM }
  428. if (length(st)>2) and (st[2]=':') and (st[3]='/') then
  429. st:=CygDrivePrefix+'/'+st[1]+copy(st,3,length(st));
  430. { support spaces in the name by escaping them but without changing '\ ' into '\\ ' }
  431. for i:=Length(st) downto 1 do
  432. if (st[i]=' ') and ((i=1) or (st[i-1]<>'\')) then
  433. st:=copy(st,1,i-1)+'\'+copy(st,i,length(st));
  434. {$endif win32}
  435. {$ifdef go32v2}
  436. { for go32v2 we should convert //e/ back into e:/ PM }
  437. if (length(st)>3) and (st[1]='/') and (st[2]='/') and (st[4]='/') then
  438. st:=st[3]+':/'+copy(st,5,length(st));
  439. {$endif go32v2}
  440. GDBFileName:=LowerCaseStr(st);
  441. {$endif}
  442. {$endif NODEBUG}
  443. end;
  444. function OSFileName(st : string) : string;
  445. {$ifndef Unix}
  446. var i : longint;
  447. {$endif Unix}
  448. begin
  449. {$ifdef Unix}
  450. OSFileName:=st;
  451. {$else}
  452. {$ifdef win32}
  453. {$ifndef NODEBUG}
  454. { for win32 we should convert /cygdrive/e/ into e:\ PM }
  455. if pos(CygDrivePrefix+'/',st)=1 then
  456. st:=st[Length(CygdrivePrefix)+2]+':\'+copy(st,length(CygdrivePrefix)+4,length(st));
  457. {$endif NODEBUG}
  458. {$endif win32}
  459. { support spaces in the name by escaping them but without changing '\ ' into '\\ ' }
  460. for i:=Length(st) downto 2 do
  461. if (st[i]=' ') and (st[i-1]='\') then
  462. st:=copy(st,1,i-2)+copy(st,i,length(st));
  463. {$ifdef go32v2}
  464. { for go32v2 we should convert //e/ back into e:/ PM }
  465. if (length(st)>3) and (st[1]='/') and (st[2]='/') and (st[4]='/') then
  466. st:=st[3]+':\'+copy(st,5,length(st));
  467. {$endif go32v2}
  468. { should we also use / chars ? }
  469. for i:=1 to Length(st) do
  470. if st[i]='/' then
  471. st[i]:='\';
  472. OSFileName:=LowerCaseStr(st);
  473. {$endif}
  474. end;
  475. {****************************************************************************
  476. TDebugController
  477. ****************************************************************************}
  478. procedure UpdateDebugViews;
  479. begin
  480. {$ifdef SUPPORT_REMOTE}
  481. PushStatus(msg_getting_info_on+RemoteMachine);
  482. {$endif SUPPORT_REMOTE}
  483. DeskTop^.Lock;
  484. If assigned(StackWindow) then
  485. StackWindow^.Update;
  486. If assigned(RegistersWindow) then
  487. RegistersWindow^.Update;
  488. {$ifndef NODEBUG}
  489. If assigned(Debugger) then
  490. Debugger^.ReadWatches;
  491. {$endif NODEBUG}
  492. If assigned(FPUWindow) then
  493. FPUWindow^.Update;
  494. DeskTop^.UnLock;
  495. {$ifdef SUPPORT_REMOTE}
  496. PopStatus;
  497. {$endif SUPPORT_REMOTE}
  498. end;
  499. {$ifndef NODEBUG}
  500. constructor TDebugController.Init;
  501. begin
  502. inherited Init;
  503. CenterDebuggerRow:=IniCenterDebuggerRow;
  504. Disableallinvalidbreakpoints:=false;
  505. NoSwitch:=False;
  506. HasExe:=false;
  507. Debugger:=@self;
  508. WindowWidth:=-1;
  509. switch_to_user:=true;
  510. GetDir(0,OrigPwd);
  511. Command('set print object off');
  512. end;
  513. procedure TDebugController.SetExe(const exefn:string);
  514. var f : string;
  515. begin
  516. f := GDBFileName(GetShortName(exefn));
  517. if (f<>'') and ExistsFile(exefn) then
  518. begin
  519. LoadFile(f);
  520. HasExe:=true;
  521. Command('b FPC_BREAK_ERROR');
  522. FPCBreakErrorNumber:=last_breakpoint_number;
  523. {$ifdef FrameNameKnown}
  524. { this fails in GDB 5.1 because
  525. GDB replies that there is an attempt to dereference
  526. a generic pointer...
  527. test delayed in DoSourceLine... PM
  528. Command('cond '+IntToStr(FPCBreakErrorNumber)+
  529. ' (('+FrameName+' + 8)^ <> 0) or'+
  530. ' (('+FrameName+' + 12)^ <> 0)'); }
  531. {$endif FrameNameKnown}
  532. SetArgs(GetRunParameters);
  533. SetSourceDirs;
  534. InsertBreakpoints;
  535. ReadWatches;
  536. end
  537. else
  538. begin
  539. HasExe:=false;
  540. Command('file');
  541. end;
  542. end;
  543. procedure TDebugController.SetWidth(AWidth : longint);
  544. begin
  545. WindowWidth:=AWidth;
  546. Command('set width '+inttostr(WindowWidth));
  547. end;
  548. procedure TDebugController.SetSourceDirs;
  549. var f,s: string;
  550. i : longint;
  551. Dir : SearchRec;
  552. begin
  553. f:=GetSourceDirectories+';'+OrigPwd;
  554. repeat
  555. i:=pos(';',f);
  556. if i=0 then
  557. s:=f
  558. else
  559. begin
  560. s:=copy(f,1,i-1);
  561. system.delete(f,1,i);
  562. end;
  563. DefaultReplacements(s);
  564. if (pos('*',s)=0) and ExistsDir(s) then
  565. Command('dir '+GDBFileName(GetShortName(s)))
  566. { we should also handle the /* cases of -Fu option }
  567. else if pos('*',s)>0 then
  568. begin
  569. Dos.FindFirst(s,Directory,Dir);
  570. { the '*' can only be in the last dir level }
  571. s:=DirOf(s);
  572. while Dos.DosError=0 do
  573. begin
  574. if ((Dir.attr and Directory) <> 0) and ExistsDir(s+Dir.Name) then
  575. Command('dir '+GDBFileName(GetShortName(s+Dir.Name)));
  576. Dos.FindNext(Dir);
  577. end;
  578. {$ifdef FPC}
  579. Dos.FindClose(Dir);
  580. {$endif def FPC}
  581. end;
  582. until i=0;
  583. end;
  584. procedure TDebugController.InsertBreakpoints;
  585. procedure DoInsert(PB : PBreakpoint);
  586. begin
  587. PB^.Insert;
  588. end;
  589. begin
  590. BreakpointsCollection^.ForEach(@DoInsert);
  591. Disableallinvalidbreakpoints:=false;
  592. end;
  593. procedure TDebugController.ReadWatches;
  594. procedure DoRead(PB : PWatch);
  595. begin
  596. PB^.Get_new_value;
  597. end;
  598. begin
  599. WatchesCollection^.ForEach(@DoRead);
  600. If Assigned(WatchesWindow) then
  601. WatchesWindow^.Update;
  602. end;
  603. procedure TDebugController.RereadWatches;
  604. procedure DoRead(PB : PWatch);
  605. begin
  606. PB^.Force_new_value;
  607. end;
  608. begin
  609. WatchesCollection^.ForEach(@DoRead);
  610. If Assigned(WatchesWindow) then
  611. WatchesWindow^.Update;
  612. end;
  613. procedure TDebugController.RemoveBreakpoints;
  614. procedure DoDelete(PB : PBreakpoint);
  615. begin
  616. PB^.Remove;
  617. end;
  618. begin
  619. BreakpointsCollection^.ForEach(@DoDelete);
  620. end;
  621. procedure TDebugController.ResetBreakpointsValues;
  622. procedure DoResetVal(PB : PBreakpoint);
  623. begin
  624. PB^.ResetValues;
  625. end;
  626. begin
  627. BreakpointsCollection^.ForEach(@DoResetVal);
  628. end;
  629. destructor TDebugController.Done;
  630. begin
  631. { kill the program if running }
  632. Reset;
  633. RemoveBreakpoints;
  634. inherited Done;
  635. end;
  636. procedure TDebugController.Run;
  637. {$ifdef Unix}
  638. var
  639. Debuggeefile : text;
  640. ResetOK, TTYUsed : boolean;
  641. {$endif Unix}
  642. {$ifdef PALMOSGDB}
  643. const
  644. TargetProtocol = 'palmos';
  645. {$else}
  646. const
  647. TargetProtocol = 'remote';
  648. {$endif PALMOSGDB}
  649. {$ifdef SUPPORT_REMOTE}
  650. var
  651. S,ErrorStr : string;
  652. {$endif SUPPORT_REMOTE}
  653. begin
  654. ResetBreakpointsValues;
  655. {$ifdef SUPPORT_REMOTE}
  656. NoSwitch:=true;
  657. isRemoteDebugging:=false;
  658. {$ifndef CROSSGDB}
  659. If (RemoteMachine<>'') and (RemotePort<>'') then
  660. {$else CROSSGDB}
  661. if true then
  662. {$endif CROSSGDB}
  663. begin
  664. isRemoteDebugging:=true;
  665. S:=RemoteMachine;
  666. If pos('@',S)>0 then
  667. S:=copy(S,pos('@',S)+1,High(S));
  668. If RemotePort<>'' then
  669. S:=S+':'+RemotePort;
  670. {$ifdef PALMOSGDB}
  671. { set the default value for PalmOS }
  672. If S='' then
  673. S:='localhost:2000';
  674. {$endif PALMOSGDB}
  675. PushStatus(msg_connectingto+S);
  676. Command('target '+TargetProtocol+' '+S);
  677. if Error then
  678. begin
  679. ErrorStr:=strpas(GetError);
  680. ErrorBox(#3'Error in "target '+TargetProtocol+'"'#13#3+ErrorStr,nil);
  681. PopStatus;
  682. exit;
  683. end;
  684. PopStatus;
  685. end
  686. else
  687. begin
  688. {$endif SUPPORT_REMOTE}
  689. {$ifdef win32}
  690. { Run the debugge in another console }
  691. if DebuggeeTTY<>'' then
  692. Command('set new-console on')
  693. else
  694. Command('set new-console off');
  695. NoSwitch:=DebuggeeTTY<>'';
  696. {$endif win32}
  697. {$ifdef Unix}
  698. { Run the debuggee in another tty }
  699. if DebuggeeTTY <> '' then
  700. begin
  701. {$I-}
  702. Assign(Debuggeefile,DebuggeeTTY);
  703. system.Reset(Debuggeefile);
  704. ResetOK:=IOResult=0;
  705. If ResetOK and {$ifdef ver1_0}IsATTY(textrec(Debuggeefile).handle){$else}(IsATTY(textrec(Debuggeefile).handle)<>-1){$endif} then
  706. begin
  707. Command('tty '+DebuggeeTTY);
  708. TTYUsed:=true;
  709. end
  710. else
  711. begin
  712. Command('tty ');
  713. TTYUsed:=false;
  714. end;
  715. if ResetOK then
  716. close(Debuggeefile);
  717. if TTYUsed and (DebuggeeTTY<>TTYName(stdout)) then
  718. NoSwitch:= true
  719. else
  720. NoSwitch:=false;
  721. end
  722. else
  723. begin
  724. if TTYName(input)<>'' then
  725. Command('tty '+TTYName(input));
  726. NoSwitch := false;
  727. end;
  728. {$endif Unix}
  729. {$ifdef SUPPORT_REMOTE}
  730. end;
  731. {$endif SUPPORT_REMOTE}
  732. { Switch to user screen to get correct handles }
  733. UserScreen;
  734. { Don't try to print GDB messages while in User Screen mode }
  735. If assigned(GDBWindow) then
  736. GDBWindow^.Editor^.Lock;
  737. {$ifdef SUPPORT_REMOTE}
  738. if isRemoteDebugging then
  739. begin
  740. inc(init_count);
  741. { pass the stop in start code }
  742. Command('continue');
  743. end else
  744. {$endif SUPPORT_REMOTE}
  745. { Set cwd for debuggee }
  746. SetDir(GetRunDir);
  747. inherited Run;
  748. { Restore cwd for IDE }
  749. SetDir(StartupDir);
  750. DebuggerScreen;
  751. If assigned(GDBWindow) then
  752. GDBWindow^.Editor^.UnLock;
  753. IDEApp.SetCmdState([cmResetDebugger,cmUntilReturn],true);
  754. IDEApp.UpdateRunMenu(true);
  755. UpdateDebugViews;
  756. end;
  757. function TDebugController.IsRunning : boolean;
  758. begin
  759. IsRunning:=debuggee_started;
  760. end;
  761. procedure TDebugController.Continue;
  762. begin
  763. {$ifdef NODEBUG}
  764. NoDebugger;
  765. {$else}
  766. if not debuggee_started then
  767. Run
  768. else
  769. inherited Continue;
  770. UpdateDebugViews;
  771. {$endif NODEBUG}
  772. end;
  773. procedure TDebugController.UntilReturn;
  774. begin
  775. Command('finish');
  776. UpdateDebugViews;
  777. { We could try to get the return value !
  778. Not done yet }
  779. end;
  780. procedure TDebugController.CommandBegin(const s:string);
  781. begin
  782. if assigned(GDBWindow) and (in_command>1) then
  783. begin
  784. { We should do something special for errors !! }
  785. If StrLen(GetError)>0 then
  786. GDBWindow^.WriteErrorText(GetError);
  787. GDBWindow^.WriteOutputText(GetOutput);
  788. end;
  789. if assigned(GDBWindow) then
  790. GDBWindow^.WriteString(S);
  791. end;
  792. procedure TDebugController.CommandEnd(const s:string);
  793. begin
  794. if assigned(GDBWindow) and (in_command<=1) then
  795. begin
  796. { We should do something special for errors !! }
  797. If StrLen(GetError)>0 then
  798. GDBWindow^.WriteErrorText(GetError);
  799. GDBWindow^.WriteOutputText(GetOutput);
  800. GDBWindow^.Editor^.TextEnd;
  801. end;
  802. end;
  803. function TDebugController.AllowQuit : boolean;
  804. begin
  805. if IsRunning then
  806. begin
  807. if ConfirmBox('Really quit GDB window'#13+
  808. 'and kill running program?',nil,true)=cmYes then
  809. begin
  810. Reset;
  811. DoneGDBWindow;
  812. {AllowQuit:=true;}
  813. AllowQuit:=false;
  814. end
  815. else
  816. AllowQuit:=false;
  817. end
  818. else if ConfirmBox('Really quit GDB window?',nil,true)=cmYes then
  819. begin
  820. DoneGDBWindow;
  821. {AllowQuit:=true;}
  822. AllowQuit:=false;
  823. end
  824. else
  825. AllowQuit:=false;
  826. end;
  827. procedure TDebugController.ResetDebuggerRows;
  828. procedure ResetDebuggerRow(P: PView); {$ifndef FPC}far;{$endif}
  829. begin
  830. if assigned(P) and
  831. (TypeOf(P^)=TypeOf(TSourceWindow)) then
  832. PSourceWindow(P)^.Editor^.SetLineFlagExclusive(lfDebuggerRow,-1);
  833. end;
  834. begin
  835. Desktop^.ForEach(@ResetDebuggerRow);
  836. end;
  837. procedure TDebugController.Reset;
  838. begin
  839. inherited Reset;
  840. { we need to free the executable
  841. if we want to recompile it }
  842. SetExe('');
  843. NoSwitch:=false;
  844. { In case we have something that the compiler touched }
  845. If IDEApp.IsRunning then
  846. begin
  847. IDEApp.SetCmdState([cmResetDebugger,cmUntilReturn],false);
  848. IDEApp.UpdateRunMenu(false);
  849. AskToReloadAllModifiedFiles;
  850. ResetDebuggerRows;
  851. end;
  852. end;
  853. procedure TDebugController.AnnotateError;
  854. var errornb : longint;
  855. begin
  856. if error then
  857. begin
  858. errornb:=error_num;
  859. UpdateDebugViews;
  860. ErrorBox(#3'Error within GDB'#13#3'Error code = %d',@errornb);
  861. end;
  862. end;
  863. function TDebugController.GetValue(Const expr : string) : pchar;
  864. var
  865. p,p2,p3 : pchar;
  866. begin
  867. if WindowWidth<>-1 then
  868. Command('set width 0xffffffff');
  869. Command('p '+expr);
  870. p:=GetOutput;
  871. p3:=nil;
  872. if assigned(p) and (p[strlen(p)-1]=#10) then
  873. begin
  874. p3:=p+strlen(p)-1;
  875. p3^:=#0;
  876. end;
  877. if assigned(p) then
  878. p2:=strpos(p,'=')
  879. else
  880. p2:=nil;
  881. if assigned(p2) then
  882. p:=p2+1;
  883. while p^ in [' ',TAB] do
  884. inc(p);
  885. { get rid of type }
  886. if p^ = '(' then
  887. p:=strpos(p,')')+1;
  888. while p^ in [' ',TAB] do
  889. inc(p);
  890. if assigned(p) then
  891. GetValue:=StrNew(p)
  892. else
  893. GetValue:=StrNew(GetError);
  894. if assigned(p3) then
  895. p3^:=#10;
  896. got_error:=false;
  897. if WindowWidth<>-1 then
  898. Command('set width '+IntToStr(WindowWidth));
  899. end;
  900. function TDebugController.GetFramePointer : CORE_ADDR;
  901. var
  902. st : string;
  903. p : longint;
  904. begin
  905. {$ifdef FrameNameKnown}
  906. Command('p /d '+FrameName);
  907. st:=strpas(GetOutput);
  908. p:=pos('=',st);
  909. while (p<length(st)) and (st[p+1] in [' ',#9]) do
  910. inc(p);
  911. Delete(st,1,p);
  912. p:=1;
  913. while (st[p] in ['0'..'9']) do
  914. inc(p);
  915. Delete(st,p,High(st));
  916. GetFramePointer:=StrToCard(st);
  917. {$else not FrameNameKnown}
  918. GetFramePointer:=0;
  919. {$endif not FrameNameKnown}
  920. end;
  921. function TDebugController.GetLongintAt(addr : CORE_ADDR) : longint;
  922. var
  923. st : string;
  924. p : longint;
  925. begin
  926. Command('x /wd 0x'+hexstr(longint(addr),8));
  927. st:=strpas(GetOutput);
  928. p:=pos(':',st);
  929. while (p<length(st)) and (st[p+1] in [' ',#9]) do
  930. inc(p);
  931. Delete(st,1,p);
  932. p:=1;
  933. while (st[p] in ['0'..'9']) do
  934. inc(p);
  935. Delete(st,p,High(st));
  936. GetLongintAt:=StrToInt(st);
  937. end;
  938. function TDebugController.GetPointerAt(addr : CORE_ADDR) : CORE_ADDR;
  939. var
  940. st : string;
  941. p : longint;
  942. begin
  943. Command('x /wx 0x'+hexstr(longint(addr),8));
  944. st:=strpas(GetOutput);
  945. p:=pos(':',st);
  946. while (p<length(st)) and (st[p+1] in [' ',#9]) do
  947. inc(p);
  948. if (p<length(st)) and (st[p+1]='$') then
  949. inc(p);
  950. Delete(st,1,p);
  951. p:=1;
  952. while (st[p] in ['0'..'9','A'..'F','a'..'f']) do
  953. inc(p);
  954. Delete(st,p,High(st));
  955. GetPointerAt:=HexToCard(st);
  956. end;
  957. procedure TDebugController.DoSelectSourceLine(const fn:string;line:longint);
  958. var
  959. W: PSourceWindow;
  960. Found : boolean;
  961. PB : PBreakpoint;
  962. S : String;
  963. BreakIndex : longint;
  964. stop_addr : CORE_ADDR;
  965. i,ExitCode : longint;
  966. ExitAddr,ExitFrame : CORE_ADDR;
  967. const
  968. FirstArgOffset = 2 * sizeof(CORE_ADDR);
  969. SecondArgOffset = 3 * sizeof(CORE_ADDR);
  970. ThirdArgOffset = 4 * sizeof(CORE_ADDR);
  971. begin
  972. BreakIndex:=stop_breakpoint_number;
  973. Desktop^.Lock;
  974. { 0 based line count in Editor }
  975. if Line>0 then
  976. dec(Line);
  977. S:=fn;
  978. stop_addr:=current_pc;
  979. if (BreakIndex=FPCBreakErrorNumber) then
  980. begin
  981. { Procedure HandleErrorAddrFrame
  982. (Errno : longint;addr,frame : longint);
  983. [public,alias:'FPC_BREAK_ERROR']; }
  984. {$ifdef FrameNameKnown}
  985. ExitCode:=GetLongintAt(GetFramePointer+FirstArgOffset);
  986. ExitAddr:=GetPointerAt(GetFramePointer+SecondArgOffset);
  987. ExitFrame:=GetPointerAt(GetFramePointer+ThirdArgOffset);
  988. if (ExitCode=0) and (ExitAddr=0) then
  989. begin
  990. Desktop^.Unlock;
  991. Command('continue');
  992. exit;
  993. end;
  994. { forget all old frames }
  995. clear_frames;
  996. { record new frames }
  997. Command('backtrace');
  998. for i:=0 to frame_count-1 do
  999. begin
  1000. with frames[i]^ do
  1001. begin
  1002. if ExitAddr=address then
  1003. begin
  1004. Command('f '+IntToStr(i));
  1005. if assigned(file_name) then
  1006. begin
  1007. s:=strpas(file_name);
  1008. line:=line_number;
  1009. stop_addr:=address;
  1010. end;
  1011. break;
  1012. end;
  1013. end;
  1014. end;
  1015. {$endif FrameNameKnown}
  1016. end;
  1017. { Update Disassembly position }
  1018. if Assigned(DisassemblyWindow) then
  1019. DisassemblyWindow^.SetCurAddress(stop_addr);
  1020. if (fn=LastFileName) then
  1021. begin
  1022. W:=PSourceWindow(LastSource);
  1023. if assigned(W) then
  1024. begin
  1025. W^.Editor^.SetCurPtr(0,Line);
  1026. W^.Editor^.TrackCursor(CenterDebuggerRow);
  1027. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,Line);
  1028. UpdateDebugViews;
  1029. {if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  1030. handled by SelectInDebugSession}
  1031. W^.SelectInDebugSession;
  1032. InvalidSourceLine:=false;
  1033. end
  1034. else
  1035. InvalidSourceLine:=true;
  1036. end
  1037. else
  1038. begin
  1039. if s='' then
  1040. W:=nil
  1041. else
  1042. W:=TryToOpenFile(nil,s,0,Line,false);
  1043. if assigned(W) then
  1044. begin
  1045. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,Line);
  1046. W^.Editor^.TrackCursor(CenterDebuggerRow);
  1047. UpdateDebugViews;
  1048. {if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  1049. handled by SelectInDebugSession}
  1050. W^.SelectInDebugSession;
  1051. LastSource:=W;
  1052. InvalidSourceLine:=false;
  1053. end
  1054. { only search a file once }
  1055. else
  1056. begin
  1057. Desktop^.UnLock;
  1058. if s='' then
  1059. Found:=false
  1060. else
  1061. { it is easier to handle with a * at the end }
  1062. Found:=IDEApp.OpenSearch(s+'*');
  1063. Desktop^.Lock;
  1064. if not Found then
  1065. begin
  1066. InvalidSourceLine:=true;
  1067. LastSource:=Nil;
  1068. { Show the stack in that case }
  1069. InitStackWindow;
  1070. UpdateDebugViews;
  1071. StackWindow^.MakeFirst;
  1072. end
  1073. else
  1074. begin
  1075. { should now be open }
  1076. W:=TryToOpenFile(nil,s,0,Line,true);
  1077. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,Line);
  1078. W^.Editor^.TrackCursor(CenterDebuggerRow);
  1079. UpdateDebugViews;
  1080. {if Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive) then
  1081. handled by SelectInDebugSession}
  1082. W^.SelectInDebugSession;
  1083. LastSource:=W;
  1084. InvalidSourceLine:=false;
  1085. end;
  1086. end;
  1087. end;
  1088. LastFileName:=s;
  1089. Desktop^.UnLock;
  1090. if BreakIndex>0 then
  1091. begin
  1092. PB:=BreakpointsCollection^.GetGDB(BreakIndex);
  1093. if (BreakIndex=FPCBreakErrorNumber) then
  1094. begin
  1095. if (ExitCode<>0) or (ExitAddr<>0) then
  1096. WarningBox(#3'Run Time Error '+IntToStr(ExitCode)+#13+
  1097. #3'Error address $'+IntToHex(ExitAddr,8),nil)
  1098. else
  1099. WarningBox(#3'Run Time Error',nil);
  1100. end
  1101. else if not assigned(PB) then
  1102. begin
  1103. WarningBox(#3'Stopped by breakpoint '+IntToStr(BreakIndex),nil);
  1104. end
  1105. { For watch we should get old and new value !! }
  1106. else if (Not assigned(GDBWindow) or not GDBWindow^.GetState(sfActive)) and
  1107. (PB^.typ<>bt_file_line) and (PB^.typ<>bt_function) and
  1108. (PB^.typ<>bt_address) then
  1109. begin
  1110. Command('p '+GetStr(PB^.Name));
  1111. S:=GetPChar(GetOutput);
  1112. got_error:=false;
  1113. If Pos('=',S)>0 then
  1114. S:=Copy(S,Pos('=',S)+1,255);
  1115. If S[Length(S)]=#10 then
  1116. Delete(S,Length(S),1);
  1117. if Assigned(PB^.OldValue) then
  1118. DisposeStr(PB^.OldValue);
  1119. PB^.OldValue:=PB^.CurrentValue;
  1120. PB^.CurrentValue:=NewStr(S);
  1121. If PB^.typ=bt_function then
  1122. WarningBox(#3'GDB stopped due to'#13+
  1123. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name),nil)
  1124. else if (GetStr(PB^.OldValue)<>S) then
  1125. WarningBox(#3'GDB stopped due to'#13+
  1126. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
  1127. #3+'Old value = '+GetStr(PB^.OldValue)+#13+
  1128. #3+'New value = '+GetStr(PB^.CurrentValue),nil)
  1129. else
  1130. WarningBox(#3'GDB stopped due to'#13+
  1131. #3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
  1132. #3+' value = '+GetStr(PB^.CurrentValue),nil);
  1133. end;
  1134. end;
  1135. end;
  1136. procedure TDebugController.DoUserSignal;
  1137. var P :Array[1..2] of pstring;
  1138. S1, S2 : string;
  1139. begin
  1140. S1:=strpas(signal_name);
  1141. S2:=strpas(signal_string);
  1142. P[1]:=@S1;
  1143. P[2]:=@S2;
  1144. WarningBox(msg_programsignal,@P);
  1145. end;
  1146. procedure TDebugController.DoEndSession(code:longint);
  1147. var P :Array[1..2] of longint;
  1148. begin
  1149. IDEApp.SetCmdState([cmUntilReturn,cmResetDebugger],false);
  1150. IDEApp.UpdateRunMenu(false);
  1151. ResetDebuggerRows;
  1152. LastExitCode:=Code;
  1153. If HiddenStepsCount=0 then
  1154. InformationBox(msg_programexitedwithexitcode,@code)
  1155. else
  1156. begin
  1157. P[1]:=code;
  1158. P[2]:=HiddenStepsCount;
  1159. WarningBox(msg_programexitedwithcodeandsteps,@P);
  1160. end;
  1161. { In case we have something that the compiler touched }
  1162. AskToReloadAllModifiedFiles;
  1163. {$ifdef win32}
  1164. main_pid_valid:=false;
  1165. {$endif win32}
  1166. end;
  1167. procedure TDebugController.DoDebuggerScreen;
  1168. {$ifdef win32}
  1169. var
  1170. IdeMode : DWord;
  1171. {$endif win32}
  1172. begin
  1173. if NoSwitch then
  1174. begin
  1175. PopStatus;
  1176. end
  1177. else
  1178. begin
  1179. IDEApp.ShowIDEScreen;
  1180. Message(Application,evBroadcast,cmDebuggerStopped,pointer(ptrint(RunCount)));
  1181. PopStatus;
  1182. end;
  1183. {$ifdef win32}
  1184. if NoSwitch then
  1185. begin
  1186. { Ctrl-C as normal char }
  1187. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @IdeMode);
  1188. IdeMode:=(IdeMode or ENABLE_MOUSE_INPUT or ENABLE_WINDOW_INPUT) and not ENABLE_PROCESSED_INPUT;
  1189. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), IdeMode);
  1190. end;
  1191. ChangeDebuggeeWindowTitleTo(Stopped_State);
  1192. {$endif win32}
  1193. end;
  1194. procedure TDebugController.DoUserScreen;
  1195. {$ifdef win32}
  1196. var
  1197. IdeMode : DWord;
  1198. {$endif win32}
  1199. begin
  1200. Inc(RunCount);
  1201. if NoSwitch then
  1202. begin
  1203. {$ifdef SUPPORT_REMOTE}
  1204. PushStatus(msg_runningremotely+RemoteMachine);
  1205. {$else not SUPPORT_REMOTE}
  1206. {$ifdef Unix}
  1207. PushStatus(msg_runninginanotherwindow+DebuggeeTTY);
  1208. {$else not Unix}
  1209. PushStatus(msg_runninginanotherwindow);
  1210. {$endif Unix}
  1211. {$endif not SUPPORT_REMOTE}
  1212. end
  1213. else
  1214. begin
  1215. PushStatus(msg_runningprogram);
  1216. IDEApp.ShowUserScreen;
  1217. end;
  1218. {$ifdef win32}
  1219. if NoSwitch then
  1220. begin
  1221. { Ctrl-C as interrupt }
  1222. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @IdeMode);
  1223. IdeMode:=(IdeMode or ENABLE_MOUSE_INPUT or ENABLE_PROCESSED_INPUT or ENABLE_WINDOW_INPUT);
  1224. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), IdeMode);
  1225. end;
  1226. ChangeDebuggeeWindowTitleTo(Running_State);
  1227. {$endif win32}
  1228. end;
  1229. {$endif NODEBUG}
  1230. {****************************************************************************
  1231. TBreakpoint
  1232. ****************************************************************************}
  1233. function ActiveBreakpoints : boolean;
  1234. var
  1235. IsActive : boolean;
  1236. procedure TestActive(PB : PBreakpoint);
  1237. begin
  1238. If PB^.state=bs_enabled then
  1239. IsActive:=true;
  1240. end;
  1241. begin
  1242. IsActive:=false;
  1243. If assigned(BreakpointsCollection) then
  1244. BreakpointsCollection^.ForEach(@TestActive);
  1245. ActiveBreakpoints:=IsActive;
  1246. end;
  1247. constructor TBreakpoint.Init_function(Const AFunc : String);
  1248. begin
  1249. typ:=bt_function;
  1250. state:=bs_enabled;
  1251. GDBState:=bs_deleted;
  1252. Name:=NewStr(AFunc);
  1253. FileName:=nil;
  1254. Line:=0;
  1255. IgnoreCount:=0;
  1256. Commands:=nil;
  1257. Conditions:=nil;
  1258. OldValue:=nil;
  1259. CurrentValue:=nil;
  1260. end;
  1261. constructor TBreakpoint.Init_Address(Const AAddress : String);
  1262. begin
  1263. typ:=bt_address;
  1264. state:=bs_enabled;
  1265. GDBState:=bs_deleted;
  1266. Name:=NewStr(AAddress);
  1267. FileName:=nil;
  1268. Line:=0;
  1269. IgnoreCount:=0;
  1270. Commands:=nil;
  1271. Conditions:=nil;
  1272. OldValue:=nil;
  1273. CurrentValue:=nil;
  1274. end;
  1275. constructor TBreakpoint.Init_Empty;
  1276. begin
  1277. typ:=bt_function;
  1278. state:=bs_enabled;
  1279. GDBState:=bs_deleted;
  1280. Name:=Nil;
  1281. FileName:=nil;
  1282. Line:=0;
  1283. IgnoreCount:=0;
  1284. Commands:=nil;
  1285. Conditions:=nil;
  1286. OldValue:=nil;
  1287. CurrentValue:=nil;
  1288. end;
  1289. constructor TBreakpoint.Init_type(atyp : BreakpointType;Const AnExpr : String);
  1290. begin
  1291. typ:=atyp;
  1292. state:=bs_enabled;
  1293. GDBState:=bs_deleted;
  1294. Name:=NewStr(AnExpr);
  1295. IgnoreCount:=0;
  1296. Commands:=nil;
  1297. Conditions:=nil;
  1298. OldValue:=nil;
  1299. CurrentValue:=nil;
  1300. end;
  1301. constructor TBreakpoint.Init_file_line(AFile : String; ALine : longint);
  1302. var
  1303. CurDir : String;
  1304. begin
  1305. typ:=bt_file_line;
  1306. state:=bs_enabled;
  1307. GDBState:=bs_deleted;
  1308. AFile:=FEXpand(AFile);
  1309. (*
  1310. { d:test.pas:12 does not work !! }
  1311. { I do not know how to solve this if
  1312. if (Length(AFile)>1) and (AFile[2]=':') then
  1313. AFile:=Copy(AFile,3,255); }
  1314. {$ifdef Unix}
  1315. CurDir:=GetCurDir;
  1316. {$else}
  1317. CurDir:=LowerCaseStr(GetCurDir);
  1318. {$endif Unix}
  1319. if Pos(CurDir,OSFileName(AFile))=1 then
  1320. FileName:=NewStr(Copy(OSFileName(AFile),length(CurDir)+1,255))
  1321. else
  1322. *)
  1323. FileName:=NewStr(OSFileName(AFile));
  1324. Name:=nil;
  1325. Line:=ALine;
  1326. IgnoreCount:=0;
  1327. Commands:=nil;
  1328. Conditions:=nil;
  1329. OldValue:=nil;
  1330. CurrentValue:=nil;
  1331. end;
  1332. constructor TBreakpoint.Load(var S: TStream);
  1333. var
  1334. FName : PString;
  1335. begin
  1336. S.Read(typ,SizeOf(BreakpointType));
  1337. S.Read(state,SizeOf(BreakpointState));
  1338. GDBState:=bs_deleted;
  1339. case typ of
  1340. bt_file_line :
  1341. begin
  1342. { convert to current target }
  1343. FName:=S.ReadStr;
  1344. FileName:=NewStr(OSFileName(GetStr(FName)));
  1345. If Assigned(FName) then
  1346. DisposeStr(FName);
  1347. S.Read(Line,SizeOf(Line));
  1348. Name:=nil;
  1349. end;
  1350. else
  1351. begin
  1352. Name:=S.ReadStr;
  1353. Line:=0;
  1354. FileName:=nil;
  1355. end;
  1356. end;
  1357. S.Read(IgnoreCount,SizeOf(IgnoreCount));
  1358. Commands:=S.StrRead;
  1359. Conditions:=S.ReadStr;
  1360. OldValue:=nil;
  1361. CurrentValue:=nil;
  1362. end;
  1363. procedure TBreakpoint.Store(var S: TStream);
  1364. var
  1365. St : String;
  1366. begin
  1367. S.Write(typ,SizeOf(BreakpointType));
  1368. S.Write(state,SizeOf(BreakpointState));
  1369. case typ of
  1370. bt_file_line :
  1371. begin
  1372. st:=OSFileName(GetStr(FileName));
  1373. S.WriteStr(@St);
  1374. S.Write(Line,SizeOf(Line));
  1375. end;
  1376. else
  1377. begin
  1378. S.WriteStr(Name);
  1379. end;
  1380. end;
  1381. S.Write(IgnoreCount,SizeOf(IgnoreCount));
  1382. S.StrWrite(Commands);
  1383. S.WriteStr(Conditions);
  1384. end;
  1385. procedure TBreakpoint.Insert;
  1386. var
  1387. p,p2 : pchar;
  1388. st : string;
  1389. begin
  1390. {$ifndef NODEBUG}
  1391. If not assigned(Debugger) then Exit;
  1392. Remove;
  1393. Debugger^.last_breakpoint_number:=0;
  1394. if (GDBState=bs_deleted) and (state=bs_enabled) then
  1395. begin
  1396. if (typ=bt_file_line) and assigned(FileName) then
  1397. Debugger^.Command('break '+GDBFileName(NameAndExtOf(GetStr(FileName)))+':'+IntToStr(Line))
  1398. else if (typ=bt_function) and assigned(name) then
  1399. Debugger^.Command('break '+name^)
  1400. else if (typ=bt_address) and assigned(name) then
  1401. Debugger^.Command('break *0x'+name^)
  1402. else if (typ=bt_watch) and assigned(name) then
  1403. Debugger^.Command('watch '+name^)
  1404. else if (typ=bt_awatch) and assigned(name) then
  1405. Debugger^.Command('awatch '+name^)
  1406. else if (typ=bt_rwatch) and assigned(name) then
  1407. Debugger^.Command('rwatch '+name^);
  1408. if Debugger^.last_breakpoint_number<>0 then
  1409. begin
  1410. GDBIndex:=Debugger^.last_breakpoint_number;
  1411. GDBState:=bs_enabled;
  1412. Debugger^.Command('cond '+IntToStr(GDBIndex)+' '+GetStr(Conditions));
  1413. If IgnoreCount>0 then
  1414. Debugger^.Command('ignore '+IntToStr(GDBIndex)+' '+IntToStr(IgnoreCount));
  1415. If Assigned(Commands) then
  1416. begin
  1417. {Commands are not handled yet }
  1418. Debugger^.Command('command '+IntToStr(GDBIndex));
  1419. p:=commands;
  1420. while assigned(p) do
  1421. begin
  1422. p2:=strscan(p,#10);
  1423. if assigned(p2) then
  1424. p2^:=#0;
  1425. st:=strpas(p);
  1426. Debugger^.command(st);
  1427. if assigned(p2) then
  1428. p2^:=#10;
  1429. p:=p2;
  1430. if assigned(p) then
  1431. inc(p);
  1432. end;
  1433. Debugger^.Command('end');
  1434. end;
  1435. end
  1436. else
  1437. { Here there was a problem !! }
  1438. begin
  1439. GDBIndex:=0;
  1440. if not Debugger^.Disableallinvalidbreakpoints then
  1441. begin
  1442. if (typ=bt_file_line) and assigned(FileName) then
  1443. begin
  1444. ClearFormatParams;
  1445. AddFormatParamStr(NameAndExtOf(FileName^));
  1446. AddFormatParamInt(Line);
  1447. if ChoiceBox(msg_couldnotsetbreakpointat,@FormatParams,[btn_ok,button_DisableAllBreakpoints],false)=cmUserBtn2 then
  1448. Debugger^.Disableallinvalidbreakpoints:=true;
  1449. end
  1450. else
  1451. begin
  1452. ClearFormatParams;
  1453. AddFormatParamStr(BreakpointTypeStr[typ]);
  1454. AddFormatParamStr(GetStr(Name));
  1455. if ChoiceBox(msg_couldnotsetbreakpointtype,@FormatParams,[btn_ok,button_DisableAllBreakpoints],false)=cmUserBtn2 then
  1456. Debugger^.Disableallinvalidbreakpoints:=true;
  1457. end;
  1458. end;
  1459. state:=bs_disabled;
  1460. UpdateSource;
  1461. end;
  1462. end
  1463. else if (GDBState=bs_disabled) and (state=bs_enabled) then
  1464. Enable
  1465. else if (GDBState=bs_enabled) and (state=bs_disabled) then
  1466. Disable;
  1467. {$endif NODEBUG}
  1468. end;
  1469. procedure TBreakpoint.Remove;
  1470. begin
  1471. {$ifndef NODEBUG}
  1472. If not assigned(Debugger) then Exit;
  1473. if GDBIndex>0 then
  1474. Debugger^.Command('delete '+IntToStr(GDBIndex));
  1475. GDBIndex:=0;
  1476. GDBState:=bs_deleted;
  1477. {$endif NODEBUG}
  1478. end;
  1479. procedure TBreakpoint.Enable;
  1480. begin
  1481. {$ifndef NODEBUG}
  1482. If not assigned(Debugger) then Exit;
  1483. if GDBIndex>0 then
  1484. Debugger^.Command('enable '+IntToStr(GDBIndex))
  1485. else
  1486. Insert;
  1487. GDBState:=bs_disabled;
  1488. {$endif NODEBUG}
  1489. end;
  1490. procedure TBreakpoint.Disable;
  1491. begin
  1492. {$ifndef NODEBUG}
  1493. If not assigned(Debugger) then Exit;
  1494. if GDBIndex>0 then
  1495. Debugger^.Command('disable '+IntToStr(GDBIndex));
  1496. GDBState:=bs_disabled;
  1497. {$endif NODEBUG}
  1498. end;
  1499. procedure TBreakpoint.ResetValues;
  1500. begin
  1501. if assigned(OldValue) then
  1502. DisposeStr(OldValue);
  1503. OldValue:=nil;
  1504. if assigned(CurrentValue) then
  1505. DisposeStr(CurrentValue);
  1506. CurrentValue:=nil;
  1507. end;
  1508. procedure TBreakpoint.UpdateSource;
  1509. var W: PSourceWindow;
  1510. b : boolean;
  1511. begin
  1512. if typ=bt_file_line then
  1513. begin
  1514. W:=SearchOnDesktop(OSFileName(GetStr(FileName)),false);
  1515. If assigned(W) then
  1516. begin
  1517. if state=bs_enabled then
  1518. b:=true
  1519. else
  1520. b:=false;
  1521. W^.Editor^.SetLineFlagState(Line-1,lfBreakpoint,b);
  1522. end;
  1523. end;
  1524. end;
  1525. destructor TBreakpoint.Done;
  1526. begin
  1527. Remove;
  1528. ResetValues;
  1529. if assigned(Name) then
  1530. DisposeStr(Name);
  1531. if assigned(FileName) then
  1532. DisposeStr(FileName);
  1533. if assigned(Conditions) then
  1534. DisposeStr(Conditions);
  1535. if assigned(Commands) then
  1536. StrDispose(Commands);
  1537. inherited Done;
  1538. end;
  1539. {****************************************************************************
  1540. TBreakpointCollection
  1541. ****************************************************************************}
  1542. function TBreakpointCollection.At(Index: Integer): PBreakpoint;
  1543. begin
  1544. At:=inherited At(Index);
  1545. end;
  1546. procedure TBreakpointCollection.Update;
  1547. begin
  1548. {$ifndef NODEBUG}
  1549. if assigned(Debugger) then
  1550. begin
  1551. Debugger^.RemoveBreakpoints;
  1552. Debugger^.InsertBreakpoints;
  1553. end;
  1554. {$endif NODEBUG}
  1555. if assigned(BreakpointsWindow) then
  1556. BreakpointsWindow^.Update;
  1557. end;
  1558. function TBreakpointCollection.GetGDB(index : longint) : PBreakpoint;
  1559. function IsNum(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  1560. begin
  1561. IsNum:=P^.GDBIndex=index;
  1562. end;
  1563. begin
  1564. if index=0 then
  1565. GetGDB:=nil
  1566. else
  1567. GetGDB:=FirstThat(@IsNum);
  1568. end;
  1569. procedure TBreakpointCollection.ShowBreakpoints(W : PFPWindow);
  1570. procedure SetInSource(P : PBreakpoint);{$ifndef FPC}far;{$endif}
  1571. begin
  1572. If assigned(P^.FileName) and
  1573. (OSFileName(P^.FileName^)=OSFileName(FExpand(PSourceWindow(W)^.Editor^.FileName))) then
  1574. PSourceWindow(W)^.Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,P^.state=bs_enabled);
  1575. end;
  1576. procedure SetInDisassembly(P : PBreakpoint);{$ifndef FPC}far;{$endif}
  1577. var
  1578. PDL : PDisasLine;
  1579. S : string;
  1580. ps,qs,i : longint;
  1581. begin
  1582. for i:=0 to PDisassemblyWindow(W)^.Editor^.GetLineCount-1 do
  1583. begin
  1584. PDL:=PDisasLine(PDisassemblyWindow(W)^.Editor^.GetLine(i));
  1585. if PDL^.Address=0 then
  1586. begin
  1587. if (P^.typ=bt_file_line) then
  1588. begin
  1589. S:=PDisassemblyWindow(W)^.Editor^.GetDisplayText(i);
  1590. ps:=pos(':',S);
  1591. qs:=pos(' ',copy(S,ps+1,High(S)));
  1592. if (GDBFileName(P^.FileName^)=GDBFileName(FExpand(Copy(S,1,ps-1)))) and
  1593. (StrToInt(copy(S,ps+1,qs-1))=P^.line) then
  1594. PDisassemblyWindow(W)^.Editor^.SetLineFlagState(i,lfBreakpoint,P^.state=bs_enabled);
  1595. end;
  1596. end
  1597. else
  1598. begin
  1599. If (P^.typ=bt_address) and (PDL^.Address=HexToCard(P^.Name^)) then
  1600. PDisassemblyWindow(W)^.Editor^.SetLineFlagState(i,lfBreakpoint,P^.state=bs_enabled);
  1601. end;
  1602. end;
  1603. end;
  1604. begin
  1605. if W=PFPWindow(DisassemblyWindow) then
  1606. ForEach(@SetInDisassembly)
  1607. else
  1608. ForEach(@SetInSource);
  1609. end;
  1610. procedure TBreakpointCollection.AdaptBreakpoints(Editor : PSourceEditor; Pos, Change : longint);
  1611. procedure AdaptInSource(P : PBreakpoint);{$ifndef FPC}far;{$endif}
  1612. begin
  1613. If assigned(P^.FileName) and
  1614. (P^.FileName^=OSFileName(FExpand(Editor^.FileName))) then
  1615. begin
  1616. if P^.state=bs_enabled then
  1617. Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,false);
  1618. if P^.Line-1>=Pos then
  1619. begin
  1620. if (Change>0) or (P^.Line-1>=Pos-Change) then
  1621. P^.line:=P^.Line+Change
  1622. else
  1623. begin
  1624. { removing inside a ForEach call leads to problems }
  1625. { so we do that after PM }
  1626. P^.state:=bs_delete_after;
  1627. end;
  1628. end;
  1629. if P^.state=bs_enabled then
  1630. Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,true);
  1631. end;
  1632. end;
  1633. var
  1634. I : longint;
  1635. begin
  1636. ForEach(@AdaptInSource);
  1637. I:=Count-1;
  1638. While (I>=0) do
  1639. begin
  1640. if At(I)^.state=bs_delete_after then
  1641. AtFree(I);
  1642. Dec(I);
  1643. end;
  1644. end;
  1645. function TBreakpointCollection.FindBreakpointAt(Editor : PSourceEditor; Line : longint) : PBreakpoint;
  1646. function IsAtLine(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  1647. begin
  1648. If assigned(P^.FileName) and
  1649. (P^.FileName^=OSFileName(FExpand(Editor^.FileName))) and
  1650. (Line=P^.Line) then
  1651. IsAtLine:=true
  1652. else
  1653. IsAtLine:=false;
  1654. end;
  1655. begin
  1656. FindBreakpointAt:=FirstThat(@IsAtLine);
  1657. end;
  1658. procedure TBreakpointCollection.ShowAllBreakpoints;
  1659. procedure SetInSource(P : PBreakpoint);{$ifndef FPC}far;{$endif}
  1660. var
  1661. W : PSourceWindow;
  1662. begin
  1663. If assigned(P^.FileName) then
  1664. begin
  1665. W:=SearchOnDesktop(P^.FileName^,false);
  1666. if assigned(W) then
  1667. W^.Editor^.SetLineFlagState(P^.Line-1,lfBreakpoint,P^.state=bs_enabled);
  1668. end;
  1669. end;
  1670. begin
  1671. ForEach(@SetInSource);
  1672. end;
  1673. function TBreakpointCollection.GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
  1674. function IsThis(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  1675. begin
  1676. IsThis:=(P^.typ=typ) and (GetStr(P^.Name)=S);
  1677. end;
  1678. begin
  1679. GetType:=FirstThat(@IsThis);
  1680. end;
  1681. function TBreakpointCollection.ToggleFileLine(FileName: String;LineNr : Longint) : boolean;
  1682. function IsThere(P : PBreakpoint) : boolean;{$ifndef FPC}far;{$endif}
  1683. begin
  1684. IsThere:=(P^.typ=bt_file_line) and assigned(P^.FileName) and
  1685. (OSFileName(P^.FileName^)=FileName) and (P^.Line=LineNr);
  1686. end;
  1687. var
  1688. PB : PBreakpoint;
  1689. begin
  1690. ToggleFileLine:=false;
  1691. FileName:=OSFileName(FExpand(FileName));
  1692. PB:=FirstThat(@IsThere);
  1693. If Assigned(PB) then
  1694. begin
  1695. { delete it form source window }
  1696. PB^.state:=bs_disabled;
  1697. PB^.UpdateSource;
  1698. { remove from collection }
  1699. BreakpointsCollection^.free(PB);
  1700. end
  1701. else
  1702. begin
  1703. PB:= New(PBreakpoint,Init_file_line(FileName,LineNr));
  1704. if assigned(PB) then
  1705. Begin
  1706. Insert(PB);
  1707. PB^.UpdateSource;
  1708. ToggleFileLine:=true;
  1709. End;
  1710. end;
  1711. Update;
  1712. end;
  1713. {****************************************************************************
  1714. TBreakpointItem
  1715. ****************************************************************************}
  1716. constructor TBreakpointItem.Init(ABreakpoint : PBreakpoint);
  1717. begin
  1718. inherited Init;
  1719. Breakpoint:=ABreakpoint;
  1720. end;
  1721. function TBreakpointItem.GetText(MaxLen: Sw_integer): string;
  1722. var S: string;
  1723. begin
  1724. with Breakpoint^ do
  1725. begin
  1726. S:=BreakpointTypeStr[typ];
  1727. While Length(S)<10 do
  1728. S:=S+' ';
  1729. S:=S+'|';
  1730. S:=S+BreakpointStateStr[state]+' ';
  1731. While Length(S)<20 do
  1732. S:=S+' ';
  1733. S:=S+'|';
  1734. if (typ=bt_file_line) then
  1735. S:=S+NameAndExtOf(GetStr(FileName))+':'+IntToStr(Line)
  1736. else
  1737. S:=S+GetStr(name);
  1738. While Length(S)<40 do
  1739. S:=S+' ';
  1740. S:=S+'|';
  1741. if IgnoreCount>0 then
  1742. S:=S+IntToStr(IgnoreCount);
  1743. While Length(S)<49 do
  1744. S:=S+' ';
  1745. S:=S+'|';
  1746. if assigned(Conditions) then
  1747. S:=S+' '+GetStr(Conditions);
  1748. if length(S)>MaxLen then S:=copy(S,1,MaxLen-2)+'..';
  1749. GetText:=S;
  1750. end;
  1751. end;
  1752. procedure TBreakpointItem.Selected;
  1753. begin
  1754. end;
  1755. function TBreakpointItem.GetModuleName: string;
  1756. begin
  1757. if breakpoint^.typ=bt_file_line then
  1758. GetModuleName:=GetStr(breakpoint^.FileName)
  1759. else
  1760. GetModuleName:='';
  1761. end;
  1762. {****************************************************************************
  1763. TBreakpointsListBox
  1764. ****************************************************************************}
  1765. constructor TBreakpointsListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  1766. begin
  1767. inherited Init(Bounds,1,AHScrollBar, AVScrollBar);
  1768. GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  1769. NoSelection:=true;
  1770. end;
  1771. function TBreakpointsListBox.GetLocalMenu: PMenu;
  1772. var M: PMenu;
  1773. begin
  1774. if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
  1775. M:=NewMenu(
  1776. NewItem(menu_bplocal_gotosource,'',kbNoKey,cmMsgGotoSource,hcMsgGotoSource,
  1777. NewItem(menu_bplocal_editbreakpoint,'',kbNoKey,cmEditBreakpoint,hcEditBreakpoint,
  1778. NewItem(menu_bplocal_newbreakpoint,'',kbNoKey,cmNewBreakpoint,hcNewBreakpoint,
  1779. NewItem(menu_bplocal_deletebreakpoint,'',kbNoKey,cmDeleteBreakpoint,hcDeleteBreakpoint,
  1780. NewItem(menu_bplocal_togglestate,'',kbNoKey,cmToggleBreakpoint,hcToggleBreakpoint,
  1781. nil))))));
  1782. GetLocalMenu:=M;
  1783. end;
  1784. procedure TBreakpointsListBox.HandleEvent(var Event: TEvent);
  1785. var DontClear: boolean;
  1786. begin
  1787. case Event.What of
  1788. evKeyDown :
  1789. begin
  1790. DontClear:=false;
  1791. case Event.KeyCode of
  1792. kbEnd :
  1793. FocusItem(List^.Count-1);
  1794. kbHome :
  1795. FocusItem(0);
  1796. kbEnter :
  1797. Message(@Self,evCommand,cmMsgGotoSource,nil);
  1798. kbIns :
  1799. Message(@Self,evCommand,cmNewBreakpoint,nil);
  1800. kbDel :
  1801. Message(@Self,evCommand,cmDeleteBreakpoint,nil);
  1802. else
  1803. DontClear:=true;
  1804. end;
  1805. if not DontClear then
  1806. ClearEvent(Event);
  1807. end;
  1808. evBroadcast :
  1809. case Event.Command of
  1810. cmListItemSelected :
  1811. if Event.InfoPtr=@Self then
  1812. Message(@Self,evCommand,cmEditBreakpoint,nil);
  1813. end;
  1814. evCommand :
  1815. begin
  1816. DontClear:=false;
  1817. case Event.Command of
  1818. cmMsgTrackSource :
  1819. if Range>0 then
  1820. TrackSource;
  1821. cmEditBreakpoint :
  1822. EditCurrent;
  1823. cmToggleBreakpoint :
  1824. ToggleCurrent;
  1825. cmDeleteBreakpoint :
  1826. DeleteCurrent;
  1827. cmNewBreakpoint :
  1828. EditNew;
  1829. cmMsgClear :
  1830. Clear;
  1831. else
  1832. DontClear:=true;
  1833. end;
  1834. if not DontClear then
  1835. ClearEvent(Event);
  1836. end;
  1837. end;
  1838. inherited HandleEvent(Event);
  1839. end;
  1840. procedure TBreakpointsListBox.AddBreakpoint(P: PBreakpointItem);
  1841. var W : integer;
  1842. begin
  1843. if List=nil then New(List, Init(20,20));
  1844. W:=length(P^.GetText(255));
  1845. if W>MaxWidth then
  1846. begin
  1847. MaxWidth:=W;
  1848. if HScrollBar<>nil then
  1849. HScrollBar^.SetRange(0,MaxWidth);
  1850. end;
  1851. List^.Insert(P);
  1852. SetRange(List^.Count);
  1853. if Focused=List^.Count-1-1 then
  1854. FocusItem(List^.Count-1);
  1855. P^.Breakpoint^.UpdateSource;
  1856. DrawView;
  1857. end;
  1858. function TBreakpointsListBox.GetText(Item,MaxLen: Sw_Integer): String;
  1859. var P: PBreakpointItem;
  1860. S: string;
  1861. begin
  1862. P:=List^.At(Item);
  1863. S:=P^.GetText(MaxLen);
  1864. GetText:=copy(S,1,MaxLen);
  1865. end;
  1866. procedure TBreakpointsListBox.Clear;
  1867. begin
  1868. if assigned(List) then
  1869. Dispose(List, Done);
  1870. List:=nil;
  1871. MaxWidth:=0;
  1872. SetRange(0); DrawView;
  1873. Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  1874. end;
  1875. procedure TBreakpointsListBox.TrackSource;
  1876. var W: PSourceWindow;
  1877. P: PBreakpointItem;
  1878. R: TRect;
  1879. begin
  1880. (*Message(Application,evBroadcast,cmClearLineHighlights,@Self);
  1881. if Range=0 then Exit;*)
  1882. P:=List^.At(Focused);
  1883. if P^.GetModuleName='' then Exit;
  1884. Desktop^.Lock;
  1885. GetNextEditorBounds(R);
  1886. R.B.Y:=Owner^.Origin.Y;
  1887. W:=EditorWindowFile(P^.GetModuleName);
  1888. if assigned(W) then
  1889. begin
  1890. W^.GetExtent(R);
  1891. R.B.Y:=Owner^.Origin.Y;
  1892. W^.ChangeBounds(R);
  1893. W^.Editor^.SetCurPtr(1,P^.Breakpoint^.Line);
  1894. end
  1895. else
  1896. W:=TryToOpenFile(@R,P^.GetModuleName,1,P^.Breakpoint^.Line,true);
  1897. if W<>nil then
  1898. begin
  1899. W^.Select;
  1900. W^.Editor^.TrackCursor(true);
  1901. W^.Editor^.SetLineFlagExclusive(lfHighlightRow,P^.Breakpoint^.Line);
  1902. end;
  1903. if Assigned(Owner) then
  1904. Owner^.Select;
  1905. Desktop^.UnLock;
  1906. end;
  1907. procedure TBreakpointsListBox.ToggleCurrent;
  1908. var
  1909. P: PBreakpointItem;
  1910. begin
  1911. if Range=0 then Exit;
  1912. P:=List^.At(Focused);
  1913. if P=nil then Exit;
  1914. if P^.Breakpoint^.state=bs_enabled then
  1915. P^.Breakpoint^.state:=bs_disabled
  1916. else if P^.Breakpoint^.state=bs_disabled then
  1917. P^.Breakpoint^.state:=bs_enabled;
  1918. P^.Breakpoint^.UpdateSource;
  1919. BreakpointsCollection^.Update;
  1920. end;
  1921. procedure TBreakpointsListBox.EditCurrent;
  1922. var
  1923. P: PBreakpointItem;
  1924. begin
  1925. if Range=0 then Exit;
  1926. P:=List^.At(Focused);
  1927. if P=nil then Exit;
  1928. Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P^.Breakpoint)),nil);
  1929. P^.Breakpoint^.UpdateSource;
  1930. BreakpointsCollection^.Update;
  1931. end;
  1932. procedure TBreakpointsListBox.DeleteCurrent;
  1933. var
  1934. P: PBreakpointItem;
  1935. begin
  1936. if Range=0 then Exit;
  1937. P:=List^.At(Focused);
  1938. if P=nil then Exit;
  1939. { delete it form source window }
  1940. P^.Breakpoint^.state:=bs_disabled;
  1941. P^.Breakpoint^.UpdateSource;
  1942. BreakpointsCollection^.free(P^.Breakpoint);
  1943. List^.free(P);
  1944. BreakpointsCollection^.Update;
  1945. end;
  1946. procedure TBreakpointsListBox.EditNew;
  1947. var
  1948. P: PBreakpoint;
  1949. begin
  1950. P:=New(PBreakpoint,Init_Empty);
  1951. if Application^.ExecuteDialog(New(PBreakpointItemDialog,Init(P)),nil)<>cmCancel then
  1952. begin
  1953. P^.UpdateSource;
  1954. BreakpointsCollection^.Insert(P);
  1955. BreakpointsCollection^.Update;
  1956. end
  1957. else
  1958. dispose(P,Done);
  1959. end;
  1960. procedure TBreakpointsListBox.Draw;
  1961. var
  1962. I, J, Item: Sw_Integer;
  1963. NormalColor, SelectedColor, FocusedColor, Color: Word;
  1964. ColWidth, CurCol, Indent: Integer;
  1965. B: TDrawBuffer;
  1966. Text: String;
  1967. SCOff: Byte;
  1968. TC: byte;
  1969. procedure MT(var C: word); begin if TC<>0 then C:=(C and $ff0f) or (TC and $f0); end;
  1970. begin
  1971. if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
  1972. if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
  1973. begin
  1974. NormalColor := GetColor(1);
  1975. FocusedColor := GetColor(3);
  1976. SelectedColor := GetColor(4);
  1977. end else
  1978. begin
  1979. NormalColor := GetColor(2);
  1980. SelectedColor := GetColor(4);
  1981. end;
  1982. if Transparent then
  1983. begin MT(NormalColor); MT(SelectedColor); end;
  1984. if NoSelection then
  1985. SelectedColor:=NormalColor;
  1986. if HScrollBar <> nil then Indent := HScrollBar^.Value
  1987. else Indent := 0;
  1988. ColWidth := Size.X div NumCols + 1;
  1989. for I := 0 to Size.Y - 1 do
  1990. begin
  1991. for J := 0 to NumCols-1 do
  1992. begin
  1993. Item := J*Size.Y + I + TopItem;
  1994. CurCol := J*ColWidth;
  1995. if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
  1996. (Focused = Item) and (Range > 0) then
  1997. begin
  1998. Color := FocusedColor;
  1999. SetCursor(CurCol+1,I);
  2000. SCOff := 0;
  2001. end
  2002. else if (Item < Range) and IsSelected(Item) then
  2003. begin
  2004. Color := SelectedColor;
  2005. SCOff := 2;
  2006. end
  2007. else
  2008. begin
  2009. Color := NormalColor;
  2010. SCOff := 4;
  2011. end;
  2012. MoveChar(B[CurCol], ' ', Color, ColWidth);
  2013. if Item < Range then
  2014. begin
  2015. Text := GetText(Item, ColWidth + Indent);
  2016. Text := Copy(Text,Indent,ColWidth);
  2017. MoveStr(B[CurCol+1], Text, Color);
  2018. if ShowMarkers then
  2019. begin
  2020. WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
  2021. WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
  2022. end;
  2023. end;
  2024. MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
  2025. end;
  2026. WriteLine(0, I, Size.X, 1, B);
  2027. end;
  2028. end;
  2029. constructor TBreakpointsListBox.Load(var S: TStream);
  2030. begin
  2031. inherited Load(S);
  2032. end;
  2033. procedure TBreakpointsListBox.Store(var S: TStream);
  2034. var OL: PCollection;
  2035. OldR : integer;
  2036. begin
  2037. OL:=List;
  2038. OldR:=Range;
  2039. Range:=0;
  2040. New(List, Init(1,1));
  2041. inherited Store(S);
  2042. Dispose(List, Done);
  2043. Range:=OldR;
  2044. List:=OL;
  2045. { ^^^ nasty trick - has anyone a better idea how to avoid storing the
  2046. collection? Pasting here a modified version of TListBox.Store+
  2047. TAdvancedListBox.Store isn't a better solution, since by eventually
  2048. changing the obj-hierarchy you'll always have to modify this, too - BG }
  2049. end;
  2050. destructor TBreakpointsListBox.Done;
  2051. begin
  2052. inherited Done;
  2053. if List<>nil then Dispose(List, Done);
  2054. end;
  2055. {****************************************************************************
  2056. TBreakpointsWindow
  2057. ****************************************************************************}
  2058. constructor TBreakpointsWindow.Init;
  2059. var R,R2: TRect;
  2060. HSB,VSB: PScrollBar;
  2061. ST: PStaticText;
  2062. S: String;
  2063. X,X1 : Sw_integer;
  2064. Btn: PButton;
  2065. const
  2066. NumButtons = 5;
  2067. begin
  2068. Desktop^.GetExtent(R); R.A.Y:=R.B.Y-18;
  2069. inherited Init(R, dialog_breakpointlist, wnNoNumber);
  2070. HelpCtx:=hcBreakpointListWindow;
  2071. GetExtent(R); R.Grow(-1,-1); R.B.Y:=R.A.Y+1;
  2072. S:=label_breakpointpropheader;
  2073. New(ST, Init(R,S));
  2074. ST^.GrowMode:=gfGrowHiX;
  2075. Insert(ST);
  2076. GetExtent(R); R.Grow(-1,-1); Inc(R.A.Y,1); R.B.Y:=R.A.Y+1;
  2077. New(ST, Init(R, CharStr('Ä', MaxViewWidth)));
  2078. ST^.GrowMode:=gfGrowHiX;
  2079. Insert(ST);
  2080. GetExtent(R); R.Grow(-1,-1); Inc(R.A.Y,2);Dec(R.B.Y,5);
  2081. R2.Copy(R); Inc(R2.B.Y); R2.A.Y:=R2.B.Y-1;
  2082. New(HSB, Init(R2)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX; Insert(HSB);
  2083. HSB^.SetStep(R.B.X-R.A.X-2,1);
  2084. R2.Copy(R); Inc(R2.B.X); R2.A.X:=R2.B.X-1;
  2085. New(VSB, Init(R2)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY; Insert(VSB);
  2086. VSB^.SetStep(R.B.Y-R.A.Y-2,1);
  2087. New(BreakLB, Init(R,HSB,VSB));
  2088. BreakLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  2089. BreakLB^.Transparent:=true;
  2090. Insert(BreakLB);
  2091. GetExtent(R);R.Grow(-1,-1);
  2092. Dec(R.B.Y);
  2093. R.A.Y:=R.B.Y-2;
  2094. X:=(R.B.X-R.A.X) div NumButtons;
  2095. X1:=R.A.X+(X div 2);
  2096. R.A.X:=X1-3;R.B.X:=X1+7;
  2097. New(Btn, Init(R, button_Close, cmClose, bfDefault));
  2098. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2099. Insert(Btn);
  2100. X1:=X1+X;
  2101. R.A.X:=X1-3;R.B.X:=X1+7;
  2102. New(Btn, Init(R, button_New, cmNewBreakpoint, bfNormal));
  2103. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2104. Insert(Btn);
  2105. X1:=X1+X;
  2106. R.A.X:=X1-3;R.B.X:=X1+7;
  2107. New(Btn, Init(R, button_Edit, cmEditBreakpoint, bfNormal));
  2108. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2109. Insert(Btn);
  2110. X1:=X1+X;
  2111. R.A.X:=X1-3;R.B.X:=X1+7;
  2112. New(Btn, Init(R, button_ToggleButton, cmToggleBreakInList, bfNormal));
  2113. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2114. Insert(Btn);
  2115. X1:=X1+X;
  2116. R.A.X:=X1-3;R.B.X:=X1+7;
  2117. New(Btn, Init(R, button_Delete, cmDeleteBreakpoint, bfNormal));
  2118. Btn^.GrowMode:=gfGrowLoY+gfGrowHiY;
  2119. Insert(Btn);
  2120. BreakLB^.Select;
  2121. Update;
  2122. BreakpointsWindow:=@self;
  2123. end;
  2124. constructor TBreakpointsWindow.Load(var S: TStream);
  2125. begin
  2126. inherited Load(S);
  2127. GetSubViewPtr(S,BreakLB);
  2128. end;
  2129. procedure TBreakpointsWindow.Store(var S: TStream);
  2130. begin
  2131. inherited Store(S);
  2132. PutSubViewPtr(S,BreakLB);
  2133. end;
  2134. procedure TBreakpointsWindow.AddBreakpoint(ABreakpoint : PBreakpoint);
  2135. begin
  2136. BreakLB^.AddBreakpoint(New(PBreakpointItem, Init(ABreakpoint)));
  2137. end;
  2138. procedure TBreakpointsWindow.ClearBreakpoints;
  2139. begin
  2140. BreakLB^.Clear;
  2141. ReDraw;
  2142. end;
  2143. procedure TBreakpointsWindow.ReloadBreakpoints;
  2144. procedure InsertInBreakLB(P : PBreakpoint);
  2145. begin
  2146. BreakLB^.AddBreakpoint(New(PBreakpointItem, Init(P)));
  2147. end;
  2148. begin
  2149. If not assigned(BreakpointsCollection) then
  2150. exit;
  2151. BreakpointsCollection^.ForEach(@InsertInBreakLB);
  2152. ReDraw;
  2153. end;
  2154. procedure TBreakpointsWindow.SizeLimits(var Min, Max: TPoint);
  2155. begin
  2156. inherited SizeLimits(Min,Max);
  2157. Min.X:=40; Min.Y:=18;
  2158. end;
  2159. procedure TBreakpointsWindow.Close;
  2160. begin
  2161. Hide;
  2162. end;
  2163. procedure TBreakpointsWindow.HandleEvent(var Event: TEvent);
  2164. var DontClear : boolean;
  2165. begin
  2166. case Event.What of
  2167. evKeyDown :
  2168. begin
  2169. if (Event.KeyCode=kbEnter) or (Event.KeyCode=kbEsc) then
  2170. begin
  2171. ClearEvent(Event);
  2172. Hide;
  2173. end;
  2174. end;
  2175. evCommand :
  2176. begin
  2177. DontClear:=False;
  2178. case Event.Command of
  2179. cmNewBreakpoint :
  2180. BreakLB^.EditNew;
  2181. cmEditBreakpoint :
  2182. BreakLB^.EditCurrent;
  2183. cmDeleteBreakpoint :
  2184. BreakLB^.DeleteCurrent;
  2185. cmToggleBreakInList :
  2186. BreakLB^.ToggleCurrent;
  2187. cmClose :
  2188. Hide;
  2189. else
  2190. DontClear:=true;
  2191. end;
  2192. if not DontClear then
  2193. ClearEvent(Event);
  2194. end;
  2195. evBroadcast :
  2196. case Event.Command of
  2197. cmUpdate :
  2198. Update;
  2199. end;
  2200. end;
  2201. inherited HandleEvent(Event);
  2202. end;
  2203. procedure TBreakpointsWindow.Update;
  2204. var
  2205. StoreFocus : longint;
  2206. begin
  2207. StoreFocus:=BreakLB^.Focused;
  2208. ClearBreakpoints;
  2209. ReloadBreakpoints;
  2210. If StoreFocus<BreakLB^.Range then
  2211. BreakLB^.FocusItem(StoreFocus);
  2212. end;
  2213. destructor TBreakpointsWindow.Done;
  2214. begin
  2215. inherited Done;
  2216. BreakpointsWindow:=nil;
  2217. end;
  2218. {****************************************************************************
  2219. TBreakpointItemDialog
  2220. ****************************************************************************}
  2221. constructor TBreakpointItemDialog.Init(ABreakpoint: PBreakpoint);
  2222. var R,R2,R3: TRect;
  2223. Items: PSItem;
  2224. I : BreakpointType;
  2225. KeyCount: sw_integer;
  2226. begin
  2227. KeyCount:=longint(high(BreakpointType));
  2228. R.Assign(0,0,60,Max(9+KeyCount,18));
  2229. inherited Init(R,dialog_modifynewbreakpoint);
  2230. Breakpoint:=ABreakpoint;
  2231. GetExtent(R); R.Grow(-3,-2); R3.Copy(R);
  2232. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.B.X-3;
  2233. New(NameIL, Init(R, 255)); Insert(NameIL);
  2234. R2.Copy(R); R2.A.X:=R2.B.X; R2.B.X:=R2.A.X+3;
  2235. Insert(New(PHistory, Init(R2, NameIL, hidBreakPointDialogName)));
  2236. R.Copy(R3); Inc(R.A.Y); R.B.Y:=R.A.Y+1;
  2237. R2.Copy(R); R2.Move(-1,-1);
  2238. Insert(New(PLabel, Init(R2, label_breakpoint_name, NameIL)));
  2239. R.Move(0,3);
  2240. R.B.X:=R.B.X-3;
  2241. New(ConditionsIL, Init(R, 255)); Insert(ConditionsIL);
  2242. R2.Copy(R); R2.A.X:=R2.B.X; R2.B.X:=R2.A.X+3;
  2243. Insert(New(PHistory, Init(R2, ConditionsIL, hidBreakPointDialogCond)));
  2244. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_breakpoint_conditions, ConditionsIL)));
  2245. R.Move(0,3); R.B.X:=R.A.X+36;
  2246. New(LineIL, Init(R, 128)); Insert(LineIL);
  2247. LineIL^.SetValidator(New(PRangeValidator, Init(0,MaxInt)));
  2248. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_breakpoint_line, LineIL)));
  2249. R.Move(0,3);
  2250. New(IgnoreIL, Init(R, 128)); Insert(IgnoreIL);
  2251. IgnoreIL^.SetValidator(New(PRangeValidator, Init(0,MaxInt)));
  2252. R2.Copy(R); R2.Move(-1,-1); Insert(New(PLabel, Init(R2, label_breakpoint_ignorecount, IgnoreIL)));
  2253. R.Copy(R3); Inc(R.A.X,38); Inc(R.A.Y,7); R.B.Y:=R.A.Y+KeyCount;
  2254. Items:=nil;
  2255. { don't use invalid type }
  2256. for I:=pred(high(BreakpointType)) downto low(BreakpointType) do
  2257. Items:=NewSItem(BreakpointTypeStr[I], Items);
  2258. New(TypeRB, Init(R, Items));
  2259. R2.Copy(R); R2.Move(-1,-1); R2.B.Y:=R2.A.Y+1;
  2260. Insert(New(PLabel, Init(R2, label_breakpoint_type, TypeRB)));
  2261. Insert(TypeRB);
  2262. InsertButtons(@Self);
  2263. NameIL^.Select;
  2264. end;
  2265. function TBreakpointItemDialog.Execute: Word;
  2266. var R: sw_word;
  2267. S1: string;
  2268. err: word;
  2269. L: longint;
  2270. begin
  2271. R:=sw_word(Breakpoint^.typ);
  2272. TypeRB^.SetData(R);
  2273. If Breakpoint^.typ=bt_file_line then
  2274. S1:=GetStr(Breakpoint^.FileName)
  2275. else
  2276. S1:=GetStr(Breakpoint^.name);
  2277. NameIL^.SetData(S1);
  2278. If Breakpoint^.typ=bt_file_line then
  2279. S1:=IntToStr(Breakpoint^.Line)
  2280. else
  2281. S1:='0';
  2282. LineIL^.SetData(S1);
  2283. S1:=IntToStr(Breakpoint^.IgnoreCount);
  2284. IgnoreIL^.SetData(S1);
  2285. S1:=GetStr(Breakpoint^.Conditions);
  2286. ConditionsIL^.SetData(S1);
  2287. if assigned(FirstEditorWindow) then
  2288. FindReplaceEditor:=FirstEditorWindow^.Editor;
  2289. R:=inherited Execute;
  2290. FindReplaceEditor:=nil;
  2291. if R=cmOK then
  2292. begin
  2293. TypeRB^.GetData(R);
  2294. L:=R;
  2295. Breakpoint^.typ:=BreakpointType(L);
  2296. NameIL^.GetData(S1);
  2297. If Breakpoint^.typ=bt_file_line then
  2298. begin
  2299. If assigned(Breakpoint^.FileName) then
  2300. DisposeStr(Breakpoint^.FileName);
  2301. Breakpoint^.FileName:=NewStr(S1);
  2302. end
  2303. else
  2304. begin
  2305. If assigned(Breakpoint^.Name) then
  2306. DisposeStr(Breakpoint^.Name);
  2307. Breakpoint^.name:=NewStr(S1);
  2308. end;
  2309. If Breakpoint^.typ=bt_file_line then
  2310. begin
  2311. LineIL^.GetData(S1);
  2312. Val(S1,L,err);
  2313. Breakpoint^.Line:=L;
  2314. end;
  2315. IgnoreIL^.GetData(S1);
  2316. Val(S1,L,err);
  2317. Breakpoint^.IgnoreCount:=L;
  2318. ConditionsIL^.GetData(S1);
  2319. If assigned(Breakpoint^.Conditions) then
  2320. DisposeStr(Breakpoint^.Conditions);
  2321. Breakpoint^.Conditions:=NewStr(S1);
  2322. end;
  2323. Execute:=R;
  2324. end;
  2325. {****************************************************************************
  2326. TWatch
  2327. ****************************************************************************}
  2328. constructor TWatch.Init(s : string);
  2329. begin
  2330. expr:=NewStr(s);
  2331. last_value:=nil;
  2332. current_value:=nil;
  2333. Get_new_value;
  2334. GDBRunCount:=-1;
  2335. end;
  2336. constructor TWatch.Load(var S: TStream);
  2337. begin
  2338. expr:=S.ReadStr;
  2339. last_value:=nil;
  2340. current_value:=nil;
  2341. Get_new_value;
  2342. GDBRunCount:=-1;
  2343. end;
  2344. procedure TWatch.Store(var S: TStream);
  2345. begin
  2346. S.WriteStr(expr);
  2347. end;
  2348. procedure TWatch.rename(s : string);
  2349. begin
  2350. if assigned(expr) then
  2351. begin
  2352. if GetStr(expr)=S then
  2353. exit;
  2354. DisposeStr(expr);
  2355. end;
  2356. expr:=NewStr(s);
  2357. if assigned(last_value) then
  2358. StrDispose(last_value);
  2359. last_value:=nil;
  2360. if assigned(current_value) then
  2361. StrDispose(current_value);
  2362. current_value:=nil;
  2363. GDBRunCount:=-1;
  2364. Get_new_value;
  2365. end;
  2366. procedure TWatch.Get_new_value;
  2367. {$ifndef NODEBUG}
  2368. var p, q : pchar;
  2369. i, j, curframe, startframe : longint;
  2370. s,s2 : string;
  2371. loop_higher, found : boolean;
  2372. last_removed : char;
  2373. function GetValue(var s : string) : boolean;
  2374. begin
  2375. Debugger^.command('p '+s);
  2376. if not Debugger^.Error then
  2377. begin
  2378. s:=StrPas(Debugger^.GetOutput);
  2379. GetValue:=true;
  2380. end
  2381. else
  2382. begin
  2383. s:=StrPas(Debugger^.GetError);
  2384. GetValue:=false;
  2385. { do not open a messagebox for such errors }
  2386. Debugger^.got_error:=false;
  2387. end;
  2388. end;
  2389. begin
  2390. If not assigned(Debugger) or Not Debugger^.HasExe or
  2391. (GDBRunCount=Debugger^.RunCount) then
  2392. exit;
  2393. GDBRunCount:=Debugger^.RunCount;
  2394. if assigned(last_value) then
  2395. strdispose(last_value);
  2396. last_value:=current_value;
  2397. s:=GetStr(expr);
  2398. { Fix 2d array indexing, change [x,x] to [x][x] }
  2399. i:=pos('[',s);
  2400. if i>0 then
  2401. begin
  2402. while i<length(s) do
  2403. begin
  2404. if s[i]=',' then
  2405. begin
  2406. s[i]:='[';
  2407. insert(']',s,i);
  2408. inc(i);
  2409. end;
  2410. inc(i);
  2411. end;
  2412. end;
  2413. found:=GetValue(s);
  2414. Debugger^.got_error:=false;
  2415. loop_higher:=not found;
  2416. if not found then
  2417. begin
  2418. curframe:=Debugger^.get_current_frame;
  2419. startframe:=curframe;
  2420. end
  2421. else
  2422. begin
  2423. curframe:=0;
  2424. startframe:=0;
  2425. end;
  2426. while loop_higher do
  2427. begin
  2428. s:='parent_ebp';
  2429. if GetValue(s) then
  2430. begin
  2431. repeat
  2432. inc(curframe);
  2433. if not Debugger^.set_current_frame(curframe) then
  2434. loop_higher:=false;
  2435. {$ifdef FrameNameKnown}
  2436. s2:='/x '+FrameName;
  2437. {$else not FrameNameKnown}
  2438. s2:='/x $ebp';
  2439. {$endif FrameNameKnown}
  2440. getValue(s2);
  2441. j:=pos('=',s2);
  2442. if j>0 then
  2443. s2:=copy(s2,j+1,length(s2));
  2444. while s2[1] in [' ',TAB] do
  2445. delete(s2,1,1);
  2446. if pos(s2,s)>0 then
  2447. loop_higher :=false;
  2448. until not loop_higher;
  2449. { try again at that level }
  2450. s:=GetStr(expr);
  2451. found:=GetValue(s);
  2452. loop_higher:=not found;
  2453. end
  2454. else
  2455. loop_higher:=false;
  2456. end;
  2457. if found then
  2458. p:=StrNew(Debugger^.GetOutput)
  2459. else
  2460. begin
  2461. { get a reasonable output at least }
  2462. s:=GetStr(expr);
  2463. GetValue(s);
  2464. p:=StrNew(Debugger^.GetError);
  2465. end;
  2466. Debugger^.got_error:=false;
  2467. { We should try here to find the expr in parent
  2468. procedure if there are
  2469. I will implement this as I added a
  2470. parent_ebp pseudo local var to local procedure
  2471. in stabs debug info PM }
  2472. { But there are some pitfalls like
  2473. locals redefined in other sublocals that call the function }
  2474. if curframe<>startframe then
  2475. Debugger^.set_current_frame(startframe);
  2476. q:=nil;
  2477. if assigned(p) and (p[0]='$') then
  2478. q:=StrPos(p,'=');
  2479. if not assigned(q) then
  2480. q:=p;
  2481. if assigned(q) then
  2482. i:=strlen(q)
  2483. else
  2484. i:=0;
  2485. if (i>0) and (q[i-1]=#10) then
  2486. begin
  2487. while (i>1) and ((q[i-2]=' ') or (q[i-2]=#9)) do
  2488. dec(i);
  2489. last_removed:=q[i-1];
  2490. q[i-1]:=#0;
  2491. end
  2492. else
  2493. last_removed:=#0;
  2494. if assigned(q) then
  2495. current_value:=strnew(q)
  2496. else
  2497. current_value:=strnew('');
  2498. if last_removed<>#0 then
  2499. q[i-1]:=last_removed;
  2500. strdispose(p);
  2501. GDBRunCount:=Debugger^.RunCount;
  2502. end;
  2503. {$else NODEBUG}
  2504. begin
  2505. end;
  2506. {$endif NODEBUG}
  2507. procedure TWatch.Force_new_value;
  2508. begin
  2509. GDBRunCount:=-1;
  2510. Get_new_value;
  2511. end;
  2512. destructor TWatch.Done;
  2513. begin
  2514. if assigned(expr) then
  2515. disposestr(expr);
  2516. if assigned(last_value) then
  2517. strdispose(last_value);
  2518. if assigned(current_value) then
  2519. strdispose(current_value);
  2520. inherited done;
  2521. end;
  2522. {****************************************************************************
  2523. TWatchesCollection
  2524. ****************************************************************************}
  2525. constructor TWatchesCollection.Init;
  2526. begin
  2527. inherited Init(10,10);
  2528. end;
  2529. procedure TWatchesCollection.Insert(Item: Pointer);
  2530. begin
  2531. PWatch(Item)^.Get_new_value;
  2532. Inherited Insert(Item);
  2533. Update;
  2534. end;
  2535. procedure TWatchesCollection.Update;
  2536. var
  2537. W,W1 : integer;
  2538. procedure GetMax(P : PWatch);
  2539. begin
  2540. if assigned(P^.Current_value) then
  2541. W1:=StrLen(P^.Current_value)+3+Length(GetStr(P^.expr))
  2542. else
  2543. W1:=2+Length(GetStr(P^.expr));
  2544. if W1>W then
  2545. W:=W1;
  2546. end;
  2547. begin
  2548. W:=0;
  2549. ForEach(@GetMax);
  2550. MaxW:=W;
  2551. If assigned(WatchesWindow) then
  2552. WatchesWindow^.WLB^.Update(MaxW);
  2553. end;
  2554. function TWatchesCollection.At(Index: Integer): PWatch;
  2555. begin
  2556. At:=Inherited At(Index);
  2557. end;
  2558. {****************************************************************************
  2559. TWatchesListBox
  2560. ****************************************************************************}
  2561. constructor TWatchesListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  2562. begin
  2563. inherited Init(Bounds,1,AHScrollBar,AVScrollBar);
  2564. If assigned(List) then
  2565. dispose(list,done);
  2566. List:=WatchesCollection;
  2567. end;
  2568. procedure TWatchesListBox.Update(AMaxWidth : integer);
  2569. var R : TRect;
  2570. begin
  2571. GetExtent(R);
  2572. MaxWidth:=AMaxWidth;
  2573. if (HScrollBar<>nil) and (R.B.X-R.A.X<MaxWidth) then
  2574. HScrollBar^.SetRange(0,MaxWidth-(R.B.X-R.A.X))
  2575. else
  2576. HScrollBar^.SetRange(0,0);
  2577. if R.B.X-R.A.X>MaxWidth then
  2578. HScrollBar^.Hide
  2579. else
  2580. HScrollBar^.Show;
  2581. SetRange(List^.Count+1);
  2582. if R.B.Y-R.A.Y>Range then
  2583. VScrollBar^.Hide
  2584. else
  2585. VScrollBar^.Show;
  2586. {if Focused=List^.Count-1-1 then
  2587. FocusItem(List^.Count-1);
  2588. What was that for ?? PM }
  2589. DrawView;
  2590. end;
  2591. function TWatchesListBox.GetIndentedText(Item,Indent,MaxLen: Sw_Integer;var Modified : boolean): String;
  2592. var
  2593. PW : PWatch;
  2594. ValOffset : Sw_integer;
  2595. S : String;
  2596. begin
  2597. Modified:=false;
  2598. if Item>=WatchesCollection^.Count then
  2599. begin
  2600. GetIndentedText:='';
  2601. exit;
  2602. end;
  2603. PW:=WatchesCollection^.At(Item);
  2604. ValOffset:=Length(GetStr(PW^.Expr))+2;
  2605. if not assigned(PW^.expr) then
  2606. GetIndentedText:=''
  2607. else if Indent<ValOffset then
  2608. begin
  2609. S:=GetStr(PW^.Expr);
  2610. if Indent=0 then
  2611. S:=' '+S
  2612. else
  2613. S:=Copy(S,Indent,High(S));
  2614. if not assigned(PW^.current_value) then
  2615. S:=S+' <Unknown value>'
  2616. else
  2617. S:=S+' '+GetPChar(PW^.Current_value);
  2618. GetIndentedText:=Copy(S,1,MaxLen);
  2619. end
  2620. else
  2621. begin
  2622. if not assigned(PW^.Current_value) or
  2623. (StrLen(PW^.Current_value)<Indent-Valoffset) then
  2624. S:=''
  2625. else
  2626. S:=GetPchar(@(PW^.Current_Value[Indent-Valoffset]));
  2627. GetIndentedText:=Copy(S,1,MaxLen);
  2628. end;
  2629. if assigned(PW^.current_value) and
  2630. assigned(PW^.last_value) and
  2631. (strcomp(PW^.Last_value,PW^.Current_value)<>0) then
  2632. Modified:=true;
  2633. end;
  2634. procedure TWatchesListBox.EditCurrent;
  2635. var
  2636. P: PWatch;
  2637. begin
  2638. if Range=0 then Exit;
  2639. if Focused<WatchesCollection^.Count then
  2640. P:=WatchesCollection^.At(Focused)
  2641. else
  2642. P:=New(PWatch,Init(''));
  2643. Application^.ExecuteDialog(New(PWatchItemDialog,Init(P)),nil);
  2644. WatchesCollection^.Update;
  2645. end;
  2646. function TWatchesListBox.GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String;
  2647. var
  2648. Dummy_Modified : boolean;
  2649. begin
  2650. GetText:=GetIndentedText(Item, 0, MaxLen, Dummy_Modified);
  2651. end;
  2652. procedure TWatchesListBox.DeleteCurrent;
  2653. var
  2654. P: PWatch;
  2655. begin
  2656. if (Range=0) or
  2657. (Focused>=WatchesCollection^.Count) then
  2658. exit;
  2659. P:=WatchesCollection^.At(Focused);
  2660. WatchesCollection^.free(P);
  2661. WatchesCollection^.Update;
  2662. end;
  2663. procedure TWatchesListBox.EditNew;
  2664. var
  2665. P: PWatch;
  2666. S : string;
  2667. begin
  2668. if Focused<WatchesCollection^.Count then
  2669. begin
  2670. P:=WatchesCollection^.At(Focused);
  2671. S:=GetStr(P^.expr);
  2672. end
  2673. else
  2674. S:='';
  2675. P:=New(PWatch,Init(S));
  2676. if Application^.ExecuteDialog(New(PWatchItemDialog,Init(P)),nil)<>cmCancel then
  2677. begin
  2678. WatchesCollection^.AtInsert(Focused,P);
  2679. WatchesCollection^.Update;
  2680. end
  2681. else
  2682. dispose(P,Done);
  2683. end;
  2684. procedure TWatchesListBox.Draw;
  2685. var
  2686. I, J, Item: Sw_Integer;
  2687. NormalColor, SelectedColor, FocusedColor, Color: Word;
  2688. ColWidth, CurCol, Indent: Integer;
  2689. B: TDrawBuffer;
  2690. Modified : boolean;
  2691. Text: String;
  2692. SCOff: Byte;
  2693. TC: byte;
  2694. procedure MT(var C: word);
  2695. begin
  2696. if TC<>0 then C:=(C and $ff0f) or (TC and $f0);
  2697. end;
  2698. begin
  2699. if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
  2700. if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
  2701. begin
  2702. NormalColor := GetColor(1);
  2703. FocusedColor := GetColor(3);
  2704. SelectedColor := GetColor(4);
  2705. end else
  2706. begin
  2707. NormalColor := GetColor(2);
  2708. SelectedColor := GetColor(4);
  2709. end;
  2710. if Transparent then
  2711. begin MT(NormalColor); MT(SelectedColor); end;
  2712. (* if NoSelection then
  2713. SelectedColor:=NormalColor;*)
  2714. if HScrollBar <> nil then Indent := HScrollBar^.Value
  2715. else Indent := 0;
  2716. ColWidth := Size.X div NumCols + 1;
  2717. for I := 0 to Size.Y - 1 do
  2718. begin
  2719. for J := 0 to NumCols-1 do
  2720. begin
  2721. Item := J*Size.Y + I + TopItem;
  2722. CurCol := J*ColWidth;
  2723. if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
  2724. (Focused = Item) and (Range > 0) then
  2725. begin
  2726. Color := FocusedColor;
  2727. SetCursor(CurCol+1,I);
  2728. SCOff := 0;
  2729. end
  2730. else if (Item < Range) and IsSelected(Item) then
  2731. begin
  2732. Color := SelectedColor;
  2733. SCOff := 2;
  2734. end
  2735. else
  2736. begin
  2737. Color := NormalColor;
  2738. SCOff := 4;
  2739. end;
  2740. MoveChar(B[CurCol], ' ', Color, ColWidth);
  2741. if Item < Range then
  2742. begin
  2743. (* Text := GetText(Item, ColWidth + Indent);
  2744. Text := Copy(Text,Indent,ColWidth); *)
  2745. Text:=GetIndentedText(Item,Indent,ColWidth,Modified);
  2746. if modified then
  2747. begin
  2748. SCOff:=0;
  2749. Color:=(Color and $fff0) or Red;
  2750. end;
  2751. MoveStr(B[CurCol], Text, Color);
  2752. if {ShowMarkers or } Modified then
  2753. begin
  2754. WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
  2755. WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
  2756. WordRec(B[CurCol+ColWidth-2]).Hi := Color and $ff;
  2757. end;
  2758. end;
  2759. MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
  2760. end;
  2761. WriteLine(0, I, Size.X, 1, B);
  2762. end;
  2763. end;
  2764. function TWatchesListBox.GetLocalMenu: PMenu;
  2765. var M: PMenu;
  2766. begin
  2767. if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
  2768. M:=NewMenu(
  2769. NewItem(menu_watchlocal_edit,'',kbNoKey,cmEdit,hcNoContext,
  2770. NewItem(menu_watchlocal_new,'',kbNoKey,cmNew,hcNoContext,
  2771. NewItem(menu_watchlocal_delete,'',kbNoKey,cmDelete,hcNoContext,
  2772. NewLine(
  2773. NewItem(menu_msglocal_saveas,'',kbNoKey,cmSaveAs,hcSaveAs,
  2774. nil))))));
  2775. GetLocalMenu:=M;
  2776. end;
  2777. procedure TWatchesListBox.HandleEvent(var Event: TEvent);
  2778. var DontClear: boolean;
  2779. begin
  2780. case Event.What of
  2781. evKeyDown :
  2782. begin
  2783. DontClear:=false;
  2784. case Event.KeyCode of
  2785. kbEnter :
  2786. Message(@Self,evCommand,cmEdit,nil);
  2787. kbIns :
  2788. Message(@Self,evCommand,cmNew,nil);
  2789. kbDel :
  2790. Message(@Self,evCommand,cmDelete,nil);
  2791. else
  2792. DontClear:=true;
  2793. end;
  2794. if not DontClear then
  2795. ClearEvent(Event);
  2796. end;
  2797. evBroadcast :
  2798. case Event.Command of
  2799. cmListItemSelected :
  2800. if Event.InfoPtr=@Self then
  2801. Message(@Self,evCommand,cmEdit,nil);
  2802. end;
  2803. evCommand :
  2804. begin
  2805. DontClear:=false;
  2806. case Event.Command of
  2807. cmEdit :
  2808. EditCurrent;
  2809. cmDelete :
  2810. DeleteCurrent;
  2811. cmNew :
  2812. EditNew;
  2813. else
  2814. DontClear:=true;
  2815. end;
  2816. if not DontClear then
  2817. ClearEvent(Event);
  2818. end;
  2819. end;
  2820. inherited HandleEvent(Event);
  2821. end;
  2822. constructor TWatchesListBox.Load(var S: TStream);
  2823. begin
  2824. inherited Load(S);
  2825. If assigned(List) then
  2826. dispose(list,done);
  2827. List:=WatchesCollection;
  2828. { we must set Range PM }
  2829. SetRange(List^.count+1);
  2830. end;
  2831. procedure TWatchesListBox.Store(var S: TStream);
  2832. var OL: PCollection;
  2833. OldRange : Sw_integer;
  2834. begin
  2835. OL:=List;
  2836. OldRange:=Range;
  2837. Range:=0;
  2838. New(List, Init(1,1));
  2839. inherited Store(S);
  2840. Dispose(List, Done);
  2841. List:=OL;
  2842. { ^^^ nasty trick - has anyone a better idea how to avoid storing the
  2843. collection? Pasting here a modified version of TListBox.Store+
  2844. TAdvancedListBox.Store isn't a better solution, since by eventually
  2845. changing the obj-hierarchy you'll always have to modify this, too - BG }
  2846. SetRange(OldRange);
  2847. end;
  2848. destructor TWatchesListBox.Done;
  2849. begin
  2850. List:=nil;
  2851. inherited Done;
  2852. end;
  2853. {****************************************************************************
  2854. TWatchesWindow
  2855. ****************************************************************************}
  2856. Constructor TWatchesWindow.Init;
  2857. var
  2858. HSB,VSB: PScrollBar;
  2859. R,R2 : trect;
  2860. begin
  2861. Desktop^.GetExtent(R);
  2862. R.A.Y:=R.B.Y-7;
  2863. inherited Init(R, dialog_watches,SearchFreeWindowNo);
  2864. Palette:=wpCyanWindow;
  2865. GetExtent(R);
  2866. HelpCtx:=hcWatchesWindow;
  2867. R.Grow(-1,-1);
  2868. R2.Copy(R);
  2869. Inc(R2.B.Y);
  2870. R2.A.Y:=R2.B.Y-1;
  2871. New(HSB, Init(R2));
  2872. HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX;
  2873. HSB^.SetStep(R.B.X-R.A.X,1);
  2874. Insert(HSB);
  2875. R2.Copy(R);
  2876. Inc(R2.B.X);
  2877. R2.A.X:=R2.B.X-1;
  2878. New(VSB, Init(R2));
  2879. VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  2880. Insert(VSB);
  2881. New(WLB,Init(R,HSB,VSB));
  2882. WLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  2883. WLB^.Transparent:=true;
  2884. Insert(WLB);
  2885. If assigned(WatchesWindow) then
  2886. dispose(WatchesWindow,done);
  2887. WatchesWindow:=@Self;
  2888. Update;
  2889. end;
  2890. procedure TWatchesWindow.Update;
  2891. begin
  2892. WatchesCollection^.Update;
  2893. Draw;
  2894. end;
  2895. constructor TWatchesWindow.Load(var S: TStream);
  2896. begin
  2897. inherited Load(S);
  2898. GetSubViewPtr(S,WLB);
  2899. If assigned(WatchesWindow) then
  2900. dispose(WatchesWindow,done);
  2901. WatchesWindow:=@Self;
  2902. end;
  2903. procedure TWatchesWindow.Store(var S: TStream);
  2904. begin
  2905. inherited Store(S);
  2906. PutSubViewPtr(S,WLB);
  2907. end;
  2908. Destructor TWatchesWindow.Done;
  2909. begin
  2910. WatchesWindow:=nil;
  2911. Dispose(WLB,done);
  2912. inherited done;
  2913. end;
  2914. {****************************************************************************
  2915. TWatchItemDialog
  2916. ****************************************************************************}
  2917. constructor TWatchItemDialog.Init(AWatch: PWatch);
  2918. var R,R2: TRect;
  2919. begin
  2920. R.Assign(0,0,50,10);
  2921. inherited Init(R,'Edit Watch');
  2922. Watch:=AWatch;
  2923. GetExtent(R); R.Grow(-3,-2);
  2924. Inc(R.A.Y); R.B.Y:=R.A.Y+1; R.B.X:=R.A.X+36;
  2925. New(NameIL, Init(R, 255)); Insert(NameIL);
  2926. R2.Copy(R); R2.A.X:=R2.B.X; R2.B.X:=R2.A.X+3;
  2927. Insert(New(PHistory, Init(R2, NameIL, hidWatchDialog)));
  2928. R2.Copy(R); R2.Move(-1,-1);
  2929. Insert(New(PLabel, Init(R2, label_watch_expressiontowatch, NameIL)));
  2930. GetExtent(R);
  2931. R.Grow(-3,-1);
  2932. R.A.Y:=R.A.Y+3;
  2933. TextST:=New(PAdvancedStaticText, Init(R, label_watch_values));
  2934. Insert(TextST);
  2935. InsertButtons(@Self);
  2936. NameIL^.Select;
  2937. end;
  2938. function TWatchItemDialog.Execute: Word;
  2939. var R: word;
  2940. S1,S2: string;
  2941. begin
  2942. S1:=GetStr(Watch^.expr);
  2943. NameIL^.SetData(S1);
  2944. S1:=GetPChar(Watch^.Current_value);
  2945. S2:=GetPChar(Watch^.Last_value);
  2946. ClearFormatParams;
  2947. AddFormatParamStr(S1);
  2948. AddFormatParamStr(S2);
  2949. if assigned(Watch^.Last_value) and
  2950. assigned(Watch^.Current_value) and
  2951. (strcomp(Watch^.Last_value,Watch^.Current_value)=0) then
  2952. S1:=FormatStrF(msg_watch_currentvalue,FormatParams)
  2953. else
  2954. S1:=FormatStrF(msg_watch_currentandpreviousvalue,FormatParams);
  2955. TextST^.SetText(S1);
  2956. if assigned(FirstEditorWindow) then
  2957. FindReplaceEditor:=FirstEditorWindow^.Editor;
  2958. R:=inherited Execute;
  2959. FindReplaceEditor:=nil;
  2960. if R=cmOK then
  2961. begin
  2962. NameIL^.GetData(S1);
  2963. Watch^.Rename(S1);
  2964. {$ifndef NODEBUG}
  2965. If assigned(Debugger) then
  2966. Debugger^.ReadWatches;
  2967. {$endif NODEBUG}
  2968. end;
  2969. Execute:=R;
  2970. end;
  2971. {****************************************************************************
  2972. TStackWindow
  2973. ****************************************************************************}
  2974. constructor TFramesListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  2975. begin
  2976. Inherited Init(Bounds,AHScrollBar,AVScrollBar);
  2977. end;
  2978. procedure TFramesListBox.Update;
  2979. var i : longint;
  2980. W : PSourceWindow;
  2981. begin
  2982. {$ifndef NODEBUG}
  2983. { call backtrace command }
  2984. If not assigned(Debugger) then
  2985. exit;
  2986. DeskTop^.Lock;
  2987. Clear;
  2988. { forget all old frames }
  2989. Debugger^.clear_frames;
  2990. if Debugger^.WindowWidth<>-1 then
  2991. Debugger^.Command('set width 0xffffffff');
  2992. Debugger^.Command('backtrace');
  2993. { generate list }
  2994. { all is in tframeentry }
  2995. for i:=0 to Debugger^.frame_count-1 do
  2996. begin
  2997. with Debugger^.frames[i]^ do
  2998. begin
  2999. if assigned(file_name) then
  3000. AddItem(new(PMessageItem,init(0,GetPChar(function_name)+GetPChar(args),
  3001. AddModuleName(GetPChar(file_name)),line_number,1)))
  3002. else
  3003. AddItem(new(PMessageItem,init(0,HexStr(address,8)+' '+GetPChar(function_name)+GetPChar(args),
  3004. AddModuleName(''),line_number,1)));
  3005. W:=SearchOnDesktop(GetPChar(file_name),false);
  3006. { First reset all Debugger rows }
  3007. If assigned(W) then
  3008. begin
  3009. W^.Editor^.SetLineFlagExclusive(lfDebuggerRow,-1);
  3010. W^.Editor^.DebuggerRow:=-1;
  3011. end;
  3012. end;
  3013. end;
  3014. { Now set all Debugger rows }
  3015. for i:=0 to Debugger^.frame_count-1 do
  3016. begin
  3017. with Debugger^.frames[i]^ do
  3018. begin
  3019. W:=SearchOnDesktop(GetPChar(file_name),false);
  3020. If assigned(W) then
  3021. begin
  3022. If W^.Editor^.DebuggerRow=-1 then
  3023. begin
  3024. W^.Editor^.SetLineFlagState(line_number-1,lfDebuggerRow,true);
  3025. W^.Editor^.DebuggerRow:=line_number-1;
  3026. end;
  3027. end;
  3028. end;
  3029. end;
  3030. if Assigned(list) and (List^.Count > 0) then
  3031. FocusItem(0);
  3032. if Debugger^.WindowWidth<>-1 then
  3033. Debugger^.Command('set width '+IntToStr(Debugger^.WindowWidth));
  3034. DeskTop^.Unlock;
  3035. {$endif NODEBUG}
  3036. end;
  3037. function TFramesListBox.GetLocalMenu: PMenu;
  3038. begin
  3039. GetLocalMenu:=Inherited GetLocalMenu;
  3040. end;
  3041. procedure TFramesListBox.GotoSource;
  3042. begin
  3043. {$ifndef NODEBUG}
  3044. { select frame for watches }
  3045. If not assigned(Debugger) then
  3046. exit;
  3047. Debugger^.Command('f '+IntToStr(Focused));
  3048. { for local vars }
  3049. Debugger^.RereadWatches;
  3050. {$endif NODEBUG}
  3051. { goto source }
  3052. inherited GotoSource;
  3053. end;
  3054. procedure TFramesListBox.GotoAssembly;
  3055. begin
  3056. {$ifndef NODEBUG}
  3057. { select frame for watches }
  3058. If not assigned(Debugger) then
  3059. exit;
  3060. Debugger^.Command('f '+IntToStr(Focused));
  3061. { for local vars }
  3062. Debugger^.RereadWatches;
  3063. {$endif}
  3064. { goto source/assembly mixture }
  3065. InitDisassemblyWindow;
  3066. DisassemblyWindow^.LoadFunction('');
  3067. {$ifndef NODEBUG}
  3068. DisassemblyWindow^.SetCurAddress(Debugger^.frames[Focused]^.address);
  3069. DisassemblyWindow^.SelectInDebugSession;
  3070. {$endif NODEBUG}
  3071. end;
  3072. procedure TFramesListBox.HandleEvent(var Event: TEvent);
  3073. begin
  3074. if ((Event.What=EvKeyDown) and (Event.CharCode='i')) or
  3075. ((Event.What=EvCommand) and (Event.Command=cmDisassemble)) then
  3076. GotoAssembly;
  3077. inherited HandleEvent(Event);
  3078. end;
  3079. destructor TFramesListBox.Done;
  3080. begin
  3081. Inherited Done;
  3082. end;
  3083. Constructor TStackWindow.Init;
  3084. var
  3085. HSB,VSB: PScrollBar;
  3086. R,R2 : trect;
  3087. begin
  3088. Desktop^.GetExtent(R);
  3089. R.A.Y:=R.B.Y-5;
  3090. inherited Init(R, dialog_callstack, wnNoNumber);
  3091. Palette:=wpCyanWindow;
  3092. GetExtent(R);
  3093. HelpCtx:=hcStackWindow;
  3094. R.Grow(-1,-1);
  3095. R2.Copy(R);
  3096. Inc(R2.B.Y);
  3097. R2.A.Y:=R2.B.Y-1;
  3098. New(HSB, Init(R2));
  3099. HSB^.GrowMode:=gfGrowLoY+gfGrowHiY+gfGrowHiX;
  3100. Insert(HSB);
  3101. R2.Copy(R);
  3102. Inc(R2.B.X);
  3103. R2.A.X:=R2.B.X-1;
  3104. New(VSB, Init(R2));
  3105. VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  3106. Insert(VSB);
  3107. New(FLB,Init(R,HSB,VSB));
  3108. FLB^.GrowMode:=gfGrowHiX+gfGrowHiY;
  3109. Insert(FLB);
  3110. If assigned(StackWindow) then
  3111. dispose(StackWindow,done);
  3112. StackWindow:=@Self;
  3113. Update;
  3114. end;
  3115. procedure TStackWindow.Update;
  3116. begin
  3117. FLB^.Update;
  3118. DrawView;
  3119. end;
  3120. constructor TStackWindow.Load(var S: TStream);
  3121. begin
  3122. inherited Load(S);
  3123. GetSubViewPtr(S,FLB);
  3124. If assigned(StackWindow) then
  3125. dispose(StackWindow,done);
  3126. StackWindow:=@Self;
  3127. end;
  3128. procedure TStackWindow.Store(var S: TStream);
  3129. begin
  3130. inherited Store(S);
  3131. PutSubViewPtr(S,FLB);
  3132. end;
  3133. Destructor TStackWindow.Done;
  3134. begin
  3135. StackWindow:=nil;
  3136. Dispose(FLB,done);
  3137. inherited done;
  3138. end;
  3139. {****************************************************************************
  3140. Init/Final
  3141. ****************************************************************************}
  3142. function GetGDBTargetShortName : string;
  3143. begin
  3144. {$ifdef SUPPORT_REMOTE}
  3145. {$ifdef PALMOSGDB}
  3146. GetGDBTargetShortName:='palmos';
  3147. {$else}
  3148. GetGDBTargetShortName:='linux';
  3149. {$endif PALMOSGDB}
  3150. {$else not SUPPORT_REMOTE}
  3151. GetGDBTargetShortName:=source_info.shortname
  3152. {$endif not SUPPORT_REMOTE}
  3153. end;
  3154. procedure InitDebugger;
  3155. {$ifdef DEBUG}
  3156. var s : string;
  3157. i,p : longint;
  3158. {$endif DEBUG}
  3159. var
  3160. NeedRecompileExe : boolean;
  3161. cm : longint;
  3162. begin
  3163. {$ifdef DEBUG}
  3164. if not use_gdb_file then
  3165. begin
  3166. Assign(gdb_file,GDBOutFileName);
  3167. {$I-}
  3168. Rewrite(gdb_file);
  3169. if InOutRes<>0 then
  3170. begin
  3171. s:=GDBOutFileName;
  3172. p:=pos('.',s);
  3173. if p>1 then
  3174. for i:=0 to 9 do
  3175. begin
  3176. s:=copy(s,1,p-2)+chr(i+ord('0'))+copy(s,p,length(s));
  3177. InOutRes:=0;
  3178. Assign(gdb_file,s);
  3179. rewrite(gdb_file);
  3180. if InOutRes=0 then
  3181. break;
  3182. end;
  3183. end;
  3184. if IOResult=0 then
  3185. Use_gdb_file:=true;
  3186. end;
  3187. {$I+}
  3188. {$endif}
  3189. NeedRecompileExe:=false;
  3190. if UpCaseStr(TargetSwitches^.GetCurrSelParam)<>UpCaseStr(GetGDBTargetShortName) then
  3191. begin
  3192. ClearFormatParams;
  3193. AddFormatParamStr(TargetSwitches^.GetCurrSelParam);
  3194. AddFormatParamStr(GetGDBTargetShortName);
  3195. cm:=ConfirmBox(msg_cantdebugchangetargetto,@FormatParams,true);
  3196. if cm=cmCancel then
  3197. Exit;
  3198. if cm=cmYes then
  3199. begin
  3200. { force recompilation }
  3201. PrevMainFile:='';
  3202. NeedRecompileExe:=true;
  3203. TargetSwitches^.SetCurrSelParam(GetGDBTargetShortName);
  3204. If DebugInfoSwitches^.GetCurrSelParam='-' then
  3205. DebugInfoSwitches^.SetCurrSelParam('l');
  3206. IDEApp.UpdateTarget;
  3207. end;
  3208. end;
  3209. if not NeedRecompileExe then
  3210. NeedRecompileExe:=(not ExistsFile(ExeFile)) or (CompilationPhase<>cpDone) or
  3211. (PrevMainFile<>MainFile) or NeedRecompile(cRun,false);
  3212. if Not NeedRecompileExe and Not MainHasDebugInfo then
  3213. begin
  3214. ClearFormatParams;
  3215. cm:=ConfirmBox(msg_compiledwithoutdebuginforecompile,nil,true);
  3216. if cm=cmCancel then
  3217. Exit;
  3218. if cm=cmYes then
  3219. begin
  3220. { force recompilation }
  3221. PrevMainFile:='';
  3222. NeedRecompileExe:=true;
  3223. DebugInfoSwitches^.SetCurrSelParam('l');
  3224. end;
  3225. end;
  3226. if NeedRecompileExe then
  3227. DoCompile(cRun);
  3228. if CompilationPhase<>cpDone then
  3229. Exit;
  3230. if (EXEFile='') then
  3231. begin
  3232. ErrorBox(msg_nothingtodebug,nil);
  3233. Exit;
  3234. end;
  3235. { init debugcontroller }
  3236. {$ifndef NODEBUG}
  3237. if not assigned(Debugger) then
  3238. begin
  3239. PushStatus(msg_startingdebugger);
  3240. new(Debugger,Init);
  3241. PopStatus;
  3242. end;
  3243. Debugger^.SetExe(ExeFile);
  3244. {$endif NODEBUG}
  3245. {$ifdef GDBWINDOW}
  3246. InitGDBWindow;
  3247. {$endif def GDBWINDOW}
  3248. end;
  3249. procedure DoneDebugger;
  3250. begin
  3251. {$ifdef DEBUG}
  3252. If IDEApp.IsRunning then
  3253. PushStatus('Closing debugger');
  3254. {$endif}
  3255. {$ifndef NODEBUG}
  3256. if assigned(Debugger) then
  3257. dispose(Debugger,Done);
  3258. Debugger:=nil;
  3259. {$endif NODEBUG}
  3260. {$ifdef DOS}
  3261. If assigned(UserScreen) then
  3262. PDosScreen(UserScreen)^.FreeGraphBuffer;
  3263. {$endif DOS}
  3264. {$ifdef DEBUG}
  3265. If Use_gdb_file then
  3266. begin
  3267. Use_gdb_file:=false;
  3268. Close(GDB_file);
  3269. end;
  3270. If IDEApp.IsRunning then
  3271. PopStatus;
  3272. {$endif DEBUG}
  3273. end;
  3274. procedure InitGDBWindow;
  3275. var
  3276. R : TRect;
  3277. begin
  3278. if GDBWindow=nil then
  3279. begin
  3280. DeskTop^.GetExtent(R);
  3281. new(GDBWindow,init(R));
  3282. DeskTop^.Insert(GDBWindow);
  3283. end;
  3284. end;
  3285. procedure DoneGDBWindow;
  3286. begin
  3287. If IDEApp.IsRunning and
  3288. assigned(GDBWindow) then
  3289. begin
  3290. DeskTop^.Delete(GDBWindow);
  3291. end;
  3292. GDBWindow:=nil;
  3293. end;
  3294. procedure InitDisassemblyWindow;
  3295. var
  3296. R : TRect;
  3297. begin
  3298. if DisassemblyWindow=nil then
  3299. begin
  3300. DeskTop^.GetExtent(R);
  3301. new(DisassemblyWindow,init(R));
  3302. DeskTop^.Insert(DisassemblyWindow);
  3303. end;
  3304. end;
  3305. procedure DoneDisassemblyWindow;
  3306. begin
  3307. if assigned(DisassemblyWindow) then
  3308. begin
  3309. DeskTop^.Delete(DisassemblyWindow);
  3310. Dispose(DisassemblyWindow,Done);
  3311. DisassemblyWindow:=nil;
  3312. end;
  3313. end;
  3314. procedure InitStackWindow;
  3315. begin
  3316. if StackWindow=nil then
  3317. begin
  3318. new(StackWindow,init);
  3319. DeskTop^.Insert(StackWindow);
  3320. end;
  3321. end;
  3322. procedure DoneStackWindow;
  3323. begin
  3324. if assigned(StackWindow) then
  3325. begin
  3326. DeskTop^.Delete(StackWindow);
  3327. StackWindow:=nil;
  3328. end;
  3329. end;
  3330. procedure InitBreakpoints;
  3331. begin
  3332. New(BreakpointsCollection,init(10,10));
  3333. end;
  3334. procedure DoneBreakpoints;
  3335. begin
  3336. Dispose(BreakpointsCollection,Done);
  3337. BreakpointsCollection:=nil;
  3338. end;
  3339. procedure InitWatches;
  3340. begin
  3341. New(WatchesCollection,init);
  3342. end;
  3343. procedure DoneWatches;
  3344. begin
  3345. Dispose(WatchesCollection,Done);
  3346. WatchesCollection:=nil;
  3347. end;
  3348. procedure RegisterFPDebugViews;
  3349. begin
  3350. RegisterType(RWatchesWindow);
  3351. RegisterType(RBreakpointsWindow);
  3352. RegisterType(RWatchesListBox);
  3353. RegisterType(RBreakpointsListBox);
  3354. RegisterType(RStackWindow);
  3355. RegisterType(RFramesListBox);
  3356. RegisterType(RBreakpoint);
  3357. RegisterType(RWatch);
  3358. RegisterType(RBreakpointCollection);
  3359. RegisterType(RWatchesCollection);
  3360. end;
  3361. end.
  3362. {$endif}
  3363. {
  3364. $Log$
  3365. Revision 1.59 2004-12-22 15:24:06 peter
  3366. * fixed NODEBUG
  3367. * set default target to the default target of the compiler
  3368. Revision 1.58 2004/12/19 18:39:50 florian
  3369. * made 64 bit safe
  3370. Revision 1.57 2004/12/06 20:39:25 peter
  3371. change a[1,2] to a[1][2]
  3372. Revision 1.56 2004/11/21 20:53:26 peter
  3373. * fixed breakpoint dialog
  3374. Revision 1.55 2004/11/11 15:20:52 florian
  3375. * applied Peter's patch from yesterday
  3376. Revision 1.54 2004/11/08 21:55:09 peter
  3377. * fixed run directory
  3378. * Open dialog starts in dir of last editted file
  3379. Revision 1.53 2004/11/08 20:28:26 peter
  3380. * Breakpoints are now deleted when removed from source, disabling is
  3381. still possible from the breakpoint list
  3382. * COMPILER_1_0, FVISION, GABOR defines removed, only support new
  3383. FV and 1.9.x compilers
  3384. * Run directory added to Run menu
  3385. * Useless programinfo window removed
  3386. Revision 1.52 2004/11/06 17:22:52 peter
  3387. * fixes for new fv
  3388. Revision 1.51 2004/07/09 23:17:25 peter
  3389. * revert isatty patch
  3390. Revision 1.49 2004/02/20 21:46:06 peter
  3391. * fix compile with 1.0.x
  3392. Revision 1.48 2003/11/19 17:11:39 marco
  3393. * termio unit
  3394. Revision 1.47 2003/11/17 10:05:51 marco
  3395. * threads for FreeBSD. Not working tho
  3396. Revision 1.46 2003/03/30 12:12:12 armin
  3397. * allow local and remote debugging if SUPPORT_REMOTE is given
  3398. Revision 1.45 2003/03/27 14:10:55 pierre
  3399. * fix problem with mixed case target names as suggested by Armin Diehl
  3400. Revision 1.44 2003/01/14 16:25:23 pierre
  3401. + small palmos specific additions
  3402. Revision 1.43 2002/12/18 01:20:12 pierre
  3403. + Use TEditorInputLine instead of TInputLine
  3404. Revision 1.42 2002/12/16 15:15:40 pierre
  3405. * Added TBreakpointCollection.FindBreakpointAt method
  3406. Revision 1.41 2002/12/16 09:05:28 pierre
  3407. * sanity ceck in ToggleFileLine method
  3408. Revision 1.40 2002/02/09 02:04:46 pierre
  3409. * fix problem with disable all invalid breakpoints
  3410. Revision 1.39 2002/12/12 00:05:57 pierre
  3411. * add code for breakpoint moves + registers in fprags.pas unit
  3412. Revision 1.38 2002/11/30 01:56:52 pierre
  3413. + powerpc cpu support started
  3414. Revision 1.37 2002/11/28 13:00:25 pierre
  3415. + remote support
  3416. Revision 1.36 2002/11/21 17:52:28 pierre
  3417. * some crossgdb infos added
  3418. Revision 1.35 2002/11/21 15:48:39 pierre
  3419. * fix several problems related to remote cross debugging
  3420. Revision 1.34 2002/11/21 00:37:56 pierre
  3421. + some cross gdb enhancements
  3422. Revision 1.33 2002/09/21 22:23:49 pierre
  3423. * restore text mode on reset for Dos apps
  3424. Revision 1.32 2002/09/17 21:58:45 pierre
  3425. * correct last fpu patch so 'info all' is called only once
  3426. Revision 1.31 2002/09/17 21:48:41 pierre
  3427. * allow fpu window to be resized
  3428. Revision 1.30 2002/09/17 21:20:07 pierre
  3429. * fix infinite recursion if GDB window and register window open
  3430. Revision 1.29 2002/09/13 22:30:50 pierre
  3431. * only fpc uses video unit
  3432. Revision 1.28 2002/09/13 08:13:07 pierre
  3433. * avoid RTE 201 in hexstr calls
  3434. Revision 1.27 2002/09/07 21:04:41 carl
  3435. * fix range check errors for version 1.1 compilation
  3436. Revision 1.26 2002/09/07 15:40:42 peter
  3437. * old logs removed and tabs fixed
  3438. Revision 1.25 2002/09/03 13:59:47 pierre
  3439. + added history for watches and breakpoints
  3440. Revision 1.24 2002/09/02 10:18:09 pierre
  3441. * fix problems with breakpoint lists
  3442. Revision 1.23 2002/08/13 08:59:12 pierre
  3443. + Run menu changes depending on wether the debuggee is running or not
  3444. Revision 1.22 2002/08/13 07:15:02 pierre
  3445. + Disable all invalid breakpoints feature added
  3446. Revision 1.21 2002/06/10 19:26:48 pierre
  3447. * check if DebuggeTTY is a valid terminal
  3448. Revision 1.20 2002/06/06 14:11:25 pierre
  3449. * handle win32 Ctrl-C change for graphic version
  3450. Revision 1.19 2002/06/06 08:16:18 pierre
  3451. * avoid crashes if quitting while debuggee is running
  3452. Revision 1.18 2002/04/25 13:33:31 pierre
  3453. * fix the problem with dirs containing asterisks
  3454. Revision 1.17 2002/04/17 11:11:54 pierre
  3455. * avoid problems for ClassVariable in Watches window
  3456. Revision 1.16 2002/04/11 06:41:13 pierre
  3457. * fix problem of TWatchesListBox with fvision
  3458. Revision 1.15 2002/04/03 06:18:30 pierre
  3459. * fix some win32 GDB filename problems
  3460. Revision 1.14 2002/04/02 15:09:38 pierre
  3461. * fixed wrong exit without unlock
  3462. Revision 1.13 2002/04/02 13:23:54 pierre
  3463. * Use StrToCard and HexToCard functions to avoid signed/unsigned overflows
  3464. Revision 1.12 2002/04/02 12:20:58 pierre
  3465. * fix problem with breakpoints in subdirs
  3466. Revision 1.11 2002/04/02 11:10:29 pierre
  3467. * fix FPC_BREAK_ERROR problem and avoid blinking J
  3468. Revision 1.10 2002/03/27 11:24:09 pierre
  3469. * fix several problems related to long file nmze support for win32 exes
  3470. Revision 1.9 2002/02/06 14:45:00 pierre
  3471. + handle signals
  3472. }