From e53717973462337fae073fbcdf467c75e6a6ee24 Mon Sep 17 00:00:00 2001 From: axelcl Date: Mon, 10 Oct 2005 16:54:44 +0000 Subject: [PATCH 01/16] Renamed 'PHP Application' to 'PHP DBG Script' --- .../plugin.properties | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/net.sourceforge.phpeclipse.launching/plugin.properties b/net.sourceforge.phpeclipse.launching/plugin.properties index 973f149..61ea781 100644 --- a/net.sourceforge.phpeclipse.launching/plugin.properties +++ b/net.sourceforge.phpeclipse.launching/plugin.properties @@ -1,3 +1,2 @@ - Plugin.name=PHPEclipse Launching Support -LaunchConfigurationTypePHPApplication.name=PHP Application \ No newline at end of file +LaunchConfigurationTypePHPApplication.name=PHP DBG Script \ No newline at end of file -- 1.7.1 From f52a63f74a290ac3861824095fd1a6e9e0165189 Mon Sep 17 00:00:00 2001 From: axelcl Date: Mon, 10 Oct 2005 19:03:15 +0000 Subject: [PATCH 02/16] Preferencedialog for "Mark Occurrences" --- net.sourceforge.phpeclipse/plugin.properties | 3 +- net.sourceforge.phpeclipse/plugin.xml | 7 + .../MarkOccurrencesConfigurationBlock.java | 246 ++++++++++++++++++++ .../preferences/MarkOccurrencesPreferencePage.java | 60 +++++ .../ui/preferences/PreferencesMessages.properties | 35 ++-- 5 files changed, 333 insertions(+), 18 deletions(-) create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/MarkOccurrencesConfigurationBlock.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/MarkOccurrencesPreferencePage.java diff --git a/net.sourceforge.phpeclipse/plugin.properties b/net.sourceforge.phpeclipse/plugin.properties index 4e2f6b2..87909f1 100644 --- a/net.sourceforge.phpeclipse/plugin.properties +++ b/net.sourceforge.phpeclipse/plugin.properties @@ -40,6 +40,7 @@ todoTaskPrefName= Task Tags templatePageName= Templates spellingPrefName= Spelling codeAssistPageName= Code Assist +editorMarkOccurrencesPage= Mark Occurrences # # Extension point names @@ -374,7 +375,7 @@ OccurrenceAnnotation.label= PHP Marker Occurrences phpEditorFontDefiniton.label= PHP Editor Text Font phpEditorFontDefintion.description= The PHP editor text font is used by PHP editors. -#--- filter +#--- filter HideImportDeclaration.label= Import declarations HideImportDeclaration.description= Hides all import declarations diff --git a/net.sourceforge.phpeclipse/plugin.xml b/net.sourceforge.phpeclipse/plugin.xml index 0e77cc1..42ac482 100644 --- a/net.sourceforge.phpeclipse/plugin.xml +++ b/net.sourceforge.phpeclipse/plugin.xml @@ -1362,6 +1362,13 @@ class="net.sourceforge.phpdt.internal.ui.preferences.SpellingPreferencePage" id = "net.sourceforge.phpdt.internal.ui.preferences.SpellingPreferencePage"> + + + + + + + + + @@ -28,6 +35,7 @@ + @@ -37,74 +45,65 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - + + + + @@ -113,17 +112,17 @@ - - + + - + - + @@ -139,11 +138,11 @@ - - + + - + @@ -152,28 +151,28 @@ - - - + + + - - + + - - + + - + @@ -191,7 +190,7 @@ - + diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGBase.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGBase.java index f72c52a..f814943 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGBase.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGBase.java @@ -14,56 +14,56 @@ public class PHPDBGBase { // Constants // php-engine commands/events - public static final int DBGC_REPLY = 0x0000; /* reply to previous DBGA_REQUEST request */ - public static final int DBGC_STARTUP = 0x0001; /* script startup */ - public static final int DBGC_END = 0x0002; /* script done */ - public static final int DBGC_BREAKPOINT = 0x0003; /* user definded breakpoint occured */ - public static final int DBGC_STEPINTO_DONE = 0x0004; /* step to the next statement is completed */ - public static final int DBGC_STEPOVER_DONE = 0x0005; /* step to the next statement is completed */ - public static final int DBGC_STEPOUT_DONE = 0x0006; /* step to the next statement is completed */ - public static final int DBGC_EMBEDDED_BREAK = 0x0007; /* breakpoint caused by DebugBreak() function */ - public static final int DBGC_ERROR = 0x0010; /* error occured */ - public static final int DBGC_LOG = 0x0011; /* logging support */ - public static final int DBGC_SID = 0x0012; /* send SID */ - public static final int DBGC_PAUSE = 0x0013; /* pause current session as soon as possible */ - - public static final char[] DBGA_CONTINUE = IntToChar4(0x8001); /* php should continue run */ - public static final char[] DBGA_STOP = IntToChar4(0x8002); - public static final char[] DBGA_STEPINTO = IntToChar4(0x8003); - public static final char[] DBGA_STEPOVER = IntToChar4(0x8004); - public static final char[] DBGA_STEPOUT = IntToChar4(0x8005); - public static final char[] DBGA_IGNORE = IntToChar4(0x8006); - public static final char[] DBGA_REQUEST = IntToChar4(0x8010); /* debugger client requests some information from PHP engine */ - - public static final int FRAME_STACK = 100000; /* "call:stack" - e.g. backtrace */ - public static final int FRAME_SOURCE = 100100; /* source text */ - public static final int FRAME_SRC_TREE = 100200; /* tree of source files */ - public static final int FRAME_RAWDATA = 100300; /* raw data or string */ - public static final int FRAME_ERROR = 100400; /* error notification */ - public static final int FRAME_EVAL = 100500; /* evaluating/watching */ - public static final int FRAME_BPS = 100600; /* set/remove breakpoint */ - public static final int FRAME_BPL = 100700; /* breakpoint(s) request = get the list */ - public static final int FRAME_VER = 100800; /* version request */ - public static final int FRAME_SID = 100900; /* session id info*/ - public static final int FRAME_SRCLINESINFO = 101000; /* source lines info */ - public static final int FRAME_SRCCTXINFO = 101100; /* source contexts info */ - public static final int FRAME_LOG = 101200; /* logging */ - public static final int FRAME_PROF = 101300; /* profiler */ - public static final int FRAME_PROF_C = 101400; /* profiler counter/accuracy */ - public static final int FRAME_SET_OPT = 101500; /* set/update options */ - - public static final char[] DBGSYNC = { 0, 0, (char) 89, (char) 83}; /* DBG syncronization chars */ + public static final int DBGC_REPLY = 0x0000; // reply to previous DBGA_REQUEST request + public static final int DBGC_STARTUP = 0x0001; // script startup + public static final int DBGC_END = 0x0002; // script done + public static final int DBGC_BREAKPOINT = 0x0003; // user definded breakpoint occured + public static final int DBGC_STEPINTO_DONE = 0x0004; // step to the next statement is completed + public static final int DBGC_STEPOVER_DONE = 0x0005; // step to the next statement is completed + public static final int DBGC_STEPOUT_DONE = 0x0006; // step to the next statement is completed + public static final int DBGC_EMBEDDED_BREAK = 0x0007; // breakpoint caused by DebugBreak() function + public static final int DBGC_ERROR = 0x0010; // error occured + public static final int DBGC_LOG = 0x0011; // logging support + public static final int DBGC_SID = 0x0012; // send SID + public static final int DBGC_PAUSE = 0x0013; // pause current session as soon as possible + + public static final char[] DBGA_CONTINUE = IntToChar4(0x8001); // php should continue run + public static final char[] DBGA_STOP = IntToChar4(0x8002); + public static final char[] DBGA_STEPINTO = IntToChar4(0x8003); + public static final char[] DBGA_STEPOVER = IntToChar4(0x8004); + public static final char[] DBGA_STEPOUT = IntToChar4(0x8005); + public static final char[] DBGA_IGNORE = IntToChar4(0x8006); + public static final char[] DBGA_REQUEST = IntToChar4(0x8010); // debugger client requests some information from PHP engine + + public static final int FRAME_STACK = 100000; // "call:stack" - e.g. backtrace + public static final int FRAME_SOURCE = 100100; // source text + public static final int FRAME_SRC_TREE = 100200; // tree of source files + public static final int FRAME_RAWDATA = 100300; // raw data or string + public static final int FRAME_ERROR = 100400; // error notification + public static final int FRAME_EVAL = 100500; // evaluating/watching + public static final int FRAME_BPS = 100600; // set/remove breakpoint + public static final int FRAME_BPL = 100700; // breakpoint(s) request = get the list + public static final int FRAME_VER = 100800; // version request + public static final int FRAME_SID = 100900; // session id info + public static final int FRAME_SRCLINESINFO = 101000; // source lines info + public static final int FRAME_SRCCTXINFO = 101100; // source contexts info + public static final int FRAME_LOG = 101200; // logging + public static final int FRAME_PROF = 101300; // profiler + public static final int FRAME_PROF_C = 101400; // profiler counter/accuracy + public static final int FRAME_SET_OPT = 101500; // set/update options + + public static final char[] DBGSYNC = { 0, 0, (char) 89, (char) 83}; // DBG syncronization chars // Session Types - public static final int DBG_COMPAT = 0x0001; - public static final int DBG_JIT = 0x0002; - public static final int DBG_REQ = 0x0003; - public static final int DBG_EMB = 0x0004; - - public static final int BPS_DELETED = 0; - public static final int BPS_DISABLED = 1; - public static final int BPS_ENABLED = 2; - public static final int BPS_UNRESOLVED = 0x100; + public static final int DBG_COMPAT = 0x0001; + public static final int DBG_JIT = 0x0002; + public static final int DBG_REQ = 0x0003; + public static final int DBG_EMB = 0x0004; + + public static final int BPS_DELETED = 0; + public static final int BPS_DISABLED = 1; + public static final int BPS_ENABLED = 2; + public static final int BPS_UNRESOLVED = 0x100; public static final int E_ERROR = (1<<0L); public static final int E_WARNING = (1<<1L); @@ -80,58 +80,115 @@ public class PHPDBGBase { public PHPDBGBase() { } - public static void copyCharsTo(char[] to, char[] from, int bytes, int tostart) { + + /** + * Copies the number of bytes from a source buffer to a destination buffer + * Destination index starts with 0 + tostart, + * and source index starts with 0. + * + * @param to The destination buffer. + * @param from The source buffer. + * @param bytes The number of bytes which are to copy. + * @param tostart The start index for the destination buffer. + */ + public static void copyCharsTo (char[] to, char[] from, int bytes, int tostart) { int i; - for(i=0; i < bytes; i++) to[i + tostart]= from[i]; + + for (i = 0; i < bytes; i++) { // For the number of bytes which are to copy + to[i + tostart] = from[i]; // Copy from destination to source (+startindex) + } } - public static void copyChars(char[] to, char[] from, int bytes) { - copyCharsTo(to, from, bytes, 0); + /** + * Copies the number of bytes from a source buffer to a destination buffer + * Destination index starts with 0, + * and source index starts with 0. + * + * @param to The destination buffer. + * @param from The source buffer. + * @param bytes The number of bytes which are to copy. + */ + public static void copyChars (char[] to, char[] from, int bytes) { + copyCharsTo (to, from, bytes, 0); } - public static int Char4ToInt(char[] ch, int startPos) { - int pos=startPos, ret=0; - - ret += CharToInt(ch[pos++]) << 24; - ret += CharToInt(ch[pos++]) << 16; - ret += CharToInt(ch[pos++]) << 8; - ret += CharToInt(ch[pos++]) << 0; + /** + * Converts a four chars big endian value into + * an integer value + * + * @param ch The buffer which contains the four chars which are to convert. + * @param startPos The start position (of the four bytes) within the buffer. + */ + public static int Char4ToInt (char[] ch, int startPos) { + int pos = startPos; + int ret = 0; + + ret += CharToInt (ch[pos++]) << 24; + ret += CharToInt (ch[pos++]) << 16; + ret += CharToInt (ch[pos++]) << 8; + ret += CharToInt (ch[pos++]) << 0; + return ret; } - public static int CharToInt(char ch) { + /** + * @return The character which is converted to an integer value. + */ + public static int CharToInt (char ch) { return (int) (ch & 0x00FF); } - public static char[] IntToChar4(int num) { - char[] ret= new char[4]; - + /** + * Converts an integer value into a four char big endian number + * + * @param num The integer value which is to convert to a four char big endian number. + * @return The four byte buffer with the big endian number. + */ + public static char[] IntToChar4 (int num) { + char[] ret = new char[4]; + ret[0] = (char) ((num >> 24) & 0x00FF); ret[1] = (char) ((num >> 16) & 0x00FF); - ret[2] = (char) ((num >> 8) & 0x00FF); - ret[3] = (char) ((num >> 0) & 0x00FF); + ret[2] = (char) ((num >> 8) & 0x00FF); + ret[3] = (char) ((num >> 0) & 0x00FF); return ret; } - public static String CharArrayToString(char[] cha) { - String ret= new String(); - int i, p; - - for(i=0; i < cha.length; i++) { - p= (int) cha[i]; - ret= ret + "(" + String.valueOf(p) + ") "; + /** + * Converts the chars of an array into a string in form of + * (byte value string) (byte value string) (byte value string) ... + * + * @param cha The input buffer which contains the chars which are to convert. + * @return The string which contains the bytes as strings. + * E.g.: (123) (11) (46) (213) ... + */ + public static String CharArrayToString (char[] cha) { + String ret = new String (); + int i; + int p; + + for (i = 0; i < cha.length; i++) { // For all bytes within the input buffer + p = (int) cha[i]; // Convert the byte into an integer value + ret = ret + "(" + String.valueOf (p) + ") "; // Add the value } + return ret; } - - public static byte[] CharArrayToByteArray(char[] cha) { - byte[] ret= new byte[cha.length]; - int i; - - for(i=0; i < cha.length; i++) { - ret[i]= (byte) cha[i]; + + /** + * + * @param cha The input buffer which contains the chars which are to convert. + * @return The byte array which contains the converted chars. + */ + public static byte[] CharArrayToByteArray (char[] cha) { + byte[] ret = new byte[cha.length]; // The resulting byte array + int i; // The index for the buffers + + for (i = 0; i < cha.length; i++) { // For all chars within the input buffer + ret[i] = (byte) cha[i]; // Convert the character to a byte and store to buffer } - return ret; + + return ret; // Return the byte array } } diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGFrame.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGFrame.java index 6e9b777..15b1ffb 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGFrame.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGFrame.java @@ -14,67 +14,114 @@ import java.util.Vector; public class PHPDBGFrame { - public static final int FRAME_HEADER_SIZE= 8; - private char[] frameType= new char[4]; - private Vector frameData= new Vector(); - private int frameSize= 0; - - public PHPDBGFrame(int frameType) { - this.frameType= PHPDBGBase.IntToChar4(frameType); - frameSize+= FRAME_HEADER_SIZE; + public static final int FRAME_HEADER_SIZE = 8; // Header consist of 4 byte frame type and 4 byte frame length + private char[] frameType = new char[4]; + private Vector frameData = new Vector (); + private int frameSize = 0; + + /** + * Construct a new frame. + * + * @param frameType The type of the frame which is created. + */ + public PHPDBGFrame (int frameType) { + this.frameType = PHPDBGBase.IntToChar4 (frameType); + frameSize += FRAME_HEADER_SIZE; } - - public void addInt(int num) { - char[] newData= PHPDBGBase.IntToChar4(num); - frameData.add(newData); - frameSize+= 4; + + /** + * Add an integer to the frame. + * + * @param num + */ + public void addInt (int num) { + char[] newData = PHPDBGBase.IntToChar4 (num); // Convert the integer to four bytes big endian + frameData.add (newData); // Add the four bytes to the frame data + frameSize += 4; // Calculate the new fram size } - public void addChar(char ch) { - char[] newData= new char[1]; - newData[0]= ch; - frameData.add(newData); - frameSize+= 1; + /** + * Add a character to the frame. + * + * @param ch The character which is to add to the frame. + */ + public void addChar (char ch) { + char[] newData = new char[1]; + + newData[0] = ch; // + frameData.add (newData); // Add the character to the frame data + frameSize += 1; // Calculate the new fram size } - public void addString(String str) { - frameData.add(str); - frameSize+= str.length(); + /** + * @param str + */ + public void addString (String str) { + frameData.add (str); + frameSize += str.length (); } - public int getSize() { + /** + * Get the size of the frame, including the frame header. + * + * @return The size of the entire frame. + */ + public int getSize () { return frameSize; } - public int getSizeOfData() { + /** + * Return the size of the frame, which is the number of all bytes + * without the 8 byte from frame header. + * + * @return The size of the frame (without the frame header). + */ + public int getSizeOfData () { return frameSize - FRAME_HEADER_SIZE; } - public char[] getHeader() { - char[] ret= new char[FRAME_HEADER_SIZE]; + /** + * Get the header of this frame. + * + * @return The eight char array which forms the header of this frame. + */ + public char[] getHeader () { + char[] ret = new char[FRAME_HEADER_SIZE]; // Allocate 8 chars for the header - PHPDBGBase.copyChars(ret, frameType, 4); - PHPDBGBase.copyCharsTo(ret, PHPDBGBase.IntToChar4(getSizeOfData()), 4, 4); - return ret; + PHPDBGBase.copyChars (ret, frameType, 4); // The first four chars are the frame type + PHPDBGBase.copyCharsTo (ret, PHPDBGBase.IntToChar4 (getSizeOfData ()), 4, 4); // The second four chars is for the size of the data area + + return ret; // Return the header } - - public char[] getFrameData() { - char[] ret= new char[getSizeOfData()]; - int i, pos= 0; - - for(i=0; i < frameData.size(); i++) { - if(frameData.get(i).getClass().getName().equals("[C")) { - char[] conv= (char[])frameData.get(i); - PHPDBGBase.copyCharsTo(ret, conv, conv.length, pos); - pos+= conv.length; + + /** + * Get the data array of this frame + * + * TODO Finish commenting + * + * @return The char array which holds the data of this frame. + */ + public char[] getFrameData () { + char[] ret = new char[getSizeOfData ()]; // The frame data (data without the frame header) + int pos = 0; // The current position for the 'ret' array + int i; // The current position for the frame data list + + for (i = 0; i < frameData.size (); i++) { // For frame data entries within the list + if (frameData.get (i).getClass ().getName ().equals ("[C")) { // What kind of type is the frame data + char[] conv = (char[]) frameData.get (i); // + + PHPDBGBase.copyCharsTo (ret, conv, conv.length, pos); // + pos += conv.length; } else { - if(frameData.get(i).getClass().getName().equals("java.lang.String")) { - String conv= (String)frameData.get(i); - PHPDBGBase.copyCharsTo(ret, conv.toCharArray(), conv.length(), pos); - pos+= conv.length(); + if (frameData.get (i).getClass ().getName ().equals ("java.lang.String")) { // + String conv = (String) frameData.get (i); // + + PHPDBGBase.copyCharsTo (ret, conv.toCharArray (), conv.length (), pos); // + pos += conv.length (); // } } } - return ret; + + return ret; // Return the data frame array } -} \ No newline at end of file +} diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java index ef96492..957c86e 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java @@ -19,262 +19,510 @@ import java.util.Vector; import net.sourceforge.phpdt.internal.debug.core.model.PHPDBGEvalString; import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame; import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable; +import net.sourceforge.phpdt.internal.debug.core.model.PHPValue; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugException; +import java.io.RandomAccessFile; + +/** + * The interface object are created by the proxy + * + */ public class PHPDBGInterface { - // Public - public boolean sessionEnded= false; - public int sessType= -1; - public int BPUnderHit= 0; - public String sessID= new String(); - - // Private - private int[] LastBPRead= new int[10]; - private Vector DBGBPList= new Vector(); - private PHPStackFrame[] DBGStackList; - private PHPVariable[] DBGVariableList; - private Vector DBGMods= new Vector(); - private BufferedReader in; - private OutputStream os; - private boolean shouldStop= false; - private String evalRet= new String(""); - private String serGlobals= new String(""); - private int rawCounter=1000; - private PHPDBGProxy proxy= null; + public boolean sessionEnded = false; + public int sessType = -1; + public int BPUnderHit = 0; + public String sessID = new String (); - private int lastCmd=-1; - private int sid=0; - private boolean stopOnError= false; - private char[] lastCommand= new char[4]; - - public PHPDBGInterface(BufferedReader in, OutputStream os, PHPDBGProxy proxy) { - DBGBPList.clear(); - this.in= in; - this.os= os; - this.proxy= proxy; + private int[] LastBPRead = new int[10]; + private Vector DBGBPList = new Vector (); + private Vector DBGVarList = new Vector (); + private PHPStackFrame[] DBGStackList; + private Vector DBGMods = new Vector (); // The module names and their numbers + private Vector stackListOld = new Vector (); + private BufferedReader in; + private OutputStream os; // The stream which goes to DBG + private boolean shouldStop = false; + private String evalRet = new String (""); + private String serGlobals = new String (""); + private int rawCounter = 1000; // An rawData frame ID counter + private PHPDBGProxy proxy = null; + private int lastCmd = -1; + private int sid = 0; + private boolean stopOnError = false; + private char[] lastCommand = new char[4]; + + /** + * @param in The input stream (communication from DBG). + * @param os The output stream (communication to DBG). + * @param proxy The proxy to which this interface belongs. + */ + public PHPDBGInterface (BufferedReader in, OutputStream os, PHPDBGProxy proxy) { + DBGBPList.clear (); + + this.in = in; + this.os = os; + this.proxy = proxy; } - public int addBreakpoint(String mod_name, int line) throws IOException { - return setBreakpoint(mod_name, "", line, PHPDBGBase.BPS_ENABLED + PHPDBGBase.BPS_UNRESOLVED, 0, 0, 0, 0, 0); + /** + * + * @param mod_name The module (source file) to which we add the breakpoint. + * @param line The line where the breakpoint is set. + * @return Breakpoint ID ???. + */ + public int addBreakpoint (String mod_name, int line) throws IOException { + return setBreakpoint (mod_name, "", line, PHPDBGBase.BPS_ENABLED + PHPDBGBase.BPS_UNRESOLVED, 0, 0, 0, 0, 0); } - public void removeBreakpoint(String mod_name, int line, int bpNo) throws IOException { - setBreakpoint(mod_name, "", line, PHPDBGBase.BPS_DISABLED, 0, 0, 0, bpNo, 0); + /** + * + * @param mod_name The module (source file) to which we add the breakpoint. + * @param line The line where the breakpoint is set. + * @param bpNo The breakpoint ID ???. + */ + public void removeBreakpoint (String mod_name, int line, int bpNo) throws IOException { + setBreakpoint (mod_name, "", line, PHPDBGBase.BPS_DISABLED, 0, 0, 0, bpNo, 0); } - public void requestDBGVersion() throws IOException { - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST); - PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_VER); - - DBGPacket.addFrame(DBGFrame); + /** + * Is this method used anywhere? + * + */ + public void requestDBGVersion () throws IOException { + PHPDBGPacket DBGPacket; // A DBG message packet + PHPDBGFrame DBGFrame; // A frame within a DBG packet - if(proxy.getSocket().isClosed()) return; - DBGPacket.sendPacket(os); - } + DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST); // A request for DBG + DBGFrame = new PHPDBGFrame (PHPDBGBase.FRAME_VER); // We want the version of DBG - public void getSourceTree() throws IOException { - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST); - PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_SRC_TREE); - - DBGPacket.addFrame(DBGFrame); - - if(proxy.getSocket().isClosed()) return; - DBGPacket.sendPacket(os); + DBGPacket.addFrame (DBGFrame); // Add the 'what we want' to the DBG packet - // Wait response (1 second) and read response - waitResponse(1000); - flushAllPackets(); + if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG? + return; // No + } + + DBGPacket.sendPacket (os); // Send the request to DBG } - public void addDBGModName(String modName) throws IOException { - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST); - PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA); - - rawCounter++; - DBGFrame.addInt(rawCounter); // FRAME_RAWDATA ID - DBGFrame.addInt(modName.length() + 1); // length of rawdata (+ null char) - DBGFrame.addString(modName); // file name - DBGFrame.addChar('\0'); // null char + /** + * Called by the proxy + * + */ + public void getSourceTree () throws IOException { + PHPDBGPacket DBGPacket; // A DBG message packet + PHPDBGFrame DBGFrame; // A frame within a DBG packet - DBGPacket.addFrame(DBGFrame); - - if(proxy.getSocket().isClosed()) return; - DBGPacket.sendPacket(os); + DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST); // A request for DBG + DBGFrame = new PHPDBGFrame (PHPDBGBase.FRAME_SRC_TREE); // We want a source tree from DBG + + DBGPacket.addFrame (DBGFrame); // Add the 'what we want' to the DBG packet + + if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG? + return; // No + } + + DBGPacket.sendPacket (os); // Send the request to DBG + + waitResponse (1000); // Wait for the DBG response (1 second) + flushAllPackets (); // Read and process the response from DBG } - // Returns DBG Breakpoint ID - private int setBreakpoint(String mod_name, String condition, int line, int state, int istemp, int hitcount, int skiphits, int bpno, int isunderhit) throws IOException { - int modNo= 0; + /** + * Is this method called from anywhere? + * + * @param modName The modul (filename). + */ + public void addDBGModName (String modName) throws IOException { + PHPDBGPacket DBGPacket; // A DBG message packet + PHPDBGFrame DBGFrame; // A frame within a DBG packet - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST); - PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_BPS); - PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA); + DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST); // A request for DBG + DBGFrame = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA); // We want Module name from DBG + + rawCounter++; // Increment the rawData ID counter + DBGFrame.addInt (rawCounter); // FRAME_RAWDATA ID + DBGFrame.addInt (modName.length () + 1); // The length of rawdata string (incl. null char termination) + DBGFrame.addString (modName); // The file name (module name) + DBGFrame.addChar ('\0'); // Add the C-String null termination + + DBGPacket.addFrame (DBGFrame); + + if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG? + return; // No + } + + DBGPacket.sendPacket (os); + } - modNo= getModByName(mod_name); - - if(modNo >= 0) { - DBGFrame1.addInt(modNo); // mod number + /** + * This method is called for adding or removing breakpoints. + * + * @param mod_name The module name (file name). + * @param condition Info about the condition when to break (not used at the moment). + * @param line The breakpoints line. + * @param state Info whether this breakpoint has to be dis- or enabled. + * @param istep Always 0. + * @param hitcount Always 0. + * @param skiphits Always 0. + * @param bpno The breakpoint ID. + * @param isunderhit ??? + * @return + */ + private int setBreakpoint (String mod_name, String condition, int line, int state, int istemp, int hitcount, int skiphits, int bpno, int isunderhit) throws IOException { + PHPDBGPacket DBGPacket; + PHPDBGFrame DBGFrame1; + PHPDBGFrame DBGFrame2; + int modNo; + + DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST); + DBGFrame1 = new PHPDBGFrame (PHPDBGBase.FRAME_BPS); + DBGFrame2 = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA); + + modNo = getModByName (mod_name); // Get the module ID by name + + if (modNo >= 0) { // Did we find a module ID for the module name? + DBGFrame1.addInt (modNo); // Add the module ID to frame 1 } else { - DBGFrame1.addInt(0); // mod number (0 use file name) + DBGFrame1.addInt (0); // mod number (0 use file name) } - - DBGFrame1.addInt(line); // line number - - if(modNo >= 0) { - DBGFrame1.addInt(0); // use mod number + + DBGFrame1.addInt (line); // line number + + if (modNo >= 0) { // Did we find a module ID for the module name? + DBGFrame1.addInt (0); // use mod number } else { rawCounter++; - DBGFrame1.addInt(rawCounter); // ID of FRAME_RAWDATA to send file name + DBGFrame1.addInt (rawCounter); // ID of FRAME_RAWDATA to send file name } - DBGFrame1.addInt(state); // state BPS_* - DBGFrame1.addInt(istemp); // istemp - DBGFrame1.addInt(hitcount); // hit count - DBGFrame1.addInt(skiphits); // skip hits - DBGFrame1.addInt(0); // ID of condition - DBGFrame1.addInt(bpno); // breakpoint number - DBGFrame1.addInt(isunderhit); // is under hit - - if(modNo < 0) { - DBGFrame2.addInt(rawCounter); // FRAME_RAWDATA ID - DBGFrame2.addInt(mod_name.length() + 1); // length of rawdata (+ null char) - DBGFrame2.addString(mod_name); // file name - DBGFrame2.addChar('\0'); // null char - // First add file name data - DBGPacket.addFrame(DBGFrame2); + DBGFrame1.addInt (state); // state BPS_* + DBGFrame1.addInt (istemp); // istep + DBGFrame1.addInt (hitcount); // hit count + DBGFrame1.addInt (skiphits); // skip hits + DBGFrame1.addInt (0); // ID of condition + DBGFrame1.addInt (bpno); // breakpoint number + DBGFrame1.addInt (isunderhit); // is under hit + + if (modNo < 0) { // Did we find a module ID for the module name? + DBGFrame2.addInt (rawCounter); // FRAME_RAWDATA ID + DBGFrame2.addInt (mod_name.length() + 1); // length of rawdata (+ null char) + DBGFrame2.addString (mod_name); // file name + DBGFrame2.addChar ('\0'); // null char + + DBGPacket.addFrame (DBGFrame2); // First add file name data } - // Second add command data - DBGPacket.addFrame(DBGFrame1); + DBGPacket.addFrame (DBGFrame1); // Second add command data - if(proxy.getSocket().isClosed()) return 0; - DBGPacket.sendPacket(os); + if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG? + return 0; // No + } - clearLastBP(); + DBGPacket.sendPacket (os); // Send the request to DBG - // Wait response (1 second) and read response - waitResponse(1000); - flushAllPackets(); + clearLastBP (); + + waitResponse (1000); // Wait for the DBG response (1 second) + flushAllPackets (); // Read and process the response from DBG - return LastBPRead[8]; + return LastBPRead[8]; // Return what ??? } - private void clearLastBP() { + /** + * + */ + private void clearLastBP () { int i; - for(i=0; i < LastBPRead.length; i++) - LastBPRead[i]= 0; + for (i = 0; i < LastBPRead.length; i++) { + LastBPRead[i] = 0; + } } - private void copyToLastBP(int[] BPBody) { + /** + * + */ + private void copyToLastBP (int[] BPBody) { int i; - for(i=0; i < LastBPRead.length; i++) - LastBPRead[i]= BPBody[i]; + for (i = 0; i < LastBPRead.length; i++) { + LastBPRead[i] = BPBody[i]; + } } - public void continueExecution() throws IOException { - BPUnderHit= 0; - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_CONTINUE); - if(proxy.getSocket().isClosed()) return; - DBGPacket.sendPacket(os); - lastCommand= PHPDBGBase.DBGA_CONTINUE; + /** + * + */ + public void continueExecution () throws IOException { + PHPDBGPacket DBGPacket; + + BPUnderHit = 0; + DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_CONTINUE); + + if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG? + return; // No + } + + DBGPacket.sendPacket (os); // Send the request to DBG + + lastCommand = PHPDBGBase.DBGA_CONTINUE; // Store the info about the command we sent } - public void pauseExecution() throws IOException { - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.IntToChar4(PHPDBGBase.DBGC_PAUSE)); - if(proxy.getSocket().isClosed()) return; - DBGPacket.sendPacket(os); + /** + * + */ + public void pauseExecution () throws IOException { + PHPDBGPacket DBGPacket; + + DBGPacket = new PHPDBGPacket (PHPDBGBase.IntToChar4 (PHPDBGBase.DBGC_PAUSE)); + + if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG? + return; // No + } + + DBGPacket.sendPacket (os); // Send the request to DBG } - private int getBPUnderHit() { - int i, BPUnder=0; - int[] dbg_bpl_body= new int[10]; + /** + * + */ + private int getBPUnderHit () { + int i; + int BPUnder = 0; + int[] dbg_bpl_body = new int[10]; + + for (i = 0; i < DBGBPList.size (); i++) { // look for bp under hit + dbg_bpl_body = (int[]) DBGBPList.get (i); - // look for bp under hit - for(i=0; i < DBGBPList.size(); i++) { - dbg_bpl_body= (int[]) DBGBPList.get(i); - if(dbg_bpl_body[9] == 1) { - BPUnder= dbg_bpl_body[8]; + if (dbg_bpl_body[9] == 1) { + BPUnder = dbg_bpl_body[8]; } } + return BPUnder; } - + public int getLastCmd() { return lastCmd; } - + public int getSID() { return sid; - } - - public void setLastCmd(int cmd) + } + + public void setLastCmd (int cmd) { - lastCmd=cmd; + lastCmd = cmd; } - public void stepInto() throws IOException { - BPUnderHit= 0; - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPINTO); - if(proxy.getSocket().isClosed()) return; - DBGPacket.sendPacket(os); - lastCommand= PHPDBGBase.DBGA_STEPINTO; + /** + * + */ + public void stepInto () throws IOException { + PHPDBGPacket DBGPacket; + + BPUnderHit = 0; + DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_STEPINTO); + + if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG? + return; // No + } + + DBGPacket.sendPacket (os); // Send the request to DBG + + lastCommand = PHPDBGBase.DBGA_STEPINTO; // Store the info about the command we sent } - public void stepOver() throws IOException { - BPUnderHit= 0; - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOVER); - if(proxy.getSocket().isClosed()) return; - DBGPacket.sendPacket(os); - lastCommand= PHPDBGBase.DBGA_STEPOVER; + /** + * + */ + public void stepOver () throws IOException { + PHPDBGPacket DBGPacket; + + BPUnderHit = 0; + DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOVER); + + if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG? + return; // No + } + + DBGPacket.sendPacket (os); // Send the request to DBG + + lastCommand = PHPDBGBase.DBGA_STEPOVER; // Store the info about the command we sent } - public void stepOut() throws IOException { - BPUnderHit= 0; - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOUT); - if(proxy.getSocket().isClosed()) return; - DBGPacket.sendPacket(os); - lastCommand= PHPDBGBase.DBGA_STEPOUT; + /** + * + */ + public void stepOut () throws IOException { + PHPDBGPacket DBGPacket; + + BPUnderHit = 0; + DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOUT); + + if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG? + return; // No + } + + DBGPacket.sendPacket (os); // Send the request to DBG + + lastCommand = PHPDBGBase.DBGA_STEPOUT; // Store the info about the command we sent } - public void stopExecution() throws IOException { - BPUnderHit= 0; - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STOP); - if(proxy.getSocket().isClosed()) return; - DBGPacket.sendPacket(os); + /** + * + */ + public void stopExecution () throws IOException { + PHPDBGPacket DBGPacket; + + BPUnderHit = 0; + DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_STOP); + + if (proxy.getSocket ().isClosed ()) { // Can we communiate with DBG? + return; // No + } + + DBGPacket.sendPacket (os); // Send the request to DBG } - public PHPVariable[] getVariables(PHPStackFrame stack) throws IOException, DebugException { - PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST); - PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL); - - DBGFrame1.addInt(0); // istr = raw data ID - DBGFrame1.addInt(1); // scope_id = -1 means current location, 0 never used, +1 first depth - - // Add command data - DBGPacket.addFrame(DBGFrame1); - - if(proxy.getSocket().isClosed()) return null; - DBGPacket.sendPacket(os); + /** + * This method updates the 'static' variables list. + * It does a replication between the 'static' list (the variable list which + * is a member of this DBG interface object) and the DBG variable list + * (the list of variables which is received from PHP via DBG with the current suspend) + * Replication is done in the following way: + *
    + *
  • It looks for new variables within the DBG variables list and + * adds them to the 'static' list. + *
  • It looks for changed variables copies the current value to the variable within + * the 'static list' and mark these variables as 'hasChanged' (which uses the UI + * for showing the variable with a different color). + *
  • It looks for variables within the 'static' list, and removes them + * from the 'static' list in case the do not appear within the DBG list. + *
