home *** CD-ROM | disk | FTP | other *** search
Text File | 2005-03-24 | 27.8 KB | 1,011 lines |
- /**************************************************************************
- *
- * @@@BUILDINFO@@@ 10debugger.jsx 1.0.0.51 20-Feb-2005
- * Copyright 2005 Adobe Systems Incorporated
- * All Rights Reserved.
- *
- * NOTICE: All information contained herein is, and remains the property of
- * Adobe Systems Incorporated and its suppliers, if any. The intellectual
- * and technical concepts contained herein are proprietary to Adobe Systems
- * Incorporated and its suppliers and may be covered by U.S. and Foreign
- * Patents,patents in process,and are protected by trade secret or copyright
- * law. Dissemination of this information or reproduction of this material
- * is strictly forbidden unless prior written permission is obtained from
- * Adobe Systems Incorporated.
- **************************************************************************/
-
- // The current debugger contains the debugger that has either been selected
- // by the user, or by a request connect command from a target application.
-
- var currentDebugger = null;
-
- // The own debugger is the fallback when a connect request fails.
-
- var ownDebugger = null;
-
- /*
- The Debugger object is the core object that talks to the debugging
- backend. There is one Debugger object per active connection.
- */
-
- function Debugger (target, engine)
- {
- this.target = target; // the target name
- this.engine = engine; // the engine name
- this.current = false; // true if this is the current debugger for the given target
- this.dynamic = false; // true if the engine is created on the fly
- this.waiting = false; // true if the engine state is "waiting"
- this.error = null; // on runtime errors, the error message
- this.document = null; // the doc being debugged
- this.frame = -1; // the stack frame we are looking at during debugging
- this.line = -1; // the current line
- this.documents = {}; // active documents collection; properties are script IDs
- this.profileLevel = 0; // the profiling level
- this.state = Debugger.INACTIVE;
- this.oldStack = false; // for targets with versions <= 3.6.36
-
- Debugger.all.push (this);
- }
-
- // The documents object holds information about the documents currently being debugged.
- // Each property (which is the document's scriptID) contains an object with the following
- // properties:
- // document: the Document object
- // profData: the Document object's ProfilerData object
- // savedText: the original text of the document
- // The latter property contains the original document text in case the app returned a different
- // text for the currently executed script (it may e.g. contain included files).
-
- //////////////////////////////////////////////////////////////////////
- // Static properties and methods
-
- // Debugger status values
-
- Debugger.RUNNING = localize ("$$$/ESToolkit/Toolbar/Engine/State/Running=running");
- Debugger.STOPPED = localize ("$$$/ESToolkit/Toolbar/Engine/State/Stopped=stopped");
- Debugger.WAITING = localize ("$$$/ESToolkit/Toolbar/Engine/State/Waiting=waiting");
- Debugger.INACTIVE = "";
-
- // Line flags for editor lines
-
- Debugger.BP_DISABLED = 0x80; // this line has a BP
- Debugger.BP_ENABLED = 0xC0; // the BP is enabled
- Debugger.BP_COND_DISABLED = 0xA0; // this line has a conditional BP
- Debugger.BP_COND_ENABLED = 0xE0; // the conditional BP is enabled
- Debugger.BP_ENABLED_MASK = 0x40; // the breakpoint is enabled
- Debugger.BP_COND_MASK = 0x20; // set for a conditional breakpoint
- Debugger.BP_MASK = 0xE0; // BP mask
- Debugger.VISITED = 0x08; // line has been visited
- Debugger.COLOR_MASK = 0x07; // background color mask
- Debugger.CURRENT_COLOR = 0xFFFF00; // yellow background
- Debugger.ERROR_COLOR = 0xFF7F7F; // red background
- Debugger.STACK_COLOR = 0x7FFF7F; // green background
-
- // The list of all debuggers.
-
- Debugger.all = [];
-
- // The list of all connected applications. This is an object whose
- // properties are the BridgeTalk names of all connected apps with
- // the value set to true.
-
- Debugger.connected = {};
-
- // Create my own debugger, but do not connect yet. During startup,
- // there may be a connect request from another app which takes precedence.
-
- Debugger.createOwn = function()
- {
- ownDebugger = new Debugger (BridgeTalk.appSpecifier, "main");
- window.setupEngines (BridgeTalk.appSpecifier);
- }
-
- // Connect to a target app. This call attempts to launch the target,
- // identifies the app as the debugger, collects the list of engines,
- // creates the necessary debugger instances, and activates the debugger
- // on the first engine returned. The supplied name is the BridgeTalk name.
- // If doc and dbgLevel are supplied, the connect request was due to an
- // autoconnect from within Debugger.start(). We need to fire a Start commend
- // with these two arguments if present.
-
- Debugger.connect = function (target, doc, dbgLevel)
- {
- if (!currentDebugger || currentDebugger.target != target)
- {
- BridgeTalk.checkTarget (target);
- var bt = BridgeTalk.create (target, "Connect");
- bt.doc = doc;
- bt.dbgLevel = dbgLevel;
- bt.onOwnResult = function (bt)
- {
- var engines = Debugger.setupConnection (bt);
- // strip the debugger suffix if present
- var target = this.target.replace ("#estk", "");
- if (target != BridgeTalk.appSpecifier)
- app.toFront();
- if (currentDebugger.target == target && this.doc)
- {
- if (engines == 1)
- currentDebugger.start (doc, dbgLevel);
- else
- {
- var displayName = BridgeTalk.getTargetDisplayName (target);
- messageBox ("$$$/ESToolkit/Alerts/PleaseSwitch=Please select target %1!", displayName);
- window.engines.active = true;
- }
- }
- }
- bt.safeSend();
- }
- }
-
- // Execute a remote connection request.
-
- Debugger.remoteConnect = function (bt)
- {
- Debugger.setupConnection (bt, true);
- }
-
- // Disconnect all active debuggers from a target; called when the target goes down.
-
- Debugger.disconnect = function (target, quiet)
- {
- BridgeTalk.setConnected (target, false);
-
- for (var i = 0; i < Debugger.all.length; i++)
- {
- var dbg = Debugger.all [i];
- if (dbg.target == target)
- {
- if (dbg.status == Debugger.RUNNING)
- {
- // for the first active debugger on a target, display the error message
- if (!quiet)
- {
- errorBox ("$$$/ESToolkit/Alerts/TargetDead=%1 does not respond anymore!^nThe debugging session will be aborted.",
- BridgeTalk.getTargetDisplayName (target));
- quiet = true;
- }
- dbg.setStoppedState();
- }
- }
- }
- if (currentDebugger.target == target)
- Debugger.connect (BridgeTalk.appSpecifier);
- }
-
- // Get all debuggers for a given target.
-
- Debugger.getAll = function (target)
- {
- var debuggers = [];
- for (var i = 0; i < Debugger.all.length; i++)
- {
- var dbg = Debugger.all [i];
- if (dbg.target == target)
- debuggers.push (dbg);
- }
- return debuggers;
- }
-
- // Get the current debugger for a given target.
-
- Debugger.getCurrent = function (target)
- {
- for (var i = 0; i < Debugger.all.length; i++)
- {
- var dbg = Debugger.all [i];
- if (dbg.target == target && dbg.current)
- return dbg;
- }
- return null;
- }
-
- // Setup a debugger connection by reading the body of the given BT message.
- // This message is either a received ConnectRequest message, or the reply
- // of a Connect message. This will also activate this debugger. Returns the
- // number of engines discovered.
-
- Debugger.setupConnection = function (bt, remote)
- {
- var reply = bt.splitBody();
- var target = bt.sender.replace ("#estk", "");
- var selEngine = bt.headers.Engine;
- var selDebugger = null;
- var engines = 0;
-
- BridgeTalk.setConnected (target, true, bt.headers ["Sender-ID"]);
-
- for (var i = 0; i < reply.length; i++)
- {
- if (reply [i].length == 0)
- // list of supported commands
- break;
- var engine = reply [i][0];
- var status = reply [i][1];
- if (!selEngine)
- selEngine = engine;
- // if we are connected by a remote request, the debugger is always active!
- // create the debugger if not yet present
- var dbg = Debugger.find (target, engine);
- if (!dbg)
- dbg = new Debugger (target, engine);
- // BUG FIX - if an app reports "running" pre x43, set to empty
- if (bt.headers.Version < "3.6.43" && status == "running")
- status = "";
-
- if (dbg.state != Debugger.STOPPED)
- switch (status)
- {
- case "running": if (dbg.state != Debugger.STOPPED)
- dbg.state = Debugger.RUNNING; break;
- case "active": dbg.waiting = true;
- dbg.state = Debugger.WAITING; break;
- default: dbg.state = Debugger.INACTIVE;
- }
- dbg.dynamic = (status == "dynamic");
- if (engine == selEngine)
- selDebugger = dbg;
- engines++;
- }
- // add the engines
- window.setupEngines (target);
- if (selDebugger)
- {
- if (remote)
- {
- documents.clearProfData();
- selDebugger.profileLevel = 0;
- selDebugger.error = null;
- selDebugger.documents = {};
- }
- selDebugger.activate();
- }
- return engines;
- }
-
- // Find a debugger by target name and engine name
-
- Debugger.find = function (target, engine)
- {
- // strip the debugger suffix if present
- target = target.replace ("#estk", "");
- for (var i = 0; i < Debugger.all.length; i++)
- {
- var dbg = Debugger.all [i];
- if (dbg.target == target && dbg.engine == engine)
- return dbg;
- }
- return null;
- }
-
- // Check for any open debug session. If found, ask the user
- // if it is OK to stop debugging, and, if so, terminate debugging.
-
- Debugger.queryExit = function()
- {
- for (var i = 0; i < Debugger.all.length; i++)
- {
- var dbg = Debugger.all [i];
- if (dbg.isActive())
- {
- if (!app.shutdown && !queryBox ("$$$/ESToolkit/Alerts/StopDebugging=Stop debugging?"))
- return false;
- else
- break;
- }
- }
- for (i = 0; i < Debugger.all.length; i++)
- {
- var dbg = Debugger.all [i];
- if (dbg.isActive())
- dbg.stop();
- }
- return true;
- }
-
- //////////////////////////////////////////////////////////////////////
- // Methods
-
- // Mark this debugger as being active (i.e. its engine is running)
-
- Debugger.prototype.activate = function()
- {
- if (this != currentDebugger)
- {
- if (currentDebugger)
- {
- currentDebugger.clearProfData();
- // the current debugger for the current target switches
- if (currentDebugger.target == this.target)
- currentDebugger.current = false;
- }
- currentDebugger = this;
- this.current = true;
- this.getScripts();
- this.getVariables (true);
- this.restoreProfData();
- if (this.document)
- this.setDocument (this.document);
- else
- Document.setCurrentLine (null);
- }
- debugMenu.reflectState();
- window.selectAppAndEngine (this.target, this.engine);
- window.setEngineState (this);
- window.running = this.isActive();
- }
-
- // Is this debugger active?
-
- Debugger.prototype.isActive = function()
- {
- return (this.state == Debugger.RUNNING || this.state == Debugger.STOPPED);
- }
-
- // eval the contents of a document in the target engine
-
- Debugger.prototype.start = function (doc, dbgLevel)
- {
- // should not happen
- if (this.isActive())
- return;
-
- // first, check the syntax
- var result = doc.checkSyntax (app.includePath);
- if (result != true)
- {
- window.statusLine = result;
- app.beep();
- return;
- }
-
- // Does the doc contain a #target directive?
- var target = app.scanForTarget (doc.text);
- if (target)
- {
- var displayName = BridgeTalk.getTargetDisplayName (target);
- if (!displayName)
- {
- errorBox ("$$$/ESToolkit/Alerts/CannotConnect=Cannot connect to target %1!", target);
- return;
- }
- else if (!currentDebugger || currentDebugger.target != target)
- {
- // Wrong debugger: if there is only one target engine, auto-switch to that target
- var targetDebugger = null;
- for (var i = 0; i < Debugger.all.length; i++)
- {
- var dbg = Debugger.all [i];
- if (dbg.target == target)
- {
- if (targetDebugger)
- {
- // more than one target: we cannot switch
- targetDebugger = null;
- break;
- }
- targetDebugger = dbg;
- }
- }
- if (targetDebugger)
- {
- if (targetDebugger.connected)
- {
- targetDebugger.activate();
- currentDebugger.start (doc, dbgLevel);
- }
- else
- // this also starts the script
- Debugger.connect (target, doc, dbgLevel);
- }
- else
- Debugger.connect (target, doc, dbgLevel);
- return;
- }
- }
- if (dbgLevel == undefined)
- dbgLevel = 0;
-
- this.profileLevel = prefs.profileLevel;
- if (this.profileLevel)
- documents.clearProfData();
-
- this.setState (Debugger.RUNNING);
- this.error = null;
- this.clearDocuments();
-
- window.statusLine = "";
-
- // send all known breakpoints in case there are pre-loaded scripts
- // documents.sendBP();
-
- var bt = BridgeTalk.create (this.target, "Eval");
- bt.headers.Engine = this.engine;
- bt.headers.DebugLevel = dbgLevel;
- bt.headers.ScriptID = doc.scriptID;
- bt.headers.Profiling = this.profileLevel;
- if (prefs.dontBreakOnErrors)
- bt.headers.DebugFlags = 1024;
- // add the debugger for onResult
- bt.dbg = this;
- bt.onOwnResult = function (bt)
- {
- this.dbg.stop (true);
- // the reply is datatype,result
- var reply = bt.splitBody();
- print (reply [0][1]);
- }
- bt.onOwnError = function (bt)
- {
- this.dbg.stop (true);
- // display the error message
- // if there is no line number and script name info, use an alert
- // but not if the error is "Execution Halted"
- if (!bt.headers.ScriptID && !bt.headers.Line && bt.headers ["Error-Code"] != -34)
- errorBox (bt.body);
- }
- // send the text if the doc is modified or out of sync with the disk image
- if (doc.modified || doc.outOfSync)
- bt.body = doc.text;
-
- // set up all breakpoints for this document
- doc.attachBP (bt);
- bt.safeSend();
-
- // show that this debugger is active
- this.activate();
- }
-
- // Stop debugging. Get the final profiling data, the final variables,
- // and clear the stack trace display.
-
- Debugger.prototype.stop = function (dontHalt)
- {
- // halt the engine
- if (this.isActive())
- {
- if (!dontHalt)
- this.execute ("Halt");
- }
- if (this.profileLevel)
- this.getProfData (true);
- this.setStoppedState();
-
- // no stack display
- window.stack.clear();
- this.getVariables (true);
- }
-
- // Set the state of the debugger with reflection into the UI.
-
- Debugger.prototype.setState = function (state)
- {
- // cannot set a state of Inactive if the engine is in Waiting state
- if (this.waiting && state == Debugger.INACTIVE)
- state = Debugger.WAITING;
- this.state = state;
- if (this == currentDebugger)
- {
- window.setEngineState (this);
- debugMenu.reflectState();
- }
- }
-
- // Put this debugger into a stopped state without sending any messages.
-
- Debugger.prototype.setStoppedState = function()
- {
- if (currentDebugger == this)
- window.running = false;
- this.setState (Debugger.INACTIVE);
- this.error = null;
- this.clearDocuments();
- Document.setCurrentLine (null);
- }
-
- // Get a list of editable scripts from the target and populate the Scripts pane
-
- Debugger.prototype.getScripts = function()
- {
- window.scripts.getScripts();
- }
-
- // Do a eval of the supplied text without any breakpoints etc.
-
- Debugger.prototype.eval = function (text, noReply)
- {
- // this BridgeTalk instance does not carry any script ID
- var bt = BridgeTalk.create (this.target, "Eval");
- bt.headers.Profiling = this.profileLevel;
- bt.headers.Engine = this.engine;
- bt.body = text;
- bt.dbg = this;
- bt.noReply = noReply;
- bt.onResult = function (bt)
- {
- // the reply is datatype,result
- if (!this.noReply)
- {
- var reply = bt.splitBody();
- print (localize ("$$$/ESToolkit/Panes/Console/Result=Result:"), ' ', reply [0][1]);
- }
- this.dbg.getVariables();
- this.destroy();
- }
- bt.onOwnError = function (bt)
- {
- // the reply is the message
- print (localize ("$$$/ESToolkit/Panes/Console/Error=Error:"), ' ', bt.body);
- app.beep();
- }
- bt.safeSend();
- }
-
- // Get the variables of the current scope.
-
- Debugger.prototype.getVariables = function (all)
- {
- // get only for engines that are either not dynamic, or that are active
- if (!this.dynamic || this.state != Debugger.INACTIVE)
- window.variables.getVariables (this.target, this.engine, (this.state == Debugger.STOPPED) ? "" : "$.global", all);
- else
- window.variables.clear();
- }
-
- // Get the profiling data of this execution.
-
- Debugger.prototype.getProfData = function (erase)
- {
- if (!this.profileLevel)
- return;
- var bt = BridgeTalk.create (this.target, "ProfilerData");
- bt.headers.Engine = this.engine;
- if (erase)
- bt.headers.Clear = "1";
- bt.dbg = this;
- bt.onOwnResult = function (bt)
- {
- if (this.dbg.profileLevel)
- {
- var docObj = null;
- var prevScriptID = null;
-
- var reply = bt.splitBody();
- for (var i = 0; i < reply.length; i++)
- {
- // line, time, hits, function, module
- var line = +reply [i][0];
- var time = +reply [i][1];
- var hits = +reply [i][2];
- // var func = reply [i][3];
- var scriptID = reply [i][4];
- // this is only transmitted on change
- if (scriptID)
- {
- // get that doc
- if (!docObj || prevScriptID != scriptID)
- {
- docObj = this.dbg.documents [scriptID];
- if (!docObj)
- {
- doc = documents.find (scriptID);
- if (!doc)
- continue; // doc seems to be closed already
- docObj = this.dbg.documents [scriptID] = { document:doc, line:-1 };
- }
- // set the profiler data for the previous doc
- if (prevScriptID)
- this.dbg.restoreProfData (prevScriptID);
- prevScriptID = scriptID;
- }
- }
- if (docObj)
- {
- if (!docObj.profData)
- docObj.profData = new ProfilerData;
- docObj.profData.add (line, hits, time);
- }
- }
- // show for the last doc
- if (prevScriptID)
- this.dbg.restoreProfData (prevScriptID);
- }
- }
- bt.safeSend();
- }
-
- // Clear the profiling data for this debugger during deactivation.
- // If the script ID is given, just restore the data for the given document.
-
- Debugger.prototype.clearProfData = function (scriptID)
- {
- if (this.profileLevel)
- {
- if (scriptID)
- {
- // for a specific document
- var docObj = this.documents [scriptID];
- if (docObj)
- docObj.document.clearProfData();
- }
- else
- {
- for (var scriptID in this.documents)
- this.clearProfData (scriptID);
- }
- }
- }
-
- // Restore the code profiler data for this debugger during activation.
- // If the script ID is given, just restore data for the given document.
-
- Debugger.prototype.restoreProfData = function (scriptID)
- {
- if (this.profileLevel)
- {
- if (scriptID)
- {
- // for a specific document
- var docObj = this.documents [scriptID];
- if (docObj)
- docObj.document.profileData = docObj.profData;
- }
- else
- {
- for (var scriptID in this.documents)
- this.restoreProfData (scriptID);
- }
- }
- }
-
- // Get the help tip text for the given text.
-
- Debugger.prototype.getHelpTip = function (doc, line, text)
- {
- // Can only do help tips if not running
- if (this.dynamic || (this.state != Debugger.RUNNING))
- {
- doc.helpTip = "";
- return;
- }
-
- if (this.error && line == this.line)
- // display the error
- doc.helpTip = this.error;
- else if (text.length && Document.checkSyntax (text) == true)
- {
- // we create a simple Eval command and ignore any errors
- var bt = BridgeTalk.create (this.target, "Eval");
- bt.headers.Engine = this.engine;
- // we want the target to walk the stack until we have a result
- bt.headers.WalkStack = 1;
- // no script ID - we supply the script on the fly
- bt.doc = doc;
- bt.text = text;
- bt.dbg = this;
- // the result handler creates something like 'type name = value'
- // and sets the help tip
- bt.onOwnResult = function (bt)
- {
- // the doc attached to the BridgeTalk instance
- var doc = this.doc;
- if (doc)
- {
- // the reply of eval is datatype,result
- var reply = bt.splitBody();
- var dataType = reply [0][0];
- var result = reply [0][1];
- if (dataType == "Function")
- text = dataType + ' ' + this.text;
- else if (dataType != "undefined")
- {
- if (dataType == "string")
- {
- result = '"' + app.escape (result) + '"';
- // Truncate a string after 20 characters
- if (result.length > 20)
- result = result.substr (0, 20) + '"...';
- }
- text = dataType + ' ' + this.text + ' = ' + result;
- }
- else if (this.text == "undefined")
- text = "";
- doc.helpTip = text;
- }
- }
- // the error handler displays the error
- bt.onOwnError = function (bt)
- {
- // the doc attached to the BridgeTalk instance
- if (this.doc)
- this.doc.helpTip = bt.body;
- }
- bt.body = text;
- bt.safeSend();
- }
- else
- doc.helpTip = "";
- }
-
- // Continue the execution after a breakpoint.
- // If the debugger is inactive, start a session.
-
- Debugger.prototype.doContinue = function (doc, dbgLevel)
- {
- if (dbgLevel == undefined)
- dbgLevel = 1;
-
- window.statusLine = "";
-
- if (this.state == Debugger.RUNNING)
- return;
-
- if (this.state == Debugger.STOPPED)
- {
- // clear the current line
- Document.setCurrentLine (null);
- this.execute ("Continue");
- }
- else
- {
- // execute the given document
- // first, check the syntax
- var result = doc.checkSyntax (app.includePath);
- if (result == true)
- // if OK, send over to the target
- this.start (doc, dbgLevel);
- else
- {
- // otherwise, display the error and beep
- window.statusLine = result;
- app.beep();
- }
- }
- }
-
- // Start/continue debugging by issuing the given command if the debugger is active.
-
- Debugger.prototype.execute = function (cmd)
- {
- if (cmd == "Continue" && this.state != Debugger.STOPPED)
- return;
-
- var bt = BridgeTalk.create (this.target, cmd);
- bt.headers.Engine = this.engine;
- bt.headers.Profiling = this.profileLevel;
- bt.headers.IgnoreErrors = 0;
- if (prefs.dontBreakOnErrors)
- bt.headers.DebugFlags = 1024;
- bt.dbg = this;
- if (this.document) // the doc may not be there if there was a load error
- bt.headers.ScriptID = this.document.scriptID;
-
- // ask whether to clear any runtime error first
- if (cmd != "Halt")
- {
- if (this.error && queryBox ("$$$/ESToolkit/Alerts/ClearErrors=Clear runtime error?"))
- bt.headers.IgnoreErrors = 1;
- if (this.document)
- // re-attach existing breakpoints
- this.document.attachBP (bt);
- }
- this.setState (Debugger.RUNNING);
- this.error = null;
- bt.safeSend();
- // Indicate the execution by switching the document to front
- if (this.document)
- document = this.document;
- }
-
- // Load a script from the target.
-
- Debugger.prototype.loadScript = function (scriptID)
- {
- window.scripts.loadScript (this.target, this.engine, ScriptID,
- BridgeTalk.getTargetDisplayName (this.target), this);
- }
-
- // Scroll the current document to the current line
-
- Debugger.prototype.showNextStatement = function()
- {
- if (this.state == Debugger.STOPPED)
- window.stack.switchToBottom();
- }
-
- // In halt mode, switch to the given stack frame
-
- Debugger.prototype.switchFrame = function (frame)
- {
- var bt = BridgeTalk.create (this.target, "SwitchFrame");
- bt.headers.Engine = this.engine;
- if (this.oldStack)
- frame = window.stack.output.items.length - frame;
- bt.body = frame;
- bt.safeSend();
- }
-
- // Process a received message
-
- Debugger.prototype.processMsg = function (bt)
- {
- switch (bt.headers.Command)
- {
- case "Print": // print msg to console
- window.console.write (bt.body);
- break;
- case "Breakpoints": // list of moved or removed breakpoints
- var doc = documents.find (bt.headers.ScriptID);
- if (doc)
- doc.updateBP (bt);
- break;
- case "Error": // runtime error
- this.error = bt.headers.ErrorMessage.replace (/\n/g, " ");
- print (this.error);
- // if the debugger is active, this is a halt at a throw
- if (this.state == Debugger.RUNNING && bt.headers.ErrorCode == 54)
- this.error = localize ("$$$/ESToolkit/Messages/ExceptionThrown=JavaScript exception thrown");
- window.statusLine = this.error;
- // fall thru
- case "Break": // breakpoint hit
- case "Frame": // stack frame changed
- app.toFront();
- this.setState (Debugger.STOPPED);
- window.running = true;
- this.line = parseInt (bt.headers.CurrentLine) - parseInt (bt.headers.FirstLine);
- this.frame = parseInt (bt.headers.Frame);
- var frames = parseInt (bt.headers.Frames);
- var source = null;
-
- if (bt.headers.Command != "Frame")
- {
- // the body contains the stack trace, a newline, and the source
- var srcStart = bt.body.indexOf ("\n\n");
- var stackTrace = bt.body;
- if (srcStart >= 0)
- {
- stackTrace = bt.body.substr (0, srcStart + 1);
- source = bt.body.substr (srcStart + 2);
- }
- window.stack.update (stackTrace);
- }
- // set up the document
- var doc = this.document;
- if (!doc || doc.scriptID != bt.headers.ScriptID)
- {
- doc = documents.find (bt.headers.ScriptID);
- if (doc)
- {
- // we have the doc on display; make sure it displays the right thing
- if (source && doc.text != source)
- {
- doc.savedText = doc.text;
- doc.text = source;
- window.breakpoints.update();
- }
- }
- else
- {
- // no doc yet - it came from the target
- if (source) // supplied by break
- {
- doc = Document.create (this.title, source, bt.headers.ScriptID);
- }
- else
- {
- // no source supplied (pre-x41): set off an async get script request
- window.scripts.loadScript (bt.headers.ScriptID);
- // may be there already...
- doc = documents.find (bt.headers.ScriptID);
- }
- }
- }
- if (doc)
- this.setDocument (doc);
- // Get local variables
- this.getVariables (true);
- // and get the profiler data
- if (this.profileLevel)
- this.getProfData (false);
- // execute a delayed toFront to avoid a deadlock
- app.scheduleTask ("app.toFront()", 1, false);
- break;
-
- case "Exit":
- this.stop (true);
- break;
- }
- }
-
- // Set the current document and highlighting.
-
- Debugger.prototype.setDocument = function (doc)
- {
- var color = Debugger.STACK_COLOR;
- var errorMsg = "";
- if (this.frame == 0)
- {
- color = Debugger.CURRENT_COLOR;
- if (this.error)
- {
- color = Debugger.ERROR_COLOR;
- errorMsg = this.error;
- app.beep();
- }
- }
- window.statusLine = errorMsg;
-
- Document.setCurrentLine (doc, this.line, color);
- // scroll to that line
- doc.setSelection (doc.lineToOffset (this.line), 0, true);
- // Add the doc to my documents list if not present
- var docObj = this.documents [doc.scriptID];
- if (!docObj)
- this.documents [doc.scriptID] = docObj = { document:doc, profData:null };
- // bring the document to front
- if (this.document != doc)
- this.document = doc;
- if (doc)
- document = doc;
- }
-
- // Remove a document from the debugger because it is about to being closed.
-
- Debugger.prototype.closeDocument = function (doc)
- {
- delete this.documents [doc.scriptID];
- if (this.document == doc)
- this.document = null;
- }
-
- // Check if the given document is actively being debugged.
-
- Debugger.prototype.isDocumentActive = function (doc)
- {
- return (this.isActive()
- && this.documents [doc.scriptID]
- && (this.documents [doc.scriptID].document == doc));
- }
-
- // Erase all documents.
-
- Debugger.prototype.clearDocuments = function()
- {
- this.document =
- this.lines = null;
- // restore any saved text
- for (var scriptID in this.documents)
- {
- var doc = this.documents [scriptID].document;
- if (doc)
- {
- // THIS IS A TEMP FIX: check the current text for containing
- // an included file. Only then it is necessary to reload the doc
- // after a debug session.
- var text = doc.text;
- doc.containsInclude = (text.indexOf ("// +++++ #include ") >= 0
- && text.indexOf ("// ----- #include ") > 0);
- if (doc.savedText)
- {
- // the doc was here before any break/error occured
- // restore the saved text if different
- if (text != doc.savedText)
- {
- doc.text = doc.savedText;
- window.breakpoints.update();
- }
- delete doc.savedText;
- }
- else
- {
- // the doc arrived via a break/error
- if (doc.containsInclude)
- // need to grab the original document
- window.scripts.loadScript (doc.scriptID);
- }
- }
- }
- this.documents = {};
- }
-