fpdebug.pas 99 KB

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