+ * + * @param varListOld The 'static' list of variables which are to be updated. + * @param varListNew The new list of (current) variables from DBG. + */ + private void updateVariableList (Vector varListOld, Vector varListNew) + { + PHPVariable varOld; // The variable from the 'static' list + PHPVariable varNew; // The variable from the DBG list + PHPValue valOld; // The value of the current variable from 'static' list + PHPValue valNew; // The value of the current variable from DBG list + int n; // Index for the DBG list + int o; // Index for the static list + + // Add the variables (and childs) to the static list if they are new + // and update the values of variables which are already existend within + // the 'static' list. + + for (n = 0; n < varListNew.size (); n++) { // For every variable in 'DBG list' + varNew = (PHPVariable) varListNew.get (n); // Get the DBG variable + + for (o = 0; o < varListOld.size (); o++) { // For every variable in static list + varOld = (PHPVariable) varListOld.get (o); // Get the static variable + + if (varNew.getName ().equals (varOld.getName ())) { // Did we found the variable within the 'static' list? + valOld = (PHPValue) varOld.getValue (); // Get the value from 'static' + valNew = (PHPValue) varNew.getValue (); // Get the value from DBG + + try { + if (valOld.hasVariables () || // If the 'static' value has child variables + valNew.hasVariables ()) { // or if the DBG value has child variables + updateVariableList (valOld.getChildVariables (), // Update the variable list for the child variables + valNew.getChildVariables ()); + } + else if (!valOld.getValueString ().equals (valNew.getValueString ())) { // Has the value changed? + valOld.setValueString (valNew.getValueString ()); // Yes, set the 'static' value (variable) to the new value + varOld.setValueChanged (true); // and set the 'has changed' flag, so that the variable view + // could show the user the changed status with a different + // color + } + else { + varOld.setValueChanged (false); // Reset the 'has changed' flag + } + } + catch (DebugException e) { // That's, because of the hasVariables method + } - waitResponse(1000); - flushAllPackets(); - - // Process serialized variables - PHPDBGEvalString evalStr=new PHPDBGEvalString(stack,serGlobals); - - DBGVariableList= evalStr.getVars(); + break; // Found the variable, + } + } + + if (o == varListOld.size ()) { // Did we found the variable within the static list? + varListOld.add (varNew); // No, then add the DBG variable to the static list + } + } + + // Look for the variables we can remove from the 'static' list + + for (o = 0; o < varListOld.size (); o++) { // For every variable in 'static' list + varOld = (PHPVariable) varListOld.get (o); // Get the static variable + + for (n = 0; n < varListNew.size (); n++) { // For all variables in 'DBG' list + varNew = (PHPVariable) varListNew.get (n); // Get the variable from the 'DBG' list - return DBGVariableList; + if (varNew.getName ().equals (varOld.getName ())) { // Did we found the 'static' list variable within the 'DBG' list? + break; // Yes we found the variable, then leave the loop + } + } + + if (n == varListNew.size ()) { // Did not find the 'static' list variable within the 'DBG' list? + varListOld.remove (o); // then remove the 'static' list variable from list + o -= 1; // Adjust the 'static' list index + } + } } + /** + * This method is called by the proxy. + * It sends a request to DBG to get the current variables + * with their values. It waits for the response and processes + * the input from DBG. + * + * @param stack The stackframe for which we want the variables. + * @return The array of variables + */ + public PHPVariable[] getVariables (PHPStackFrame stack) throws IOException, DebugException { + PHPDBGPacket DBGPacket; + PHPDBGFrame DBGFrame1; + PHPDBGEvalString evalStr; + + DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST); // + DBGFrame1 = new PHPDBGFrame (PHPDBGBase.FRAME_EVAL); // + + DBGFrame1.addInt (0); // istr = raw data ID + DBGFrame1.addInt (1); // scope_id = -1 means current location, 0 never used, +1 first depth + + DBGPacket.addFrame (DBGFrame1); // Add command data + + if (proxy.getSocket ().isClosed ()) { // Do we have a socket for DBG communication? + return null; // No, then leave here + } + + DBGPacket.sendPacket (os); // Send the request to DBG + + waitResponse (1000); // Wait for the DBG response (1 second) + flushAllPackets (); // Read and process the response from DBG + + evalStr = new PHPDBGEvalString (stack, serGlobals); // Process serialized variables + updateVariableList (DBGVarList, evalStr.getVariables ()); // Replicate the 'static' variable list and the via DBG received variable list + + return (PHPVariable[]) DBGVarList.toArray (new PHPVariable[DBGVarList.size ()]); // Convert the list to an array and return the array + } + + /** + * + * @param logString + */ public void log(String logString) throws IOException, DebugException { PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST); PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_LOG); @@ -286,7 +534,7 @@ public class PHPDBGInterface { DBGFrame1.addInt(0); // mod_no DBGFrame1.addInt(0); // line_no DBGFrame1.addInt(0); // imod_name - DBGFrame1.addInt(0); // ext_info + DBGFrame1.addInt(0); // ext_info DBGFrame2.addInt(rawCounter); // FRAME_RAWDATA ID DBGFrame2.addInt(logString.length() + 1); // length of rawdata (+ null char) @@ -297,7 +545,7 @@ public class PHPDBGInterface { DBGPacket.addFrame(DBGFrame2); // Add command data DBGPacket.addFrame(DBGFrame1); - + if(proxy.getSocket().isClosed()) return; DBGPacket.sendPacket(os); @@ -323,211 +571,326 @@ public class PHPDBGInterface { DBGPacket.addFrame(DBGFrame2); // Add command data DBGPacket.addFrame(DBGFrame1); - + if(proxy.getSocket().isClosed()) return null; DBGPacket.sendPacket(os); waitResponse(1000); flushAllPackets(); - + PHPDBGEvalString evalStr=new PHPDBGEvalString(stack,evalRet); - + return evalStr.getVars(); - - } - public void flushAllPackets() throws IOException { - while(readResponse() != 0); } - public String getModByNo(int modNo) { - int i; - PHPDBGMod dbg_mod; + /** + * Read and process everthing we got from DBG + */ + public void flushAllPackets () throws IOException { + while (readResponse() != 0); + } - // look for mod - for(i=0; i < DBGMods.size(); i++) { - dbg_mod= (PHPDBGMod) DBGMods.get(i); - if(dbg_mod.getNo() == modNo) { - return dbg_mod.getName(); + /** + * Get the modules name by its number + * + * @param modNo The number (id) of the module + * @return The name of the module + */ + public String getModByNo (int modNo) { + int i; + PHPDBGMod dbg_mod; + + for (i = 0; i < DBGMods.size (); i++) { // For all the modules we have within the array + dbg_mod = (PHPDBGMod) DBGMods.get (i); // Get the module + + if (dbg_mod.getNo () == modNo) { // Is the module from the array the module we want? + return dbg_mod.getName (); // Yes, return the name of the module } } - return ""; - } - private int getModByName(String modName) { - int i; - PHPDBGMod dbg_mod; + return ""; // If nothing was found return emtpy string + } - // look for mod - for(i=0; i < DBGMods.size(); i++) { - dbg_mod= (PHPDBGMod) DBGMods.get(i); - if(dbg_mod.getName().equalsIgnoreCase(modName)) { - return dbg_mod.getNo(); + /** + * + * @param modName The name of the module for which we want the ID + * @return + * - The ID of the module + * - -1 if nothing was found + */ + private int getModByName (String modName) { + int i; + PHPDBGMod dbg_mod; + + for (i = 0; i < DBGMods.size (); i++) { // For all the modules we have within the array + dbg_mod = (PHPDBGMod) DBGMods.get (i); // Get the module + + if (dbg_mod.getName ().equalsIgnoreCase (modName)) { // Is the module from the array the module we want? + return dbg_mod.getNo (); // Yes, return the name of the module } } - return -1; + + return -1; // If nothing was found return -1 } - private String getRawFrameData(char[] framesInfo, int frameNo) { - int nextFrame= 0; - int[] dbg_frame= new int[2]; - - while(nextFrame < framesInfo.length) { - dbg_frame[0] = PHPDBGBase.Char4ToInt(framesInfo, nextFrame); // frame name - dbg_frame[1] = PHPDBGBase.Char4ToInt(framesInfo, nextFrame + 4); // frame size + /** + * Return the string for the given frame number + * + * @param framesInfo The buffer which is to read + * @param frameNo The frame number + * @return + */ + private String getRawFrameData (char[] framesInfo, int frameNo) { + int nextFrame = 0; // The current read position within the buffer + int[] dbg_frame = new int[2]; // The two frame header numbers + + while (nextFrame < framesInfo.length) { // As long we have something within the buffer + dbg_frame[0] = PHPDBGBase.Char4ToInt (framesInfo, nextFrame); // The frame type + dbg_frame[1] = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4); // The frame size + + nextFrame += 8; // The current read position + + if (dbg_frame[1] == 0) { // If frame size is 0 + return ""; // return an emtpy string + } + + switch (dbg_frame[0]) { // Switch for the frame type + case PHPDBGBase.FRAME_RAWDATA: // The only frame type we are interrested in + if (frameNo == PHPDBGBase.Char4ToInt (framesInfo, nextFrame)) { // Is it correct number of the frame + int toRead; // - nextFrame += 8; - if(dbg_frame[1] == 0) return ""; + toRead = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4); // The size of the string - switch(dbg_frame[0]) { - case PHPDBGBase.FRAME_RAWDATA: - if(frameNo == PHPDBGBase.Char4ToInt(framesInfo, nextFrame)) { - int toRead= PHPDBGBase.Char4ToInt(framesInfo, nextFrame + 4); - return String.copyValueOf(framesInfo, nextFrame + 8, toRead); + return String.copyValueOf (framesInfo, nextFrame + 8, toRead); // Copy frame content to String and return } break; } - // go to next frame - nextFrame += dbg_frame[1]; + + nextFrame += dbg_frame[1]; // Go for the next frame (add the length of the current one) } - return ""; - } - - - public int readResponse() throws IOException { - int bytesToRead=0, nextFrame=0, i=0, cmdReceived=0, stackIndex=0; - boolean errorStack= false; - char[] dbg_header_struct_read= new char[16]; - int[] dbg_header_struct= new int[4]; - int[] dbg_bpl_tmp= new int[10]; - int[] dbg_frame= new int[2]; - int[] dbg_eval_tmp= new int[3]; - int[] dbg_src_tree_tmp= new int[4]; - int[] dbg_error_tmp= new int[2]; - Vector rawList= new Vector(); - Vector stackList= new Vector(); + + return ""; // We did not found any FRAM_RAWDATA, so return an emtpy strin + } + + /** + * + * The stackList contains the currently read stackframes which were sent + * from DBG. The DBG interface holds a list of the active stack frames. + * This method looks whether the sent stackframes are already in the list. + * Removes the unused stackframes from the list, or adds stackframes which + * are not yet in the list. + * + * @param stackList + */ + private void updateStackFrameList (Vector stackList) { + int i; + int n; + PHPStackFrame stackFrameNew; + PHPStackFrame stackFrameOld; PHPStackFrame[] newStackList; - - rawList.clear(); - stackList.clear(); + + for (i = 0; i < stackList.size (); i++) { // For all stackList entries + stackFrameNew = (PHPStackFrame) stackList.get(i); + + for (n = 0; n < stackListOld.size (); n++) { // For all StackFrames in the StackFrame list + stackFrameOld = (PHPStackFrame) stackListOld.get (n); // --- + + if (stackFrameNew.getModNo () == stackFrameOld.getModNo ()) { // Did we find the sent stackframe within the list of old stackframes? + stackFrameOld.setLineNumber (stackFrameNew.getLineNumber()); + + break; // Yes, then break; + } + } + + if (n == stackListOld.size ()) { // Did not find the new stackframe within the list + stackListOld.add (stackFrameNew); // then add the new stackframe + } + } + + // And now for removing unused stackframes from list + + for (n = 0; n < stackListOld.size (); n++) { // For all StackFrames in the StackFrame list + stackFrameOld = (PHPStackFrame) stackListOld.get (n); // --- + + for (i = 0; i < stackList.size (); i++) { // For all stackList entries + stackFrameNew = (PHPStackFrame) stackList.get (i); + + if (stackFrameNew.getModNo () == stackFrameOld.getModNo ()) { // Did we find the sent stackframe within the list of old stackframes? + break; // Yes, then break; + } + } + + if (i == stackList.size ()) { // Did not find the old stackframe within the list of new ones + stackListOld.remove (n); // then remove the old stackframe from list + n -= 1; // Adjust the stack list index + } + } + + newStackList = new PHPStackFrame[stackListOld.size ()]; + newStackList = (PHPStackFrame[]) stackListOld.toArray (newStackList); + DBGStackList = newStackList; + } + + /** + * Read the response from DBG and process the frame + * + * @return + * - The received command + * - or 0 if something was wrong + */ + public int readResponse () throws IOException { + int bytesToRead = 0; // The number of byte to read for the current DBG block + int nextFrame = 0; // The current read position within entirePack + int i = 0; + int cmdReceived = 0; + int stackIndex = 0; + boolean errorStack = false; + char[] dbg_header_struct_read = new char[16]; // The buffer for the first 16 bytes of a block + int[] dbg_header_struct = new int[4]; // The first four numbers (long) of a block + int[] dbg_bpl_tmp = new int[10]; + int[] dbg_frame = new int[2]; + int[] dbg_eval_tmp = new int[3]; + int[] dbg_src_tree_tmp = new int[4]; // + int[] dbg_error_tmp = new int[2]; + Vector rawList = new Vector(); + Vector stackList = new Vector(); // Intermediate stacklist which is build up in FRAME_STACK frame + + rawList.clear (); + stackList.clear (); + // Read from input - while(readInput(dbg_header_struct_read, 16) != 0) { - dbg_header_struct[0] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 0); - dbg_header_struct[1] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 4); - dbg_header_struct[2] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 8); - dbg_header_struct[3] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 12); - - // Check DBG sync bytes - if(dbg_header_struct[0] != 0x5953) return 0; - - cmdReceived= dbg_header_struct[1]; - setLastCmd(cmdReceived); - bytesToRead= dbg_header_struct[3]; + while (readInput (dbg_header_struct_read, 16) != 0) { // Read 16 byte from input stream + dbg_header_struct[0] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 0); // Debug sync header + dbg_header_struct[1] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 4); // Command + dbg_header_struct[2] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 8); // + dbg_header_struct[3] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 12); // Bytes within this block + + if (dbg_header_struct[0] != 0x5953) { // Check DBG sync bytes + return 0; // Wrong header + } + + cmdReceived = dbg_header_struct[1]; // Get the command + setLastCmd (cmdReceived); // Store the info about the current command + bytesToRead = dbg_header_struct[3]; // Get the number of bytes to read for this block //System.out.println("Response Received: " + cmdReceived); - char[] entirePack= new char[bytesToRead]; + char[] entirePack = new char[bytesToRead]; // Store the block data into buffer 'entirePack' - if(bytesToRead > 0) { - if(readInput(entirePack, bytesToRead) < bytesToRead) return 0; + if (bytesToRead > 0) { // If there is something within the frame + if (readInput (entirePack, bytesToRead) < bytesToRead) { // Read the frame into the buffer + return 0; // We did not read enough bytes, error + } } - - // First process frames - nextFrame= 0; - while(nextFrame < bytesToRead) { - dbg_frame[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame); // frame name - dbg_frame[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); // frame size - nextFrame += 8; - if(dbg_frame[1] == 0) return 0; - switch(dbg_frame[0]) { + + nextFrame = 0; // Start with the first frame + + while (nextFrame < bytesToRead) { // As long as we have something within this block + dbg_frame[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame); // The name of the frame + dbg_frame[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); // The size of the frame + nextFrame += 8; // The next read position + + if (dbg_frame[1] == 0) { // Something within the frame? + return 0; // Nothing to read, error + } + + switch (dbg_frame[0]) { case PHPDBGBase.FRAME_STACK: - int[] dbg_stack_new= new int[4]; - dbg_stack_new[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); // line no - dbg_stack_new[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); // mod no - dbg_stack_new[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8); // scope id - dbg_stack_new[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12); // id of description string + int[] dbg_stack_new = new int[4]; // + + dbg_stack_new[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0); // Source line number + dbg_stack_new[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); // Module number + dbg_stack_new[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8); // Scope id + dbg_stack_new[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12); // ID of description string + + if ((dbg_stack_new[1] != 0) && !errorStack) { + PHPStackFrame newStack; - if(dbg_stack_new[1] != 0 && !errorStack) { stackIndex++; - PHPStackFrame newStack= new PHPStackFrame(null, getModByNo(dbg_stack_new[1]), dbg_stack_new[0], stackIndex, getRawFrameData(entirePack, dbg_stack_new[3]), dbg_stack_new[1]); - stackList.add(newStack); + newStack = new PHPStackFrame (null, // The thread + getModByNo (dbg_stack_new[1]), // The name of the module (file) + dbg_stack_new[0], // The source line number + stackIndex, + getRawFrameData (entirePack, // Get the string from this packet + dbg_stack_new[3]), // The frame ID for which we want the string + dbg_stack_new[1]); // The module number + stackList.add (newStack); } - errorStack= false; - break; - case PHPDBGBase.FRAME_SOURCE: + + errorStack = false; break; - case PHPDBGBase.FRAME_SRC_TREE: - dbg_src_tree_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); // parent_mod_no - dbg_src_tree_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); // parent_line_no /* NOT USED */ - dbg_src_tree_tmp[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8); // mod_no - dbg_src_tree_tmp[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12); // imod_name - - if(getModByNo(dbg_src_tree_tmp[2]).equals("")) { - String fileName= new String(getRawFrameData(entirePack, dbg_src_tree_tmp[3])); - // Remove '\0' char - if(fileName.length() > 0) fileName= fileName.substring(0, fileName.length() - 1); - - if(dbg_src_tree_tmp[2] != 0) { - PHPDBGMod modNew= new PHPDBGMod(dbg_src_tree_tmp[2], fileName); - DBGMods.add(modNew); + + case PHPDBGBase.FRAME_SOURCE: // Nothing to be done here + break; // TODO: what's with that frame? Something interesting + + case PHPDBGBase.FRAME_SRC_TREE: // + dbg_src_tree_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0); // The parent module number + dbg_src_tree_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); // The parent line number (not used) + dbg_src_tree_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8); // The module number + dbg_src_tree_tmp[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12); // The filename number + + if (getModByNo (dbg_src_tree_tmp[2]).equals ("")) { + String fileName; + + fileName = new String (getRawFrameData (entirePack, dbg_src_tree_tmp[3])); // Get the filename + + if (fileName.length () > 0) { // If we have a filename + fileName = fileName.substring (0, fileName.length () - 1); // Remove '\0' char + } + + if (dbg_src_tree_tmp[2] != 0) { // If there is a module number + PHPDBGMod modNew; + + modNew = new PHPDBGMod (dbg_src_tree_tmp[2], fileName); // Create a module object + + DBGMods.add (modNew); // And store it to array } } break; - case PHPDBGBase.FRAME_RAWDATA: - break; - case PHPDBGBase.FRAME_ERROR: - errorStack= true; - dbg_error_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); // type /* type of error */ - dbg_error_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); // imessage /* ID of error message */ - - String error= "\n"; - switch(dbg_error_tmp[0]) { - case PHPDBGBase.E_ERROR: - error+= "[Error]"; - break; - case PHPDBGBase.E_WARNING: - error+= "[Warning]"; - break; - case PHPDBGBase.E_PARSE: - error+= "[Parse Error]"; - break; - case PHPDBGBase.E_NOTICE: - error+= "[Notice]"; - break; - case PHPDBGBase.E_CORE_ERROR: - error+= "[Core Error]"; - break; - case PHPDBGBase.E_CORE_WARNING: - error+= "[Core Warning]"; - break; - case PHPDBGBase.E_COMPILE_ERROR: - error+= "[Compile Error]"; - break; - case PHPDBGBase.E_COMPILE_WARNING: - error+= "[Compile Warning]"; - break; - case PHPDBGBase.E_USER_ERROR: - error+= "[User Error]"; - break; - case PHPDBGBase.E_USER_WARNING: - error+= "[User Warning]"; - break; - case PHPDBGBase.E_USER_NOTICE: - error+= "[User Notice]"; - break; - default: - error+= "[Unexpected Error]"; - break; + + case PHPDBGBase.FRAME_RAWDATA: // Nothing to be done here + break; // FRAME_RAWDATA are processed within getRawFrameData + + case PHPDBGBase.FRAME_ERROR: // An error frame + errorStack = true; // Yes, we have an error stack + dbg_error_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0); // Error type + dbg_error_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); // Error message ID + + String error = "\n"; // + + switch (dbg_error_tmp[0]) { // Switch on error type + case PHPDBGBase.E_ERROR: error += "[Error]"; break; + case PHPDBGBase.E_WARNING: error += "[Warning]"; break; + case PHPDBGBase.E_PARSE: error += "[Parse Error]"; break; + case PHPDBGBase.E_NOTICE: error += "[Notice]"; break; + case PHPDBGBase.E_CORE_ERROR: error += "[Core Error]"; break; + case PHPDBGBase.E_CORE_WARNING: error += "[Core Warning]"; break; + case PHPDBGBase.E_COMPILE_ERROR: error += "[Compile Error]"; break; + case PHPDBGBase.E_COMPILE_WARNING: error += "[Compile Warning]"; break; + case PHPDBGBase.E_USER_ERROR: error += "[User Error]"; break; + case PHPDBGBase.E_USER_WARNING: error += "[User Warning]"; break; + case PHPDBGBase.E_USER_NOTICE: error += "[User Notice]"; break; + default: error += "[Unexpected Error]"; break; + } + + error += ": "; + error += new String (getRawFrameData (entirePack, dbg_error_tmp[1])); // Add the error string for this error message ID + + if (error.length () > 0) { // If we have a error message + error = error.substring (0, error.length () - 1); // Remove '\0' char } - error+= ": "; - error+= new String(getRawFrameData(entirePack, dbg_error_tmp[1])); - // Remove '\0' char - if(error.length() > 0) error= error.substring(0, error.length() - 1); - error+= "\n"; - PHPDebugCorePlugin.log(new DebugException(new Status(IStatus.WARNING, PHPDebugCorePlugin.PLUGIN_ID, IStatus.OK, error, null))); + error += "\n"; // Append a CR + + PHPDebugCorePlugin.log (new DebugException (new Status (IStatus.WARNING, + PHPDebugCorePlugin.PLUGIN_ID, + IStatus.OK, + error, null))); + // To print errors on the console, I must execute a code in the // php context, that write the stderr... I didn't found a better way // TODO: Find a better way???? + // String codeExec= ""; // codeExec= "fwrite(fopen('php://stderr', 'w'),\\\"" + error + "\\\");"; // try { @@ -535,158 +898,215 @@ public class PHPDBGInterface { // } catch (DebugException e) { // PHPDebugCorePlugin.log(e); // } - if(!stopOnError) { - if(lastCommand.equals(PHPDBGBase.DBGA_CONTINUE)) { - continueExecution(); - } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPINTO)) { - stepInto(); - } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPOUT)) { - stepOut(); - } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPOVER)) { - stepOver(); +// + if (!stopOnError) { // Is always false (Did not see where this is set to true!?) + if (lastCommand.equals (PHPDBGBase.DBGA_CONTINUE)) { // If last command for PHP was a 'continue', + continueExecution (); // send continue again + } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPINTO)) { // If last command for PHP was a 'step into', + stepInto (); // send 'step into' again + } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPOUT)) { // If last command for PHP was a 'step out', + stepOut (); // send 'step out' again + } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPOVER)) { // If last command for PHP was a 'step over', + stepOver (); // send 'step over' again } } break; + case PHPDBGBase.FRAME_EVAL: - String evalString= new String(""); - dbg_eval_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); // istr - dbg_eval_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); // iresult - dbg_eval_tmp[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8); // ierror - - evalRet= getRawFrameData(entirePack, dbg_eval_tmp[1]); - evalString= getRawFrameData(entirePack, dbg_eval_tmp[0]); - serGlobals= evalRet; - break; - case PHPDBGBase.FRAME_BPS: + String evalString; + + evalString = new String (""); + dbg_eval_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0); // istr + dbg_eval_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); // iresult + dbg_eval_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8); // ierror + + evalRet = getRawFrameData (entirePack, dbg_eval_tmp[1]); // + evalString = getRawFrameData (entirePack, dbg_eval_tmp[0]); // + serGlobals = evalRet; // break; + + case PHPDBGBase.FRAME_BPS: // + break; // + case PHPDBGBase.FRAME_BPL: - int[] dbg_bpl_new= new int[10]; - dbg_bpl_new[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); - dbg_bpl_new[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); - dbg_bpl_new[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8); - dbg_bpl_new[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12); - dbg_bpl_new[4] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 16); - dbg_bpl_new[5] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 20); - dbg_bpl_new[6] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 24); - dbg_bpl_new[7] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 28); - dbg_bpl_new[8] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 32); - dbg_bpl_new[9] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 36); - + int[] dbg_bpl_new; + + dbg_bpl_new = new int[10]; + dbg_bpl_new[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0); + dbg_bpl_new[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4); + dbg_bpl_new[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8); + dbg_bpl_new[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12); + dbg_bpl_new[4] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 16); + dbg_bpl_new[5] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 20); + dbg_bpl_new[6] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 24); + dbg_bpl_new[7] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 28); + dbg_bpl_new[8] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 32); + dbg_bpl_new[9] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 36); + // look if breakpoint already exists in vector - for(i=0; i < DBGBPList.size(); i++) { - dbg_bpl_tmp= (int[]) DBGBPList.get(i); - if(dbg_bpl_tmp[8] == dbg_bpl_new[8]) { - DBGBPList.remove(i); + for (i = 0; i < DBGBPList.size (); i++) { + dbg_bpl_tmp = (int[]) DBGBPList.get (i); + + if (dbg_bpl_tmp[8] == dbg_bpl_new[8]) { + DBGBPList.remove (i); + break; } } // add breakpoint to vector - DBGBPList.add(dbg_bpl_new); - copyToLastBP(dbg_bpl_new); - + DBGBPList.add (dbg_bpl_new); + copyToLastBP (dbg_bpl_new); + // mod no returned? - if(getModByNo(dbg_bpl_new[0]).equals("")) { - String fileName= new String(getRawFrameData(entirePack, dbg_bpl_new[2])); - // Remove '\0' char - if(fileName.length() > 0) fileName= fileName.substring(0, fileName.length() - 1); - if(dbg_bpl_new[0] != 0) { - PHPDBGMod modNew= new PHPDBGMod(dbg_bpl_new[0], fileName); - DBGMods.add(modNew); + if (getModByNo (dbg_bpl_new[0]).equals ("")) { + String fileName; + + fileName = new String (getRawFrameData (entirePack, dbg_bpl_new[2])); + + if (fileName.length () > 0) { // If we have filename + fileName = fileName.substring (0, fileName.length () - 1); // Remove '\0' char + } + + if (dbg_bpl_new[0] != 0) { + PHPDBGMod modNew; + + modNew = new PHPDBGMod (dbg_bpl_new[0], fileName); + + DBGMods.add (modNew); } - } + } break; + case PHPDBGBase.FRAME_VER: break; + case PHPDBGBase.FRAME_SID: - sid = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); + sid = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); break; + case PHPDBGBase.FRAME_SRCLINESINFO: break; + case PHPDBGBase.FRAME_SRCCTXINFO: break; + case PHPDBGBase.FRAME_LOG: break; + case PHPDBGBase.FRAME_PROF: break; + case PHPDBGBase.FRAME_PROF_C: break; + case PHPDBGBase.FRAME_SET_OPT: break; } - // go to next frame - nextFrame += dbg_frame[1]; + + nextFrame += dbg_frame[1]; // go to next frame } - + // Now process command switch(cmdReceived) { case PHPDBGBase.DBGC_REPLY: break; + case PHPDBGBase.DBGC_STARTUP: break; + case PHPDBGBase.DBGC_END: - sessionEnded= true; + sessionEnded = true; break; + case PHPDBGBase.DBGC_BREAKPOINT: - newStackList= new PHPStackFrame[stackList.size()]; - newStackList= (PHPStackFrame[]) stackList.toArray(newStackList); - DBGStackList= newStackList; - BPUnderHit= getBPUnderHit(); + BPUnderHit = getBPUnderHit (); + updateStackFrameList (stackList); break; + case PHPDBGBase.DBGC_STEPINTO_DONE: case PHPDBGBase.DBGC_STEPOVER_DONE: case PHPDBGBase.DBGC_STEPOUT_DONE: case PHPDBGBase.DBGC_EMBEDDED_BREAK: case PHPDBGBase.DBGC_PAUSE: - BPUnderHit= 1; - newStackList= new PHPStackFrame[stackList.size()]; - newStackList= (PHPStackFrame[]) stackList.toArray(newStackList); - DBGStackList= newStackList; + BPUnderHit = 1; + updateStackFrameList (stackList); break; + case PHPDBGBase.DBGC_ERROR: - stackList.clear(); - newStackList= new PHPStackFrame[stackList.size()]; - newStackList= (PHPStackFrame[]) stackList.toArray(newStackList); - DBGStackList= newStackList; + stackList.clear (); + updateStackFrameList (stackList); break; + case PHPDBGBase.DBGC_LOG: break; + case PHPDBGBase.DBGC_SID: break; } } - return cmdReceived; + + return cmdReceived; // Return the command we received with this block } + /** + * + */ + public PHPStackFrame[] getStackList() { return DBGStackList; } - private int readInput(char[] buffer, int bytes) throws IOException { - int bytesRead= 0; - - for(int i=0; i < bytes; i++) { - if(in.ready()) { - buffer[i]= (char) (in.read() & 0x00FF); - bytesRead++; + /** + * Reads from input buffer (response sent from DBG) the given number of chars + * into frame buffer. + * + * @param buffer The frame buffer where to store the read data from DBG. + * @param bytes The number of bytes (chars) which are to read from input stream. + * @return The number of bytes actually read. + */ + private int readInput (char[] buffer, int bytes) throws IOException { + int bytesRead = 0; // Reset the bytes read counter + + for (int i = 0; i < bytes; i++) { // For the number of bytes we should read + if (in.ready ()) { // If input stream is ready for reading + buffer[i] = (char) (in.read () & 0x00FF); // Read a char and store only the least significant 8-bits + bytesRead++; // Increment the bytes read counter + } + else { // Input stream is not ready + break; // Break the loop } - else - break; } - return bytesRead; + + return bytesRead; // Return the number of bytes actually read } - - public void setShouldStop() { - this.shouldStop= true; + + /** + * PHPProxy could stop the waiting for a response with this method. + * + */ + public void setShouldStop () { + this.shouldStop = true; } - public boolean waitResponse(long milliseconds) throws IOException { - long timeout= System.currentTimeMillis() + milliseconds; - while(System.currentTimeMillis() < timeout) { - if(in.ready() || shouldStop) { - break; + /** + * @param milliseconds The maximum time in milliseconds we wait for something + * to be send from DBG. + * @return - true if something was received from DBG + * - false if nothing was send from DBG within the given time + * + */ + public boolean waitResponse (long milliseconds) throws IOException { + long timeout; + + timeout = System.currentTimeMillis () + milliseconds; // Calculate the system time till we wait. + + while (System.currentTimeMillis () < timeout) { // Is waiting time running out? + if (in.ready () || shouldStop) { // No, so did we get something or should we stop now + break; // Yes, break the waiting } } - return in.ready(); + + return in.ready (); // true if we got something from DBG } } diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGPacket.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGPacket.java index 9c1c322..cbbcdbe 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGPacket.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGPacket.java @@ -15,42 +15,40 @@ import java.io.OutputStream; import java.util.Vector; public class PHPDBGPacket { - private static final int PACKET_HEADER_SIZE= 16; - private char[] packetHeader= new char[PACKET_HEADER_SIZE]; - private int packetSize; - private Vector frames= new Vector(); - - public PHPDBGPacket(char[] packetType) { - PHPDBGBase.copyChars(packetHeader, PHPDBGBase.DBGSYNC, 4); - PHPDBGBase.copyCharsTo(packetHeader, packetType, 4, 4); + private static final int PACKET_HEADER_SIZE = 16; + private char[] packetHeader = new char[PACKET_HEADER_SIZE]; + private int packetSize; + private Vector frames = new Vector (); + + public PHPDBGPacket (char[] packetType) { + PHPDBGBase.copyChars (packetHeader, PHPDBGBase.DBGSYNC, 4); + PHPDBGBase.copyCharsTo (packetHeader, packetType, 4, 4); } - public void addFrame(PHPDBGFrame frame) { - frames.add(frame); - packetSize+= frame.getSize(); + public void addFrame (PHPDBGFrame frame) { + frames.add (frame); + packetSize += frame.getSize (); } - - public void sendPacket(OutputStream out) throws IOException { - int i; + + public void sendPacket (OutputStream out) throws IOException { + int i; PHPDBGFrame frame; - - PHPDBGBase.copyCharsTo(packetHeader, PHPDBGBase.IntToChar4(packetSize), 4, 12); - - // Send packet header - out.write(PHPDBGBase.CharArrayToByteArray(packetHeader)); - out.flush(); - - // Send Frames - for(i=0; i < frames.size(); i++) { - // Header of frame - frame= (PHPDBGFrame)frames.get(i); - out.write(PHPDBGBase.CharArrayToByteArray(frame.getHeader())); - out.flush(); - if (frame.getSizeOfData() > 0) { - // Data of frame - out.write(PHPDBGBase.CharArrayToByteArray(frame.getFrameData())); - out.flush(); + + PHPDBGBase.copyCharsTo (packetHeader, PHPDBGBase.IntToChar4 (packetSize), 4, 12); + + out.write (PHPDBGBase.CharArrayToByteArray (packetHeader)); // Send packet header + out.flush (); // + + for (i = 0; i < frames.size (); i++) { // Send Frames + frame = (PHPDBGFrame) frames.get (i); // Header of frame + + out.write (PHPDBGBase.CharArrayToByteArray (frame.getHeader ())); // Convert the char buffer to a byte buffer and send + out.flush (); + + if (frame.getSizeOfData () > 0) { // If there is a data frame + out.write (PHPDBGBase.CharArrayToByteArray (frame.getFrameData ()));// Convert the data char buffer to a byte buffer and send + out.flush (); } } } -} \ No newline at end of file +} diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java index 0c30b77..db66060 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java @@ -32,454 +32,599 @@ import org.eclipse.debug.core.model.IBreakpoint; public class PHPDBGProxy { - private ServerSocket server = null; - - private Socket socket; - - private BufferedReader reader = null; - - private PHPDBGInterface DBGInt = null; - - private PHPDebugTarget debugTarget = null; - - private PHPLoop phpLoop; - - private PHPThread PHPMainThread; - - private PHPDBGProxy thisProxy = null; - - private int port; - - private boolean remote; - - private boolean pathtranslation; - - private Map pathmap; - - private IPath remoteSourcePath; - - public PHPDBGProxy() { - thisProxy = this; - } - - public PHPDBGProxy(boolean remote, String remoteSourcePath,boolean pathTranslate,Map paths) { - thisProxy = this; - this.remote = remote; - this.remoteSourcePath = new Path(remoteSourcePath); - this.pathmap=paths; - this.pathtranslation=pathTranslate; - } - - public void start() { - createServerSocket(); - this.startPHPLoop(); - } - - public void stop() { - phpLoop.setShouldStop(); - if (DBGInt != null) - DBGInt.setShouldStop(); - if (!remote) { - try { - getDebugTarget().getProcess().terminate(); - } catch (DebugException e) { - e.printStackTrace(); - } - } - phpLoop.notifyWait(); - } - - protected ServerSocket getServerSocket() throws IOException { - if (server == null) { - createServerSocket(); - } - return server; - } - - protected void createServerSocket() { - port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101); -// port = 10001; - if (port == -1) { - PHPDebugCorePlugin.log(5, "Cannot find free port!!!!"); - return; - } - try { - if (server == null) { - server = new ServerSocket(port); - //System.out.println("ServerSocket on port: " + port); - } - } catch (IOException e) { - // IO Error - PHPDebugCorePlugin.log(e); - stop(); - } - } - - public Socket getSocket() throws IOException { - return socket; - } - - protected void setDBGInterface(PHPDBGInterface DBGInt) { - this.DBGInt = DBGInt; - } - - public BufferedReader getReader() throws IOException { - if (reader == null) { - reader = new BufferedReader(new InputStreamReader(this.getSocket().getInputStream(), "ISO8859_1")); - } - return reader; - } - - public BufferedReader getReader(Socket socket) throws IOException { - if (socket != null) - return new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO8859_1")); - else - return null; - } - - public OutputStream getOutputStream() throws IOException { - return this.getSocket().getOutputStream(); - } - - protected void setBreakPoints() throws IOException, CoreException { - IBreakpoint[] breakpoints = DebugPlugin.getDefault() - .getBreakpointManager().getBreakpoints(); - for (int i = 0; i < breakpoints.length; i++) { - if (breakpoints[i].isEnabled()) { - addBreakpoint(breakpoints[i]); - } - } - } - - private String MapPath(PHPLineBreakpoint phpLBP) { - IPath filename; - if (remote) { - filename = phpLBP.getMarker().getResource() - .getProjectRelativePath(); - filename = remoteSourcePath.append(filename); - } else + private ServerSocket server = null; + private BufferedReader reader = null; + private PHPDBGInterface DBGInt = null; // The DBG interface which is linked with the proxy + private PHPDebugTarget debugTarget = null; + private PHPDBGProxy thisProxy = null; + private PHPLoop phpLoop; + private PHPThread PHPMainThread; + private Socket socket; + private int port; + private boolean remote; + private boolean pathtranslation; + private Map pathmap; + private IPath remoteSourcePath; + + /** + */ + public PHPDBGProxy () { + thisProxy = this; + } + + /** + * @param remote + * @param remoteSourcePath + * @param pathTranslate + * @param paths + */ + public PHPDBGProxy (boolean remote, String remoteSourcePath, boolean pathTranslate, Map paths) { + thisProxy = this; + this.remote = remote; + this.remoteSourcePath = new Path (remoteSourcePath); + this.pathmap = paths; + this.pathtranslation = pathTranslate; + } + + /** + * + */ + public void start () { + createServerSocket (); // Create a server socket for communicatio with DBG + + this.startPHPLoop (); // + } + + /** + * + */ + public void stop () { + phpLoop.setShouldStop (); // Notify the thread's 'run loop' to stop + + if (DBGInt != null) { // If we have a DBG interface linked with this proxy + DBGInt.setShouldStop (); // Notify the DBG interface to stop the waiting for response + } + + if (!remote) { // If it's not a remote proxy session + try { + getDebugTarget ().getProcess ().terminate (); // + } catch (DebugException e) { + e.printStackTrace (); + } + } + + phpLoop.notifyWait (); + } + + /** + * TODO Is this method called from anywhere? + * + * Returns a already created server socket, or + * creates a server socket if none exists, and + * returns the newly created one. + * + * @return A server socket + */ + protected ServerSocket getServerSocket () throws IOException { + if (server == null) { // Do we have already a server socket + createServerSocket (); // No, then create one + } + + return server; // Return the server socket + } + + /** + * + * TODO The example for setting up DBG within PHP.ini shows ports from 10000 to 10016 ??? + * if my interpretation is correct. + * How can we find the correct DBG port? + */ + protected void createServerSocket () { + port = SocketUtil.findUnusedLocalPort ("localhost", 10001, 10101); // Get the first free port in the range from 10001 to 10101 + +// port = 10001; + if (port == -1) { // Did we get a free port? + PHPDebugCorePlugin.log (5, "Cannot find free port!!!!"); // No, output a error message + + return; // And return + } + try { + if (server == null) { // If there is no server socket yet + server = new ServerSocket (port); // create a server socket for the free port + //System.out.println("ServerSocket on port: " + port); + } + } catch (IOException e) { + // IO Error + PHPDebugCorePlugin.log (e); + stop (); + } + } + + /** + * + */ + public Socket getSocket () throws IOException { + return socket; // Return the socket + } + + /** + * Set the DBG interface which is linked to this proxy + * + * @paran DBGInt The DGB interface which is linked with this proxy + */ + protected void setDBGInterface (PHPDBGInterface DBGInt) { + this.DBGInt = DBGInt; + } + + /** + * Give back a buffered input stream for the socket which is + * linked with this proxy + */ + public BufferedReader getReader () throws IOException { + if (reader == null) { // Do we already have a buffered input stream + reader = new BufferedReader (new InputStreamReader (this.getSocket ().getInputStream (), + "ISO8859_1")); + } + + return reader; // Return the buffered input stream + } + + /** + * + */ + public BufferedReader getReader (Socket socket) throws IOException { + if (socket != null) { // Is a socket provided + return new BufferedReader (new InputStreamReader (socket.getInputStream (), + "ISO8859_1")); // Then create a buffered input stream + } + else { + return null; // Without a socket we can't create a input stream + } + } + + /** + * + * @return The output stream for this proxy's socket + */ + public OutputStream getOutputStream () throws IOException { + return this.getSocket ().getOutputStream (); + } + + /** + * + */ + protected void setBreakPoints () throws IOException, CoreException { + IBreakpoint[] breakpoints = DebugPlugin.getDefault ().getBreakpointManager ().getBreakpoints (); + + for (int i = 0; i < breakpoints.length; i++) { + if (breakpoints[i].isEnabled ()) { + addBreakpoint (breakpoints[i]); + } + } + } + + /** + * + */ + private String MapPath (PHPLineBreakpoint phpLBP) { + IPath filename; + + if (remote) { + filename = phpLBP.getMarker().getResource().getProjectRelativePath(); + filename = remoteSourcePath.append (filename); + } else { filename = phpLBP.getMarker().getResource().getLocation(); - String path = filename.toOSString(); - if (pathmap != null && remote) { - java.util.Iterator i = pathmap.keySet().iterator(); - while (i.hasNext()) { - String k = (String) i.next(); - if (path.startsWith(k)) { - path = pathmap.get(k) + path.substring(k.length()); - break; - } - } } - if (pathtranslation && remote) { - if (remoteSourcePath.toString().substring(0, 1).equals("/")) - path = path.replace('\\', '/'); - else - path = path.replace('/', '\\'); - } - return path; - } - - public void addBreakpoint(IBreakpoint breakpoint) { - if (DBGInt == null) - return; - int bpNo = 0; - try { - PHPLineBreakpoint phpLBP; - if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) { - phpLBP = (PHPLineBreakpoint) breakpoint; - // bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber()); - - bpNo = DBGInt.addBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber()); - phpLBP.setDBGBpNo(bpNo); - } - } catch (IOException e) { - PHPDebugCorePlugin.log(e); - stop(); - } catch (CoreException e) { - PHPDebugCorePlugin.log(e); - stop(); - } - } - - public void removeBreakpoint(IBreakpoint breakpoint) { - if (DBGInt == null) - return; - try { - PHPLineBreakpoint phpLBP; - if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) { - phpLBP = (PHPLineBreakpoint) breakpoint; - - // bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber()); - DBGInt.removeBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber(), phpLBP.getDBGBpNo()); - } - } catch (IOException e) { - PHPDebugCorePlugin.log(e); - stop(); - } catch (CoreException e) { - PHPDebugCorePlugin.log(e); - stop(); - } - } - - public void phpLoopNotify() { - phpLoop.notifyWait(); - } - - public void startPHPLoop() { - phpLoop = new PHPLoop(); - phpLoop.start(); - } - - public void resume() { - try { - DBGInt.continueExecution(); - phpLoop.notifyWait(); - } catch (IOException e) { - PHPeclipsePlugin.log("Debugging session ended.", e); - stop(); - } - } - - public void pause() { - try { - if (null != DBGInt) - DBGInt.pauseExecution(); - else { - // TODO Make sure the Suspend action is grayed out - // when DBGInt is null - } - } catch (IOException e) { - PHPDebugCorePlugin.log(e); - stop(); - } - } - - protected PHPDebugTarget getDebugTarget() { - return debugTarget; - } - - public void setDebugTarget(PHPDebugTarget debugTarget) { - this.debugTarget = debugTarget; - debugTarget.setPHPDBGProxy(this); - } - - public PHPVariable[] readVariables(PHPStackFrame frame) { - try { - return DBGInt.getVariables(frame); - } catch (IOException ioex) { - ioex.printStackTrace(); - throw new RuntimeException(ioex.getMessage()); - } catch (DebugException ex) { - ex.printStackTrace(); - throw new RuntimeException(ex.getMessage()); - } - } - - public PHPVariable[] eval(PHPStackFrame frame, String evalString) { - try { - return DBGInt.evalBlock(frame, evalString); - // return DBGInt.getVariables(frame); - } catch (IOException ioex) { - ioex.printStackTrace(); - throw new RuntimeException(ioex.getMessage()); - } catch (DebugException ex) { - ex.printStackTrace(); - throw new RuntimeException(ex.getMessage()); - } - } - - public void readStepOverEnd(PHPStackFrame stackFrame) { - try { - DBGInt.stepOver(); - phpLoop.notifyWait(); - } catch (Exception e) { - PHPDebugCorePlugin.log(e); - } - } - - public void readStepReturnEnd(PHPStackFrame stackFrame) { - try { - DBGInt.stepOut(); - phpLoop.notifyWait(); - } catch (Exception e) { - PHPDebugCorePlugin.log(e); - } - } - - public void readStepIntoEnd(PHPStackFrame stackFrame) { - try { - DBGInt.stepInto(); - phpLoop.notifyWait(); - } catch (Exception e) { - PHPDebugCorePlugin.log(e); - } - } - - /* - * public PHPStackFrame[] readFrames(PHPThread thread) { //try { //this.println("th " + thread.getId() + " ; f "); //return new - * FramesReader(getMultiReaderStrategy()).readFrames(thread); return null; //} catch (IOException e) { // - * PHPDebugCorePlugin.log(e); // return null; //} - * } - */ - - public void closeSocket() throws IOException { - if (socket != null) { - socket.close(); - } - } - - public void closeServerSocket() throws IOException { - if (server != null) { - server.close(); - } - } - - public int getPort() { - return port; - } - - class PHPLoop extends Thread { - private boolean shouldStop; - - public PHPLoop() { - shouldStop = false; - this.setName("PHPDebuggerLoop"); - } - - public synchronized void setShouldStop() { - shouldStop = true; - try { - // If the loop thread is blocked on the server socket, - // forcibly unblock it to avoid leaking the thread, - // the socket and the port - closeServerSocket(); - } catch (IOException x) { - // Log this as a warning? - PHPDebugCorePlugin.log(x); + + String path = filename.toOSString(); + + if ((pathmap != null) && remote) { + java.util.Iterator i = pathmap.keySet().iterator(); + + while (i.hasNext()) { + String k = (String) i.next(); + if (path.startsWith(k)) { + path = pathmap.get(k) + path.substring(k.length()); + break; + } + } + } + + if (pathtranslation && remote) { + if (remoteSourcePath.toString ().substring (0, 1).equals ("/")) { + path = path.replace ('\\', '/'); + } + else { + path = path.replace ('/', '\\'); + } + } + + return path; + } + + /** + * + */ + public void addBreakpoint (IBreakpoint breakpoint) { + if (DBGInt == null) { + return; + } + + int bpNo = 0; + + try { + PHPLineBreakpoint phpLBP; + + if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier()) { + phpLBP = (PHPLineBreakpoint) breakpoint; + + // bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber()); + + bpNo = DBGInt.addBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber()); + phpLBP.setDBGBpNo(bpNo); + } + } catch (IOException e) { + PHPDebugCorePlugin.log(e); + stop(); + } catch (CoreException e) { + PHPDebugCorePlugin.log(e); + stop(); + } + } + + /** + * + */ + public void removeBreakpoint (IBreakpoint breakpoint) { + if (DBGInt == null) { + return; } - } - - public synchronized void notifyWait() { - notify(); - } - - public void run() { - try { - char[] buf = new char[16]; - int i, pos, timeout; - long interval = 200; // 200ms - String line; - PHPStackFrame[] StackList; - boolean endFile = false; - boolean newconnect = false; - Socket newSocket = null; - PHPDBGInterface newDBGInt; - int sid = -1; - - // synchronized (this) { - // wait(); - // } - - PHPMainThread = new PHPThread(getDebugTarget(), getPort()); - PHPMainThread.setName("Thread [main]"); - timeout = 0; - - // while ((getDebugTarget() == null) && (timeout < 100)) { - // sleep(100); - // timeout++; - // } - // Be sure debug target is set - // PHPMainThread.setDebugTarget(getDebugTarget()); - getDebugTarget().addThread(PHPMainThread); - - //System.out.println("Waiting for breakpoints."); - while (!shouldStop) { - newconnect = true; - try { - newSocket = server.accept(); - //System.out.println("Accepted! : " + socket.toString()); - } catch (SocketTimeoutException e) { - // no one wants to connect - newconnect = false; - } catch (IOException e) { - PHPDebugCorePlugin.log(e); - return; - } - - if (newconnect) { - if (DBGInt == null) - server.setSoTimeout(1); - newDBGInt = new PHPDBGInterface(getReader(newSocket), newSocket.getOutputStream(), thisProxy); - newDBGInt.waitResponse(1000); - newDBGInt.flushAllPackets(); - // Check version and session ID - if ((DBGInt == null) || (DBGInt.getSID() == newDBGInt.getSID())) { - DBGInt = newDBGInt; - try { - closeSocket(); - } catch (IOException e) { - PHPDebugCorePlugin.log(e); - shouldStop = true; - } - socket = newSocket; - setBreakPoints(); - DBGInt.continueExecution(); - } else { - newDBGInt.continueExecution(); - newSocket.close(); - } - } - - if (DBGInt.waitResponse(interval)) { - - DBGInt.flushAllPackets(); - - if (DBGInt.BPUnderHit != 0) { - StackList = DBGInt.getStackList(); - if (StackList.length > 0) { - for (i = 0; i < StackList.length; i++) { - StackList[i].setThread(PHPMainThread); - if (DBGInt.getModByNo(StackList[i].getModNo()).equals("")) { - DBGInt.getSourceTree(); - } - StackList[i].setFile(DBGInt.getModByNo(StackList[i].getModNo())); - } - PHPMainThread.setStackFrames(StackList); - } - // Fire debug event - PHPMainThread.suspend(); - - synchronized (this) { - wait(); - } - } - } - if (remote) { - if (PHPMainThread.isTerminated()) { - shouldStop = true; - break; - } - } else { - if (PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated()) { - shouldStop = true; - break; - } - } - } - } catch (Exception ex) { - PHPDebugCorePlugin.log(ex); - System.out.println(ex); - } finally { - try { - getDebugTarget().terminate(); - closeSocket(); - closeServerSocket(); - } catch (IOException e) { - PHPDebugCorePlugin.log(e); - return; - } - //System.out.println("Socket loop finished."); - } - } - } + + try { + PHPLineBreakpoint phpLBP; + + if (breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getUniqueIdentifier ()) { + phpLBP = (PHPLineBreakpoint) breakpoint; + + // bpNo= DBGInt.addBreakpoint(filename.toOSString(), phpLBP.getLineNumber()); + + DBGInt.removeBreakpoint(MapPath(phpLBP), phpLBP.getLineNumber(), phpLBP.getDBGBpNo()); + } + } catch (IOException e) { + PHPDebugCorePlugin.log (e); + stop (); + } catch (CoreException e) { + PHPDebugCorePlugin.log (e); + stop (); + } + } + + /** + * + */ + public void phpLoopNotify () { + phpLoop.notifyWait (); + } + + /** + * + */ + public void startPHPLoop () { + phpLoop = new PHPLoop (); // Create a DBG communication loop object + + phpLoop.start (); // And start the communication loop + } + + /** + * + */ + public void resume () { + try { + DBGInt.continueExecution(); + phpLoop.notifyWait(); + } catch (IOException e) { + PHPeclipsePlugin.log("Debugging session ended.", e); + stop(); + } + } + + /** + * + */ + public void pause () { + try { + if (null != DBGInt) { + DBGInt.pauseExecution(); + } + else { + // TODO Make sure the Suspend action is grayed out + // when DBGInt is null + } + } catch (IOException e) { + PHPDebugCorePlugin.log (e); + stop (); + } + } + + /** + * + */ + protected PHPDebugTarget getDebugTarget() { + return debugTarget; + } + + /** + * + * @param debugTarget + */ + public void setDebugTarget (PHPDebugTarget debugTarget) { + this.debugTarget = debugTarget; + debugTarget.setPHPDBGProxy(this); + } + + /** + * This method is called by a stackframe. + * It reads the variables from PHP via DBG + * + * @param frame The stackframe which wants the variables. + * @return The array of variables for this stackframe. + */ + public PHPVariable[] readVariables (PHPStackFrame frame) { + try { + return DBGInt.getVariables (frame); // Get the variables from DBG interface + } catch (IOException ioex) { + ioex.printStackTrace (); + throw new RuntimeException (ioex.getMessage ()); + } catch (DebugException ex) { + ex.printStackTrace (); + throw new RuntimeException (ex.getMessage ()); + } + } + + /** + * + * @param frame + * @param evalString + * @return + */ + public PHPVariable[] eval (PHPStackFrame frame, String evalString) { + try { + return DBGInt.evalBlock (frame, evalString); + //return DBGInt.getVariables(frame); + } catch (IOException ioex) { + ioex.printStackTrace(); + throw new RuntimeException(ioex.getMessage()); + } catch (DebugException ex) { + ex.printStackTrace(); + throw new RuntimeException(ex.getMessage()); + } + } + + public void readStepOverEnd (PHPStackFrame stackFrame) { + try { + DBGInt.stepOver(); + phpLoop.notifyWait(); + } catch (Exception e) { + PHPDebugCorePlugin.log(e); + } + } + + public void readStepReturnEnd (PHPStackFrame stackFrame) { + try { + DBGInt.stepOut(); + phpLoop.notifyWait(); + } catch (Exception e) { + PHPDebugCorePlugin.log(e); + } + } + + public void readStepIntoEnd (PHPStackFrame stackFrame) { + try { + DBGInt.stepInto(); + phpLoop.notifyWait(); + } catch (Exception e) { + PHPDebugCorePlugin.log(e); + } + } + + /* + * public PHPStackFrame[] readFrames(PHPThread thread) { //try { //this.println("th " + thread.getId() + " ; f "); //return new + * FramesReader(getMultiReaderStrategy()).readFrames(thread); return null; //} catch (IOException e) { // + * PHPDebugCorePlugin.log(e); // return null; //} + * } + */ + + public void closeSocket() throws IOException { + if (socket != null) { + socket.close(); + } + } + + public void closeServerSocket() throws IOException { + if (server != null) { + server.close(); + } + } + + public int getPort() { + return port; + } + + /** + * + * + */ + class PHPLoop extends Thread { + private boolean shouldStop; + + public PHPLoop () { + shouldStop = false; + this.setName ("PHPDebuggerLoop"); + } + + /** + * + */ + public synchronized void setShouldStop () { + shouldStop = true; // The run loop should stop + + try { + // If the loop thread is blocked on the server socket, + // forcibly unblock it to avoid leaking the thread, + // the socket and the port + closeServerSocket (); + } catch (IOException x) { + // Log this as a warning? + PHPDebugCorePlugin.log (x); + } + } + + /** + * + */ + public synchronized void notifyWait () { + notify (); + } + + /** + * + * + */ + public void run () { + try { + int i; + int timeout; + long interval = 200; // Wait 200 ms maximum for a DBG response + boolean newconnect = false; // + Socket newSocket = null; + PHPStackFrame[] StackList; + PHPDBGInterface newDBGInt; + + // synchronized (this) { + // wait(); + // } + + PHPMainThread = new PHPThread (getDebugTarget (), getPort ()); + PHPMainThread.setName ("Thread [main]"); + timeout = 0; + + // while ((getDebugTarget() == null) && (timeout < 100)) { + // sleep(100); + // timeout++; + // } + // Be sure debug target is set + // PHPMainThread.setDebugTarget(getDebugTarget()); + + getDebugTarget ().addThread (PHPMainThread); + + //System.out.println("Waiting for breakpoints."); + + while (!shouldStop) { // As long as nobody will stop us + newconnect = true; // The first time + + try { + newSocket = server.accept(); // Waits until DBG want to connect + //System.out.println("Accepted! : " + socket.toString()); + } catch (SocketTimeoutException e) { + newconnect = false; // No one wants to connect (connection already done) + } catch (IOException e) { + PHPDebugCorePlugin.log(e); + return; + } + + if (newconnect) { // Is it just after a new connection + if (DBGInt == null) { // Do we have a DBG interface? + server.setSoTimeout(1); // ??? + } + + newDBGInt = new PHPDBGInterface (getReader (newSocket), // Create a new interface + newSocket.getOutputStream (), + thisProxy); + newDBGInt.waitResponse (1000); // Wait for the initial DBG response + newDBGInt.flushAllPackets (); // Read and process the DBG response + + // Check version and session ID + if ((DBGInt == null) || // If we have no interface + (DBGInt.getSID () == newDBGInt.getSID ())) {// or the new session ID is different to the old one + DBGInt = newDBGInt; // Set the new interface as current one + + try { + closeSocket (); + } + catch (IOException e) { + PHPDebugCorePlugin.log (e); + shouldStop = true; + } + + socket = newSocket; + setBreakPoints (); + DBGInt.continueExecution (); // Notify DBG that PHP should continue + } + else { + newDBGInt.continueExecution (); // Notify DBG that PHP should continue + newSocket.close (); + } + } + + if (DBGInt.waitResponse (interval)) { // Wait for a DBG response (200 ms) + DBGInt.flushAllPackets (); // If we got something, read and process it + + if (DBGInt.BPUnderHit != 0) { // ??? + StackList = DBGInt.getStackList (); // Get the stack list from DBGInterface + + if (StackList.length > 0) { // If there is something in stack list + for (i = 0; i < StackList.length; i++) { // For all stack list + StackList[i].setThread (PHPMainThread); // Set the PHPTread for all PHPStackFrames + + if (DBGInt.getModByNo (StackList[i].getModNo ()).equals ("")) { + DBGInt.getSourceTree (); + } + + StackList[i].setFile (DBGInt.getModByNo (StackList[i].getModNo ())); + } + + PHPMainThread.setStackFrames (StackList); + } + + PHPMainThread.suspend (); // Fire debug event + + synchronized (this) { + wait (); + } + } + } + + if (remote) { + if (PHPMainThread.isTerminated ()) { + shouldStop = true; + + break; // Go for terminating the thread + } + } else { + if (PHPMainThread.isTerminated () || + getDebugTarget ().getProcess ().isTerminated ()) { + shouldStop = true; + + break; // Go for terminating the thread + } + } + } + } catch (Exception ex) { + PHPDebugCorePlugin.log (ex); + System.out.println (ex); + } finally { + try { + getDebugTarget ().terminate (); + closeSocket(); + closeServerSocket (); + } catch (IOException e) { + PHPDebugCorePlugin.log (e); + + return; + } + + //System.out.println("Socket loop finished."); + } + } + } } diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPDBGEvalString.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPDBGEvalString.java index 4225702..40afdb0 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPDBGEvalString.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPDBGEvalString.java @@ -25,17 +25,17 @@ public class PHPDBGEvalString { String workStr; private PHPStackFrame fStackFrame; - + public PHPDBGEvalString(PHPStackFrame stack,String dataStr) { fStackFrame=stack; workStr=dataStr; } - + String ExtractSubStr(char chstart, char chend,int startIdx) throws DebugException { int idx=startIdx; String rslt; if (idx >= (workStr.length() - 1) || workStr.charAt(idx) != chstart) { - Status status= new Status(Status.ERROR,PHPDebugCorePlugin.getUniqueIdentifier(),Status.OK,"worng startIdx!",null); + Status status= new Status(Status.ERROR,PHPDebugCorePlugin.getUniqueIdentifier(),Status.OK,"worng startIdx!",null); throw new DebugException(status); } int i = ++idx; @@ -49,11 +49,11 @@ public class PHPDBGEvalString { workStr=workStr.substring(i+1); return rslt; } - + String ExtractQuotedSubStr(int slen,int startIdx) throws DebugException { int idx=startIdx; String rslt; - if (idx+slen+1 >= workStr.length() || + if (idx+slen+1 >= workStr.length() || workStr.charAt(idx)!= '"' || workStr.charAt(idx+slen+1) != '"') { Status status= new Status(Status.ERROR,PHPDebugCorePlugin.getUniqueIdentifier(),Status.OK,"no quoted substring found!",null); @@ -64,7 +64,7 @@ public class PHPDBGEvalString { return rslt; } - + int ExtractInt(char chstart, char chend,int startIdx) throws DebugException { String subs; int rslt; @@ -91,7 +91,7 @@ public class PHPDBGEvalString { if (arritems > 0) { subitems = new Vector(); } else - if (workStr.charAt(0)!='}') + if (workStr.charAt(0)!='}') { Status status= new Status(Status.ERROR,PHPDebugCorePlugin.getUniqueIdentifier(),Status.OK,"no array endcharecter!",null); throw new DebugException(status); @@ -106,18 +106,18 @@ public class PHPDBGEvalString { } // value parse(((PHPVariable)tmplst.elementAt(0)).getValue().getValueString(),item, subitems, var_list, true,0); - + } ((PHPValue)item.getValue()).addVariable(subitems); workStr=workStr.substring(1); return item; } - + void ParseEvalNULL(String name,PHPVariable parent,Vector list, Vector var_list, int startIdx) throws DebugException { int idx=startIdx; if (idx >= workStr.length() || workStr.charAt(idx) != ';') { Status status= new Status(Status.ERROR,PHPDebugCorePlugin.getUniqueIdentifier(),Status.OK,"NULL not found!",null); - throw new DebugException(status); + throw new DebugException(status); } workStr=workStr.substring(1); PHPVariable item= new PHPVariable(fStackFrame, name,parent,"NULL",PHPValue.PEVT_UNKNOWN,null); @@ -125,7 +125,7 @@ public class PHPDBGEvalString { if (var_list!=null) var_list.add(item); } - + boolean ParseEvalInt( String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException { String subs=null; PHPVariable item; @@ -136,7 +136,7 @@ public class PHPDBGEvalString { var_list.add(item); return true; } - + boolean ParseEvalDouble(String name,PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException { String subs=null; PHPVariable item; @@ -147,7 +147,7 @@ public class PHPDBGEvalString { var_list.add(item); return true; } - + boolean ParseEvalString(String name,PHPVariable parent, Vector list, Vector var_list, boolean MakePhpStr, int startIdx) throws DebugException{ int slen; @@ -176,7 +176,7 @@ public class PHPDBGEvalString { var_list.add(item); return true; } - + boolean ParseEvalBool(String name,PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException{ long v; @@ -186,8 +186,8 @@ public class PHPDBGEvalString { if (var_list!=null) list.add(item); return true; - } - + } + boolean ParseEvalObject(String name,PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException{ int slen; @@ -199,7 +199,7 @@ public class PHPDBGEvalString { ParseEvalArray(name,parent, list, var_list, classname,PHPValue.PEVT_OBJECT); return true; } - + boolean ParseEvalResource(String name,PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException{ int v, slen; @@ -213,18 +213,18 @@ public class PHPDBGEvalString { return true; } - + boolean ParseEvalRef(String name,PHPVariable parent, Vector list, Vector var_list, boolean isSoftRef, int startIdx) throws DebugException{ int v; v=ExtractInt(':', ';',startIdx); - PHPVariable item= new PHPVariable(fStackFrame, name,parent,"",(isSoftRef)? (PHPValue.PEVT_SOFTREF): (PHPValue.PEVT_REF),null); + PHPVariable item= new PHPVariable(fStackFrame, name,parent,"",(isSoftRef)? (PHPValue.PEVT_SOFTREF): (PHPValue.PEVT_REF),null); v--; // ref ID is 1-based, EvalList is 0-based - if ((var_list==null) || (v<0) || (v >= var_list.size())) { + if ((var_list==null) || (v<0) || (v >= var_list.size())) { // item.ref = item; // self-resolving return true; } else { @@ -237,63 +237,77 @@ public class PHPDBGEvalString { // TODO Auto-generated catch block e.printStackTrace(); } - list.add(item); + list.add(item); } - + return true; } - - public PHPVariable[] getVars(){ - Vector list=new Vector(); - Vector var_list=new Vector(); - parse("",null,list,var_list,false,0); - return (PHPVariable[])list.toArray(new PHPVariable[list.size()]); + + /** + * + * @return The array of PHPVariables + */ + public PHPVariable[] getVars () { + Vector list = new Vector (); + Vector var_list = new Vector (); + + parse ("", null, list, var_list, false, 0); + + return (PHPVariable[]) list.toArray (new PHPVariable[list.size ()]); // Convert the list to an array and return the array + } + + /** + * + * @return The array of PHPVariables + */ + public Vector getVariables () { + Vector list = new Vector (); + Vector var_list = new Vector (); + + parse ("", null, list, var_list, false, 0); + + return list; // return the PHPVariable list } - - boolean parse(String name,PHPVariable parent, Vector list, Vector var_list, boolean MakePhpStr,int startIdx) { + + /** + * + * @param name + * @param parent + * @param list + * @param var_list + * @param MakePhpStr + * @param startIdx + */ + boolean parse (String name, PHPVariable parent, Vector list, Vector var_list, boolean MakePhpStr, int startIdx) { boolean ret_val = false; + char ch; + + if (startIdx >= workStr.length ()) { + return false; + } + + ch = workStr.charAt (startIdx); + workStr = workStr.substring (1); - if (startIdx >= workStr.length()) return false; - char ch = workStr.charAt(startIdx); - workStr=workStr.substring(1); try { switch (ch) { - case 'N': - ParseEvalNULL(name,parent, list, var_list, startIdx); - break; - case 'i': - ParseEvalInt(name,parent, list, var_list, startIdx); - break; - case 'd': - ParseEvalDouble(name,parent, list, var_list, startIdx); - break; - case 's': - ParseEvalString(name,parent, list, var_list, MakePhpStr, startIdx); - break; - case 'a': - ParseEvalArray(name,parent, list, var_list, "", PHPValue.PEVT_ARRAY); - break; - case 'O': - ParseEvalObject(name,parent, list, var_list, startIdx); - break; - case 'b': - ParseEvalBool(name,parent, list, var_list, startIdx); - break; - case 'z': - ParseEvalResource(name,parent, list, var_list, startIdx); - break; - case 'R': - ParseEvalRef(name,parent, list, var_list, false, startIdx); - break; - case 'r': - ParseEvalRef(name,parent, list, var_list, true, startIdx); - break; + case 'N': ParseEvalNULL (name, parent, list, var_list, startIdx); break; + case 'i': ParseEvalInt (name, parent, list, var_list, startIdx); break; + case 'd': ParseEvalDouble (name, parent, list, var_list, startIdx); break; + case 's': ParseEvalString (name, parent, list, var_list, MakePhpStr, startIdx); break; + case 'a': ParseEvalArray (name, parent, list, var_list, "", PHPValue.PEVT_ARRAY); break; + case 'O': ParseEvalObject (name, parent, list, var_list, startIdx); break; + case 'b': ParseEvalBool (name, parent, list, var_list, startIdx); break; + case 'z': ParseEvalResource (name, parent, list, var_list, startIdx); break; + case 'R': ParseEvalRef (name, parent, list, var_list, false, startIdx); break; + case 'r': ParseEvalRef (name, parent, list, var_list, true, startIdx); break; } } catch (DebugException e) { // TODO Auto-generated catch block e.printStackTrace(); } + /* if (!ret_val) { // try to recover unsigned int i=*startIdx; while (i 0; + + return variables.length > 0; // Is there something within the array? } public int getLineNumber() { return lineNumber; } + public void setLineNumber(int line) { + lineNumber = line; + } + public int getCharStart() throws DebugException { // not supported return -1; @@ -154,25 +212,43 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame { return false; } - public void stepInto() throws DebugException { - thread.prepareForResume() ; - this.getPHPDBGProxy().readStepIntoEnd(PHPStackFrame.this) ; - DebugEvent ev = new DebugEvent(this.getThread(), DebugEvent.RESUME, DebugEvent.STEP_INTO); - DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev }); + /** + * + */ + public void stepInto () throws DebugException { + DebugEvent ev; + + thread.prepareForResume (DebugEvent.STEP_INTO); // Don't know why, but this is necessary + this.getPHPDBGProxy ().readStepIntoEnd (PHPStackFrame.this); + + ev = new DebugEvent (this.getThread (), DebugEvent.RESUME, DebugEvent.STEP_INTO); + DebugPlugin.getDefault().fireDebugEventSet (new DebugEvent[] { ev }); } - public void stepOver() throws DebugException { - thread.prepareForResume() ; - this.getPHPDBGProxy().readStepOverEnd(PHPStackFrame.this) ; - DebugEvent ev = new DebugEvent(this.getThread(), DebugEvent.RESUME, DebugEvent.STEP_OVER); - DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev }); + /** + * + */ + public void stepOver () throws DebugException { + DebugEvent ev; + + thread.prepareForResume (DebugEvent.STEP_OVER); + this.getPHPDBGProxy ().readStepOverEnd (PHPStackFrame.this) ; + + ev = new DebugEvent (this.getThread (), DebugEvent.RESUME, DebugEvent.STEP_OVER); + DebugPlugin.getDefault ().fireDebugEventSet (new DebugEvent[] { ev }); } - public void stepReturn() throws DebugException { - thread.prepareForResume() ; - this.getPHPDBGProxy().readStepReturnEnd(PHPStackFrame.this) ; - DebugEvent ev = new DebugEvent(this.getThread(), DebugEvent.RESUME, DebugEvent.STEP_RETURN); - DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev }); + /** + * + */ + public void stepReturn () throws DebugException { + DebugEvent ev; + + thread.prepareForResume (DebugEvent.STEP_RETURN); + this.getPHPDBGProxy ().readStepReturnEnd (PHPStackFrame.this) ; + + ev = new DebugEvent (this.getThread (), DebugEvent.RESUME, DebugEvent.STEP_RETURN); + DebugPlugin.getDefault ().fireDebugEventSet (new DebugEvent[] { ev }); } @@ -213,8 +289,10 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame { public PHPDBGProxy getPHPDBGProxy() { PHPDebugTarget DebugTarget; - DebugTarget= (PHPDebugTarget)thread.getDebugTarget(); - return DebugTarget.getPHPDBGProxy(); + + DebugTarget = (PHPDebugTarget) thread.getDebugTarget (); + + return DebugTarget.getPHPDBGProxy (); } public void setFile(String file) { diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPThread.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPThread.java index efc55ea..c6508e8 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPThread.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPThread.java @@ -26,46 +26,49 @@ import org.eclipse.ui.model.IWorkbenchAdapter; public class PHPThread extends PHPDebugElement implements IThread { - private PHPStackFrame[] frames; - - private PHPDebugTarget target; - - private String name; - - private int id; + private PHPStackFrame[] frames; // The stackframes which belongs to this thread + private PHPDebugTarget target; // + private String name; // + private int id; // The port number through which we communicate to DBG private class State { - private boolean isSuspended = false; - + private boolean isSuspended = false; private boolean isTerminated = false; + private boolean isStepping = false; - private boolean isStepping = false; - - boolean isSuspended() { + boolean isSuspended () { return isSuspended; } - boolean isTerminated() { + boolean isTerminated () { return isTerminated; } - boolean isStepping() { + boolean isStepping () { return isStepping; } - void setSuspended(boolean suspended) { - if (isTerminated()) - throw new IllegalStateException(); - if (suspended && isStepping()) + void setSuspended (boolean suspended) { + if (isTerminated ()) { throw new IllegalStateException(); + } + + if (suspended && isStepping ()) { + throw new IllegalStateException (); + } + isSuspended = suspended; } - void setStepping(boolean stepping) { - if (stepping && !isSuspended()) - throw new IllegalStateException(); - if (isTerminated()) - throw new IllegalStateException(); + void setStepping (boolean stepping) { + if (stepping && !isSuspended ()) { + throw new IllegalStateException (); + } + + if (isTerminated ()) { + throw new IllegalStateException (); + } + isStepping = stepping; } @@ -74,34 +77,43 @@ public class PHPThread extends PHPDebugElement implements IThread { } } - private final State state = new State(); + private final State state = new State (); - public PHPThread (PHPDebugTarget target, int id) { + /** + * @param target + * @param id The port number through which we communicate to DBG + */ + public PHPThread (PHPDebugTarget target, int id) { super (target); + this.target = target; - this.setId(id); + this.setId (id); } - public IStackFrame[] getStackFrames() throws DebugException { + /** + * + */ + public IStackFrame[] getStackFrames () throws DebugException { return frames; } - public int getStackFramesSize() { + public int getStackFramesSize () { return frames.length; } - public boolean hasStackFrames() { + public boolean hasStackFrames () { if (frames == null) { return false; } + return frames.length > 0; } - public int getPriority() throws DebugException { + public int getPriority () throws DebugException { return 0; } - public IStackFrame getTopStackFrame() throws DebugException { + public IStackFrame getTopStackFrame () throws DebugException { if (frames == null || frames.length == 0) { return null; } @@ -140,19 +152,34 @@ public class PHPThread extends PHPDebugElement implements IThread { return state.isSuspended; } - protected void prepareForResume() { - state.setSuspended(false); - this.frames = null; - DebugEvent ev = new DebugEvent(this, DebugEvent.RESUME, - DebugEvent.CLIENT_REQUEST); - DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev }); + /** + * + * Is called from PHPstackframe whenever a stepInto, stepOver or stepReturn is + * to be performed + * + * @param de + */ + protected void prepareForResume (int de) { + DebugEvent ev; + + state.setSuspended (false); // We will leave the suspended state + this.frames = null; // Reset the stackframes + ev = new DebugEvent (this, DebugEvent.RESUME, de); // Create an event resume by stepping + + DebugPlugin.getDefault ().fireDebugEventSet (new DebugEvent[] { ev }); // Fire the event } - public synchronized void resume() throws DebugException { - if (!isSuspended()) - return; - this.prepareForResume(); - ((PHPDebugTarget) this.getDebugTarget()).getPHPDBGProxy().resume(); + /** + * + */ + public synchronized void resume () throws DebugException { + if (!isSuspended ()) { // Is the thread in suspended state? + return; // No, leave here + } + + this.prepareForResume (DebugEvent.STEP_OVER); // Use a STEP_OVER here because a 0 leads to a collapsing variable tree in UI + + ((PHPDebugTarget) this.getDebugTarget ()).getPHPDBGProxy ().resume (); } /* @@ -161,82 +188,141 @@ public class PHPThread extends PHPDebugElement implements IThread { * this.createName(suspensionPoint) ; this.suspend() ; } */ - public synchronized void suspend() throws DebugException { - if (isSuspended()) - return; - state.setSuspended(true); - state.setStepping(false); - getDebugTarget().suspend(); - DebugEvent ev = new DebugEvent(this, DebugEvent.SUSPEND, - DebugEvent.BREAKPOINT); - DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev }); + public synchronized void suspend () throws DebugException { + DebugEvent ev; + + if (isSuspended ()) { // Is the thread in suspend state? + return; // Yes, leave here + } + + state.setSuspended (true); // Set thread to suspended state + state.setStepping (false); // Reset thread from stepping state + + getDebugTarget ().suspend (); // + + ev = new DebugEvent (this, DebugEvent.SUSPEND, DebugEvent.BREAKPOINT); + + DebugPlugin.getDefault ().fireDebugEventSet (new DebugEvent[] { ev }); } - public boolean canStepInto() { - return isSuspended() && isStepping() && this.hasStackFrames(); + /** + * + */ + public boolean canStepInto () { + return isSuspended () && // Is the thread in suspended mode (stopped) + isStepping () && // and ??? + this.hasStackFrames (); // and does this thread have stack frames? } - public boolean canStepOver() { - return isSuspended() && isStepping() && this.hasStackFrames(); + /** + * + */ + public boolean canStepOver () { + return isSuspended () && // Is the thread in suspended mode (stopped) + isStepping () && // and ??? + this.hasStackFrames (); // and does this thread have stack frames? } - public boolean canStepReturn() { - return isSuspended() && isStepping() && this.hasStackFrames(); + /** + * + */ + public boolean canStepReturn () { + return isSuspended () && // Is the thread in suspended mode (stopped) + isStepping () && // and ??? + this.hasStackFrames (); // and does this thread have stack frames? } - public boolean isStepping() { - return state.isStepping(); + /** + * + */ + public boolean isStepping () { + return state.isStepping (); } - public void stepInto() throws DebugException { - try { state.setStepping(true); } + /** + * + */ + public void stepInto () throws DebugException { + try { + state.setStepping (true); // Store the info about what we do + } catch (IllegalStateException x) { - throw new DebugException(PHPeclipsePlugin.error(x)); + throw new DebugException (PHPeclipsePlugin.error (x)); } + this.frames = null; - frames[0].stepInto(); + + frames[0].stepInto (); } - public void stepOver() throws DebugException { - state.setStepping(true); + /** + * + */ + public void stepOver () throws DebugException { + state.setStepping (true); + this.frames = null; - frames[0].stepOver(); + + frames[0].stepOver (); } - public void stepReturn() throws DebugException { + /** + * + */ + public void stepReturn () throws DebugException { } - public boolean canTerminate() { - return !isTerminated(); + /** + * + */ + public boolean canTerminate () { + return !isTerminated (); } - public boolean isTerminated() { - return state.isTerminated(); + /** + * + */ + public boolean isTerminated () { + return state.isTerminated (); } - public synchronized void terminate() throws DebugException { - if (isTerminated()) + /** + * + */ + public synchronized void terminate () throws DebugException { + if (isTerminated ()) { return; - state.setTerminated(true); + } + + state.setTerminated (true); this.frames = null; - getDebugTarget().terminate(); + getDebugTarget ().terminate (); } - public Object getAdapter(Class arg0) { - if (IWorkbenchAdapter.class.equals(arg0)) { + /** + * + * @param arg0 + * @return + */ + public Object getAdapter (Class arg0) { + if (IWorkbenchAdapter.class.equals (arg0)) { return new IWorkbenchAdapter() { public Object[] getChildren(Object o) { Object[] children = null; + try { IStackFrame[] frames = getStackFrames(); + if (null != frames) { children = new Object[frames.length]; - for (int i = 0; i < frames.length; ++i) + for (int i = 0; i < frames.length; ++i) { children[i] = frames[i]; + } } } catch (DebugException x) { - PHPeclipsePlugin.log("Unable to get stack frames.", x); - } + PHPeclipsePlugin.log ("Unable to get stack frames.", x); + } + return children; } @@ -253,21 +339,33 @@ public class PHPThread extends PHPDebugElement implements IThread { } }; } + return null; } + /** + * + */ public void setStackFrames(PHPStackFrame[] frames) { this.frames = frames; } - public String getName() { - String name = this.name; - if (isSuspended()) + /** + * + */ + public String getName () { + String name; + + name = this.name; + + if (isSuspended ()) { name = name + " (suspended)"; + } + return name; } - public void setName(String name) { + public void setName (String name) { this.name = name; } diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPValue.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPValue.java index caecb89..bf97de2 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPValue.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPValue.java @@ -23,56 +23,93 @@ import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.IVariable; +/** + * PHPValue object belongs to a PHPVariable (is a member of PHPVariable). + * A PHPValue itself can have PHPVariables as children. + * + */ public class PHPValue implements IValue { - - final static String[] PEV_NAMES={"undefined","long","double","string","array", - "object","boolean","resource","reference","soft reference"}; - final static int PEVT_UNKNOWN =0; - final static int PEVT_LONG = 1; - final static int PEVT_DOUBLE=2; - final static int PEVT_STRING=3; - final static int PEVT_ARRAY=4; - final static int PEVT_OBJECT=5; - final static int PEVT_BOOLEAN=6; - final static int PEVT_RESOURCE=7; - final static int PEVT_REF=8; - final static int PEVT_SOFTREF=9; - - private int fValueType; - private boolean hasChildren; - private String fValueString; - private Vector fVariables; - private PHPStackFrame fStackFrame; - - PHPValue() { - this(null,"",PEVT_UNKNOWN,null); - } - - PHPValue(PHPStackFrame frame,String value,int fValueType,Vector subitems) + + final static String[] PEV_NAMES = {"undefined", // 0 + "long", // 1 + "double", // 2 + "string", // 3 + "array", // 4 + "object", // 5 + "boolean", // 6 + "resource", // 7 + "reference", // 8 + "soft reference"}; // 9 + final static int PEVT_UNKNOWN = 0; + final static int PEVT_LONG = 1; + final static int PEVT_DOUBLE = 2; + final static int PEVT_STRING = 3; + final static int PEVT_ARRAY = 4; + final static int PEVT_OBJECT = 5; + final static int PEVT_BOOLEAN = 6; + final static int PEVT_RESOURCE = 7; + final static int PEVT_REF = 8; + final static int PEVT_SOFTREF = 9; + + private int fValueType; // The type of this value (see the PEVT_... values) + private boolean hasChildren; // This value (variable) has children (more variables) + private String fValueString; // The value of this variable as text + private Vector fVariables; // The children of this variable (other variables) if any + private PHPStackFrame fStackFrame; // The stackframe this value (variable) belongs to + // + + /** + * + */ + PHPValue () { + this (null, "", PEVT_UNKNOWN, null); // Creates an empty value + } + + /** + * + * @param frame The stackframe this value (and variable) belongs to. + * @param value The value of this value. + * @param fValueType The type of this value (see the PEVT_... values). + * @param subitems This value has subitems. + */ + PHPValue (PHPStackFrame frame, String value, int fValueType, Vector subitems) { - this.fValueType=fValueType; - this.fValueString=value; - this.fStackFrame=frame; - if (subitems !=null) - this.fVariables=new Vector(subitems); - else - this.fVariables = new Vector(); - } - - Vector addVariable(Vector item) - { - if (item!=null) - this.fVariables.addAll(item); + this.fValueType = fValueType; + this.fValueString = value; + this.fStackFrame = frame; + + if (subitems != null) { // If there are children for this value (variable) + this.fVariables = new Vector (subitems); // Then add the children to this value (variable) + } + else { + this.fVariables = new Vector (); // Create an empty vector + } + } + + /** + * + * @param item + */ + Vector addVariable (Vector item) + { + if (item != null) { // If there is something we want to add + this.fVariables.addAll (item); // + } + return this.fVariables; } - - public void setParent(PHPVariable parent) { - if (!fVariables.isEmpty()) { - Iterator iter=fVariables.iterator(); - while (iter.hasNext()) { - ((PHPVariable)iter.next()).setParent(parent); + + /** + * + * @param parent + */ + public void setParent (PHPVariable parent) { + if (!fVariables.isEmpty ()) { // If we have child variables + Iterator iter = fVariables.iterator (); // Create an iterator for the children + + while (iter.hasNext ()) { // As long as we have children + ((PHPVariable) iter.next ()).setParent (parent); // Set all child's parent } - } } @@ -82,13 +119,28 @@ public class PHPValue implements IValue { public String getReferenceTypeName(){ return PEV_NAMES[fValueType]; } - + + /** + * + */ public int getReferenceType(){ return fValueType; } - - public int setReferenceType(int type){ - return fValueType=type; + + /** + * @param type Set the reference type (see the PEVT_... values). + */ + public int setReferenceType (int type) { + return fValueType = type; + } + + /** + * This method is called whenever this value (variable) is changed. + * + * @param value The changed value for this variable. + */ + public void setValueString (String value) { + fValueString = value; } /** @@ -107,17 +159,33 @@ public class PHPValue implements IValue { /** * @see org.eclipse.debug.core.model.IValue#getVariables() + * + * @return The array of child variable for this value (variable). */ public IVariable[] getVariables() { - return (PHPVariable[])fVariables.toArray(new PHPVariable[fVariables.size()]); + return (PHPVariable[]) fVariables.toArray (new PHPVariable[fVariables.size ()]); // return (IVariable[])fVariables.toArray(); } /** + * + */ + public Vector getChildVariables () { + return (fVariables); + } + + /** * @see org.eclipse.debug.core.model.IValue#hasVariables() + * + * @return + *
    + *
  • true if this value (variable) has child variables + *
  • false if no child variable available + *
*/ public boolean hasVariables() throws DebugException { - return (!fVariables.isEmpty()); + // return (!fVariables.isEmpty ()); + return (fVariables.size () != 0); } /** @@ -128,7 +196,7 @@ public class PHPValue implements IValue { return null; } - /** + /** * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget() */ public IDebugTarget getDebugTarget() { diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPVariable.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPVariable.java index fdb3b81..0cdad2a 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPVariable.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPVariable.java @@ -21,48 +21,76 @@ import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.IVariable; + +/** + * + */ public class PHPVariable implements IVariable { - - private PHPValue fValue; - private String fName; - private PHPStackFrame fStackFrame; - private PHPVariable fParent; - private String fLongName; - - PHPVariable(){ - this(null,"",null,"",PHPValue.PEVT_UNKNOWN,null); - } - - PHPVariable(PHPStackFrame frame,String name, PHPVariable parent,String value,int valueType,Vector subitems) + private PHPValue fValue; // The value of this variable + private String fName; // The name of the variable + private PHPStackFrame fStackFrame; // The stackframe this variable belongs to + private PHPVariable fParent; // The parent variable (a back link) + private String fLongName; // ??? + private boolean fHasChanged; // + + /** + * + */ + PHPVariable () { + this (null, "", null, "", PHPValue.PEVT_UNKNOWN, null); // create an empty variable (a simple dummy node?) + } + + /** + * + * @param frame The stackframe this variable belongs to + * @param name The name for this variable + * @param parent The parent variable if this is not the root + * @param value The value of this variable which is a simple value or again a variable + * @param valueType The type of the value (e.g. int, double, string etc.) @see PHPValue + * @param subitems + */ + PHPVariable (PHPStackFrame frame, String name, PHPVariable parent, String value, int valueType, Vector subitems) { - this.fStackFrame=frame; - this.fValue=new PHPValue(frame,value,valueType,subitems); - this.fParent=parent; - setName(name); + this.fStackFrame = frame; + this.fValue = new PHPValue (frame, value, valueType, subitems); + this.fParent = parent; + this.fHasChanged = false; + + setName (name); } - - private void setName(String name) { - if ((fParent==null) || (fParent.getName()=="")) { - fLongName=name; - fName=name; + + /** + * + * @param name + */ + private void setName (String name) { + if ((fParent == null) || // If we have no parent for this variable + (fParent.getName () == "")) { // or we have a parent which is just a simple node ??? + fLongName = name; // Set the long name + fName = name; // and set the name + return; } - switch (fParent.getReferenceType()) { - case PHPValue.PEVT_ARRAY : - fName="['"+name+"']"; - fLongName=fParent.getLongName()+fName; - break; - case PHPValue.PEVT_OBJECT : - fName=name; - fLongName=fParent.getLongName()+"."+fName; - break; - default : - fName=name; - fLongName=name; - break; + + switch (fParent.getReferenceType ()) { // Get the type of the parent variable + case PHPValue.PEVT_ARRAY : // It's an array + fName = "['" + name + "']"; // So set the variable name as [name] + fLongName = fParent.getLongName () + fName; // Set the longname to parentVariableLongname[name] + break; + + case PHPValue.PEVT_OBJECT : // It's an object + fName = name; // Set the name to name + fLongName = fParent.getLongName () + "." + fName; // Set the longname to parentVariableLongname.name + break; + + default : + fName = name; // Set the name to name + fLongName = name; // Set the Longname to name + break; } } + /** * @see org.eclipse.debug.core.model.IVariable#getValue() */ @@ -76,18 +104,27 @@ public class PHPVariable implements IVariable { public String getName() { return fName; } - + + /** + * + */ public PHPVariable getParent() { return fParent; } - + + /** + * + */ public void setParent(PHPVariable parent) { this.fParent=parent; fLongName=parent.getLongName()+fName; } - + + /** + * + */ public String getLongName() { return fLongName; } @@ -98,11 +135,17 @@ public class PHPVariable implements IVariable { public String getReferenceTypeName() { return fValue.getReferenceTypeName(); } - + + /** + * + */ public int getReferenceType() { return fValue.getReferenceType(); } - + + /** + * + */ public int setReferenceType(int type) { return ((PHPValue) getValue()).setReferenceType(type); } @@ -112,10 +155,22 @@ public class PHPVariable implements IVariable { */ public boolean hasValueChanged() throws DebugException { // TODO Auto-generated method stub - return false; + // return false; + return fHasChanged; } - - /** + + /** + * + * @param changed This method is called after a suspend when the list of + * variables is updated, to mark that this variable has a changed + * value. The variable view will show this variable in + * a different color. + */ + public void setValueChanged (boolean changed) { + fHasChanged = changed; + } + + /** * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier() */ public String getModelIdentifier() { @@ -136,7 +191,6 @@ public class PHPVariable implements IVariable { return getDebugTarget().getLaunch(); } - /** * @see org.eclipse.debug.core.model.IValueModification#setValue(java.lang.String) */ @@ -187,40 +241,49 @@ public class PHPVariable implements IVariable { public Object getAdapter(Class adapter) { return Platform.getAdapterManager().getAdapter(this, adapter); } - - public String toString() { - int type=-1; - String str=""; - - switch (getReferenceType()) - { - case PHPValue.PEVT_ARRAY : - int elements=fValue.getVariables().length; - switch (elements) { - case 0: - str= this.getName() + " [no elements]"; - break; - case 1: - str= this.getName() + " [1 element]"; - break; - default: - str= this.getName() + " [" + elements + " elements]"; - break; + + /** + * This method is called from variable view and denominates the variables with + * a type specific explanation. + * + */ + public String toString () { + int type = -1; + String str = ""; + + switch (getReferenceType ()) { + case PHPValue.PEVT_ARRAY : // Variable is an array + int elements = fValue.getVariables ().length; // Get the number of child elements + + switch (elements) { // Switch for the number of child elements + case 0: // We have no child element + str = this.getName () + " [no elements]"; // string => 'varname [no elements]' + break; + + case 1: // We have exactly one child element + str = this.getName () + " [1 element]"; // string => 'varname [1 element]' + break; + + default: // We have more than one element + str = this.getName () + " [" + elements + " elements]"; // string => 'varname [x elements]' + break; } break; - case PHPValue.PEVT_OBJECT : - str =this.getName() + " [class: " + fValue.getValueString() + "]"; + + case PHPValue.PEVT_OBJECT : // Variable is an object + str = this.getName () + " [class: " + fValue.getValueString() + "]"; // string => 'varname [class: varvalue]' break; - case PHPValue.PEVT_STRING : - str =this.getName() + " = \"" + fValue.getValueString() +"\"" ; + + case PHPValue.PEVT_STRING : // Variable is a string + str = this.getName () + " = \"" + fValue.getValueString() +"\"" ; // string => 'varname = "varvalue"' break; - case PHPValue.PEVT_SOFTREF : - default : - str =this.getName() + " = " + fValue.getValueString(); + + case PHPValue.PEVT_SOFTREF : // Variable is a soft reference + default : // or anything else + str = this.getName () + " = " + fValue.getValueString(); // string => 'varname = varvalue' break; } - + return str; - } } -- 1.7.1 From 4f4f0252522e44a2181abb9c3380308dd9b63a44 Mon Sep 17 00:00:00 2001 From: axelcl Date: Sat, 15 Oct 2005 20:52:43 +0000 Subject: [PATCH 11/16] Patches from Robert Kraske (robekras): * collapsing variable tree * more documentation --- net.sourceforge.phpeclipse.debug.core/build.xml | 79 ++++++++++++----------- 1 files changed, 40 insertions(+), 39 deletions(-) diff --git a/net.sourceforge.phpeclipse.debug.core/build.xml b/net.sourceforge.phpeclipse.debug.core/build.xml index e205d70..1c20c6b 100644 --- a/net.sourceforge.phpeclipse.debug.core/build.xml +++ b/net.sourceforge.phpeclipse.debug.core/build.xml @@ -56,46 +56,47 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + @@ -172,7 +173,7 @@ - + -- 1.7.1 From 1eab445d328049f16f25428bc78adb2c86800f32 Mon Sep 17 00:00:00 2001 From: robekras Date: Sun, 16 Oct 2005 10:11:04 +0000 Subject: [PATCH 12/16] 1) Added the extension point for the watchExpressionDelegate --- net.sourceforge.phpeclipse.debug.core/plugin.xml | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/net.sourceforge.phpeclipse.debug.core/plugin.xml b/net.sourceforge.phpeclipse.debug.core/plugin.xml index f88fbc1..b197872 100644 --- a/net.sourceforge.phpeclipse.debug.core/plugin.xml +++ b/net.sourceforge.phpeclipse.debug.core/plugin.xml @@ -74,4 +74,10 @@ relationship="stack"/> + + + + -- 1.7.1 From addbbe87dda6a9e65cf6071b8f27729989a8fdec Mon Sep 17 00:00:00 2001 From: robekras Date: Sun, 16 Oct 2005 18:11:44 +0000 Subject: [PATCH 13/16] 1) Added a vector for storing the variables. 2) getVariables now read the variables as a vector list. 3) Added a findVariable method which can be called recursiv (which looks for a variable through the entire variable tree). 4) Changed the 'old' findVariable method the call the new method (means hover works now). 5) Added setIndex method for stackframe replication. 6) Added compareTo method for stackframe list sorting. --- .../internal/debug/core/model/PHPStackFrame.java | 94 ++++++++++++++++---- 1 files changed, 75 insertions(+), 19 deletions(-) diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPStackFrame.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPStackFrame.java index 4130898..a819140 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPStackFrame.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPStackFrame.java @@ -11,6 +11,8 @@ Contributors: **********************************************************************/ package net.sourceforge.phpdt.internal.debug.core.model; +import java.util.Vector; + import net.sourceforge.phpdt.internal.debug.core.PHPDBGProxy; import org.eclipse.debug.core.DebugEvent; @@ -23,14 +25,20 @@ import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; import org.eclipse.debug.core.model.IVariable; -public class PHPStackFrame extends PHPDebugElement implements IStackFrame { +/** + * + * TODO Remove the variables array and use only the varList vector + * Have also to change hasVariables + */ +public class PHPStackFrame extends PHPDebugElement implements IStackFrame, Comparable{ private PHPThread thread; // The thread to which this stackframe belongs private String file; // The file name??? private int lineNumber; // private int index; // private int modno; // - private PHPVariable[] variables; // The array of variables + private PHPVariable[] variables; // The array of variables TODO: better introduce a vector? + private Vector varList = new Vector (); private String description; // /** @@ -96,39 +104,60 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame { * @return The array of PHPVariables for this stackframe. */ public IVariable[] getVariables() throws DebugException { - PHPVariable[] variablesNew; // The intermediate storage of the variable array we get from DBG proxy + //PHPVariable[] variablesNew; // The intermediate storage of the variable array we get from DBG proxy + + //variablesNew = this.getPHPDBGProxy ().readVariables (this); // Get the variable array from DBG proxy + //variables = variablesNew; // Store the array the stackframes member variable + varList = this.getPHPDBGProxy ().readVariables (this); - variablesNew = this.getPHPDBGProxy ().readVariables (this); // Get the variable array from DBG proxy - variables = variablesNew; // Store the array the stackframes member variable + variables = (PHPVariable[]) varList.toArray (new PHPVariable[varList.size ()]); return variables; // Give the array back to user interface } /** - * TODO Is this really used (who calls this) - * I think this method could be removed * - * @param s The variables name we are looking for. - * @return */ - public IVariable findVariable (String s) throws DebugException { - String name; - int i; - - if (this.hasVariables ()) { // Does this stackframe have variables? - name = "$" + s; // Prefix the variable name with $ - - for (i = 0; i < variables.length; i++) { // For all variables - if ((variables[i].getName ()).equals (name)) { - return variables[i]; + private PHPVariable findVariable (Vector varList, String varname) { + PHPVariable variable; + PHPValue value; + int i; + + for (i = 0; i < varList.size (); i++) { // For all variables + variable = (PHPVariable) varList.get (i); // Get the variable + value = (PHPValue) variable.getValue (); // Get the value of the variable + + try { + if (value.hasVariables ()) { // Does the variable/value have children + variable = findVariable (value.getChildVariables (), varname); + + if (variable != null) { + return variable; + } + } + else if ((variable.getName ()).equals (varname)) { // + return variable; // } } + catch (DebugException e) { // That's, because of the hasVariables method + } } return null; } /** + * This method is called from the UI (e.g. from PHPDebugHover + * to find the variable the mouse is pointing to) + * + * @param s The variable name we are looking for. + * @return + */ + public IVariable findVariable (String s) throws DebugException { + return (findVariable (varList, s)); // Prefix the variable name with $ + } + + /** * */ public boolean hasVariables () throws DebugException { @@ -287,6 +316,10 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame { return index; } + public void setIndex (int index) { + this.index = index; + } + public PHPDBGProxy getPHPDBGProxy() { PHPDebugTarget DebugTarget; @@ -302,4 +335,27 @@ public class PHPStackFrame extends PHPDebugElement implements IStackFrame { public int getModNo() { return modno; } + + /** + * This function is needed when sorting the stackframes by their index numbers. + * + * @param obj The stackframe which this one is compared to. + * @return + *
    + *
  • -1 if the index of this stackframe is less. + *
  • 0 if the index of both stackfream is equal (should no happen). + *
  • 1 if the index of this stackfram is greater. + *
+ */ + public int compareTo (Object obj) + { + if (index < ((PHPStackFrame) obj).getIndex ()) { + return -1; + } + else if (index > ((PHPStackFrame) obj).getIndex ()) { + return 1; + } + + return 0; + } } -- 1.7.1 From fcade0583469b29dc7611bce6c0b06ba16d7f8c4 Mon Sep 17 00:00:00 2001 From: robekras Date: Sun, 16 Oct 2005 18:13:16 +0000 Subject: [PATCH 14/16] 1) readVariables returns variables as a vector list. --- .../phpdt/internal/debug/core/PHPDBGProxy.java | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java index db66060..e09edcb 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java @@ -15,6 +15,7 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; import java.util.Map; +import java.util.Vector; import net.sourceforge.phpdt.internal.debug.core.breakpoints.PHPLineBreakpoint; import net.sourceforge.phpdt.internal.debug.core.model.PHPDebugTarget; @@ -367,9 +368,9 @@ public class PHPDBGProxy { * It reads the variables from PHP via DBG * * @param frame The stackframe which wants the variables. - * @return The array of variables for this stackframe. + * @return The list of variables for this stackframe. */ - public PHPVariable[] readVariables (PHPStackFrame frame) { + public Vector readVariables (PHPStackFrame frame) { try { return DBGInt.getVariables (frame); // Get the variables from DBG interface } catch (IOException ioex) { -- 1.7.1 From 5f09b5a930e81c35cea0c067ad4d13f2a8dce6f5 Mon Sep 17 00:00:00 2001 From: robekras Date: Sun, 16 Oct 2005 18:19:32 +0000 Subject: [PATCH 15/16] 1) getVariables returns variables as a vector list. 2) Replicate the index number of the stackframes 3) Sort the 'static' stackframe list by their index numbers. Necessary because the UI will not step into a source file if sorting of stackframes is not in correct order. 4) Modified comments for updateStackFrameList. --- .../phpdt/internal/debug/core/PHPDBGInterface.java | 25 ++++++++++++++++--- 1 files changed, 21 insertions(+), 4 deletions(-) diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java index 957c86e..d0576f9 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java @@ -15,6 +15,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.OutputStream; import java.util.Vector; +import java.util.Collections; import net.sourceforge.phpdt.internal.debug.core.model.PHPDBGEvalString; import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame; @@ -491,7 +492,7 @@ public class PHPDBGInterface { * @param stack The stackframe for which we want the variables. * @return The array of variables */ - public PHPVariable[] getVariables (PHPStackFrame stack) throws IOException, DebugException { + public Vector getVariables (PHPStackFrame stack) throws IOException, DebugException { PHPDBGPacket DBGPacket; PHPDBGFrame DBGFrame1; PHPDBGEvalString evalStr; @@ -516,7 +517,7 @@ public class PHPDBGInterface { evalStr = new PHPDBGEvalString (stack, serGlobals); // Process serialized variables updateVariableList (DBGVarList, evalStr.getVariables ()); // Replicate the 'static' variable list and the via DBG received variable list - return (PHPVariable[]) DBGVarList.toArray (new PHPVariable[DBGVarList.size ()]); // Convert the list to an array and return the array + return DBGVarList; // Convert the list to an array and return the array } /** @@ -677,10 +678,23 @@ public class PHPDBGInterface { * * The stackList contains the currently read stackframes which were sent * from DBG. The DBG interface holds a list of the active stack frames. - * This method looks whether the sent stackframes are already in the list. + * This method replicates the 'static' stackframe list with the DBG stackframe list + * Replication is done in the following way: + *
    + *
  • It looks for new stackframes within the DBG stackframe list and + * adds them to the 'static' list. + *
  • It looks for stackframes within the 'static' list, and removes them + * from the 'static' list in case the do not appear within the DBG list. + *
  • It looks for stackframes which are already existent and replicates the + * line number and the index number. + *
  • At the end the 'static' stackfram list has to be sorted by the stackframes + * index numbers. + *
+ * * Removes the unused stackframes from the list, or adds stackframes which * are not yet in the list. * + * * @param stackList */ private void updateStackFrameList (Vector stackList) { @@ -697,7 +711,8 @@ public class PHPDBGInterface { stackFrameOld = (PHPStackFrame) stackListOld.get (n); // --- if (stackFrameNew.getModNo () == stackFrameOld.getModNo ()) { // Did we find the sent stackframe within the list of old stackframes? - stackFrameOld.setLineNumber (stackFrameNew.getLineNumber()); + stackFrameOld.setLineNumber (stackFrameNew.getLineNumber ()); + stackFrameOld.setIndex (stackFrameNew.getIndex ()); break; // Yes, then break; } @@ -727,6 +742,8 @@ public class PHPDBGInterface { } } + Collections.sort (stackListOld); // Sort the 'static' stackframe list by the stackframe index numbers. + // newStackList = new PHPStackFrame[stackListOld.size ()]; newStackList = (PHPStackFrame[]) stackListOld.toArray (newStackList); DBGStackList = newStackList; -- 1.7.1 From 8c88498688f01977ab9edca417e65c7bd910c0de Mon Sep 17 00:00:00 2001 From: robekras Date: Tue, 18 Oct 2005 19:34:16 +0000 Subject: [PATCH 16/16] 1) A temporary fix for the recursion problem with the $GLOBALS array. --- .../phpdt/internal/debug/core/PHPDBGInterface.java | 50 ++++++++++++++++++-- 1 files changed, 45 insertions(+), 5 deletions(-) diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java index d0576f9..03a735f 100644 --- a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java @@ -394,6 +394,43 @@ public class PHPDBGInterface { } /** + * Go up the tree of PHPVariables + * look whether the PHPValue is a reference to a parent PHPValue + * + * TODO Check where this recursion can come from. + * Whether this back reference is legal or a bug. + * + * @param var + * @return + *
    + *
  • false if the PHPValue is not a child of itself + *
  • true if the PHPValue is + *
+ */ + + private boolean hasRecursion (PHPVariable var) { + PHPVariable parentVar; + PHPValue val; + + val = (PHPValue) var.getValue (); // Get the PHPValue from the current PHPVariable + + while (var != null) { // As long as we have PHPVariable + parentVar = var.getParent (); // Get the parent PHPVariable + + if (parentVar != null) { // Is there a parent? + if (parentVar.getValue ().equals (val)) { // Get the PHPValue for the parent PHPVariable and check + // whether it is the same + return true; // Return, if we have recursion + } + } + + var = parentVar; + } + + return false; // No recursion found + } + + /** * This method updates the 'static' variables list. * It does a replication between the 'static' list (the variable list which * is a member of this DBG interface object) and the DBG variable list @@ -436,10 +473,13 @@ public class PHPDBGInterface { valNew = (PHPValue) varNew.getValue (); // Get the value from DBG try { - if (valOld.hasVariables () || // If the 'static' value has child variables - valNew.hasVariables ()) { // or if the DBG value has child variables - updateVariableList (valOld.getChildVariables (), // Update the variable list for the child variables - valNew.getChildVariables ()); + if (valOld.hasVariables () || // If the 'static' value has child variables + valNew.hasVariables ()) { // or if the DBG value has child variables + if (!hasRecursion (varOld) && + !hasRecursion (varNew)) { // Both branches should not have a recursion + updateVariableList (valOld.getChildVariables (), // Update the variable list for the child variables + valNew.getChildVariables ()); + } } else if (!valOld.getValueString ().equals (valNew.getValueString ())) { // Has the value changed? valOld.setValueString (valNew.getValueString ()); // Yes, set the 'static' value (variable) to the new value @@ -517,7 +557,7 @@ public class PHPDBGInterface { evalStr = new PHPDBGEvalString (stack, serGlobals); // Process serialized variables updateVariableList (DBGVarList, evalStr.getVariables ()); // Replicate the 'static' variable list and the via DBG received variable list - return DBGVarList; // Convert the list to an array and return the array + return DBGVarList; // Return the variables as list } /** -- 1.7.1