fpdebug.pas 124 KB

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