From: fvicente Date: Wed, 30 Jul 2003 00:59:11 +0000 (+0000) Subject: First submit for debug plugin X-Git-Url: http://secure.phpeclipse.com First submit for debug plugin --- diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/Environment.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/Environment.java new file mode 100644 index 0000000..731c63a --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/Environment.java @@ -0,0 +1,42 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + R M Yorston - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core; + +public class Environment { + static { + java.lang.System.loadLibrary("Environment"); + } + + private Environment() { + } + + /** + * Gets an environment variable. An environment variable is a + * system-dependent external variable that has a string value. + * + * @param name name of the environment variable + * @return the value of the variable, or null if the + * variable is not defined. + */ + public static native String getenv(String name) ; + + /** + * Sets an environment variable. An environment variable is a + * system-dependent external variable that has a string value. + * + * @param name name of the environment variable + * @param value value to set + * @return 1 if variable could be set, 0 if not. + */ + public static native String setenv(String name, String value) ; + +} 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 new file mode 100644 index 0000000..a4ff01f --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGBase.java @@ -0,0 +1,125 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + Vicente Fernando - www.alfersoft.com.ar - Initial implementation +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core; + +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 */ + + // 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 PHPDBGBase() { + } + + 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]; + } + + 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; + return ret; + } + + public static int CharToInt(char ch) { + return (int) (ch & 0x00FF); + } + + 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); + + 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) + ") "; + } + 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]; + } + return ret; + } +} 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 new file mode 100644 index 0000000..6e9b777 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGFrame.java @@ -0,0 +1,80 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + Vicente Fernando - www.alfersoft.com.ar - Initial implementation +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core; + +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 void addInt(int num) { + char[] newData= PHPDBGBase.IntToChar4(num); + frameData.add(newData); + frameSize+= 4; + } + + public void addChar(char ch) { + char[] newData= new char[1]; + newData[0]= ch; + frameData.add(newData); + frameSize+= 1; + } + + public void addString(String str) { + frameData.add(str); + frameSize+= str.length(); + } + + public int getSize() { + return frameSize; + } + + public int getSizeOfData() { + return frameSize - FRAME_HEADER_SIZE; + } + + public char[] getHeader() { + char[] ret= new char[FRAME_HEADER_SIZE]; + + PHPDBGBase.copyChars(ret, frameType, 4); + PHPDBGBase.copyCharsTo(ret, PHPDBGBase.IntToChar4(getSizeOfData()), 4, 4); + return ret; + } + + 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; + } 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(); + } + } + } + return ret; + } +} \ 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 new file mode 100644 index 0000000..40b27b4 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGInterface.java @@ -0,0 +1,709 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + Vicente Fernando - www.alfersoft.com.ar - Initial implementation +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core; + +import java.io.IOException; +import java.io.BufferedReader; +import java.io.OutputStream; +import java.util.Vector; +import java.lang.System; +import org.eclipse.debug.core.DebugException; +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 net.sourceforge.phpdt.internal.debug.core.PHPDBGMod; + +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 Vector DBGVars= new Vector(); + private BufferedReader in; + private OutputStream os; + private boolean shouldStop= false, isRef= false, hasChildren= false, isObject= false; + private String evalRet= new String(""); + private String serGlobals= new String(""); + private String typeRead= new String(""); + private String className= new String(""); + private int finalPos=0, refCounter=0, rawCounter=0; + + public PHPDBGInterface(BufferedReader in, OutputStream os) { + DBGBPList.clear(); + this.in= in; + this.os= os; + } + + 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); + } + + public void requestDBGVersion() throws IOException { + PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST); + PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_VER); + + DBGPacket.addFrame(DBGFrame); + + DBGPacket.sendPacket(os); + } + + // 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; + + PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST); + PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_BPS); + PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA); + + modNo= getModByName(mod_name); + + if(modNo >= 0) { + DBGFrame1.addInt(modNo); // mod number + } else { + DBGFrame1.addInt(0); // mod number (0 use file name) + } + + DBGFrame1.addInt(line); // line number + + if(modNo >= 0) { + DBGFrame1.addInt(0); // use mod number + } else { + rawCounter++; + 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); + } + + // Second add command data + DBGPacket.addFrame(DBGFrame1); + + DBGPacket.sendPacket(os); + + clearLastBP(); + + // Wait response (1 second) and read response + waitResponse(1000); + flushAllPackets(); + + return LastBPRead[8]; + } + + private void clearLastBP() { + int i; + + for(i=0; i < LastBPRead.length; i++) + LastBPRead[i]= 0; + } + + private void copyToLastBP(int[] BPBody) { + int 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); + DBGPacket.sendPacket(os); + } + + private int getBPUnderHit() { + int i, BPUnder=0; + int[] dbg_bpl_body= new int[10]; + + // 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]; + } + } + return BPUnder; + } + + public void stepInto() throws IOException { + BPUnderHit= 0; + PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPINTO); + DBGPacket.sendPacket(os); + } + + public void stepOver() throws IOException { + BPUnderHit= 0; + PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOVER); + DBGPacket.sendPacket(os); + } + + public void stepOut() throws IOException { + BPUnderHit= 0; + PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOUT); + DBGPacket.sendPacket(os); + } + + public void stopExecution() throws IOException { + BPUnderHit= 0; + PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STOP); + DBGPacket.sendPacket(os); + } + + public PHPVariable[] getVariables(PHPStackFrame stack) throws IOException, DebugException { + PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST); + PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL); + //PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA); + + DBGFrame1.addInt(0); // istr = raw data ID + DBGFrame1.addInt(1); // scope_id = -1 means current location, 0 never used, +1 first depth + + /* + String evalBlock= new String("$GLOBALS"); + DBGFrame2.addInt(1); // FRAME_RAWDATA ID + DBGFrame2.addInt(evalBlock.length() + 1); // length of rawdata (+ null char) + DBGFrame2.addString(evalBlock); // eval block + DBGFrame2.addChar('\0'); // null char + */ + + // Add command data + DBGPacket.addFrame(DBGFrame1); + + DBGPacket.sendPacket(os); + + waitResponse(1000); + flushAllPackets(); + + // Process serialized variables + DBGVariableList= procVars(stack); + + return DBGVariableList; + } + + public void evalBlock(String evalString) throws IOException, DebugException { + PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST); + PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL); + PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA); + + rawCounter++; + DBGFrame1.addInt(rawCounter); // istr = raw data ID + DBGFrame1.addInt(1); // scope_id = -1 means current location, 0 never used, +1 first depth + + DBGFrame2.addInt(rawCounter); // FRAME_RAWDATA ID + DBGFrame2.addInt(evalString.length() + 1); // length of rawdata (+ null char) + DBGFrame2.addString(evalString); // eval block + DBGFrame2.addChar('\0'); // null char + + // Add raw data first + DBGPacket.addFrame(DBGFrame2); + // Add command data + DBGPacket.addFrame(DBGFrame1); + + DBGPacket.sendPacket(os); + + waitResponse(1000); + flushAllPackets(); + } + + public void flushAllPackets() throws IOException { + while(readResponse() != 0); + } + + private String getModByNo(int modNo) { + int i; + PHPDBGMod dbg_mod; + + // 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(); + } + } + return ""; + } + + private int getModByName(String modName) { + int i; + PHPDBGMod dbg_mod; + + // 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(); + } + } + 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 + + nextFrame += 8; + if(dbg_frame[1] == 0) return ""; + + 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); + } + break; + } + // go to next frame + nextFrame += dbg_frame[1]; + } + return ""; + } + + public PHPVariable[] getInstVars(PHPVariable phpVar) throws DebugException { + Vector vecVars= new Vector(); + PHPVariable localPHPVar; + int i=0; + + // already unserialized + for(i=0; i < DBGVars.size(); i++) { + localPHPVar= (PHPVariable)DBGVars.get(i); + if(localPHPVar.getParent() == phpVar) { + vecVars.add(localPHPVar); + } + } + PHPVariable[] arrVars= new PHPVariable[vecVars.size()]; + arrVars= (PHPVariable[]) vecVars.toArray(arrVars); + + return arrVars; + } + + private PHPVariable[] procVars(PHPStackFrame stack) throws DebugException { + Vector vecVars= new Vector(); + + // unserialize + finalPos= 0; + refCounter= 0; + doUnserialize(stack, vecVars, null); + + DBGVars= vecVars; + + return(getInstVars(null)); + } + + private String readValue(String serialVars) throws DebugException { + int startPos=0, endPos=0, lenStr=0, i=0, elements=0; + String ret= new String(""); + + switch(serialVars.charAt(0)) { + case 'a': // associative array, a:elements:{[index][value]...} + typeRead= "hash"; + startPos= 1; + endPos= serialVars.indexOf(':', startPos + 1); + if(endPos == -1) return ""; + finalPos += endPos + 2; + ret= new String(serialVars.substring(startPos + 1, endPos)); + + hasChildren= true; + break; + case 'O': // object, O:name_len:"name":elements:{[attribute][value]...} + typeRead= "object"; + + startPos= 1; + endPos= serialVars.indexOf(':', startPos + 1); + if(endPos == -1) return ""; + + // get object class + lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos)); + startPos= endPos + 2; + endPos= lenStr + startPos; + className= new String(serialVars.substring(startPos, endPos).toString()); + + // get num of elements + startPos= endPos + 1; + endPos= serialVars.indexOf(':', startPos + 1); + if(endPos == -1) return ""; + finalPos += endPos + 2; + ret= new String(serialVars.substring(startPos + 1, endPos)); + + isObject= true; + hasChildren= true; + break; + case 's': // string, s:length:"data"; + typeRead= "string"; + startPos= 1; + endPos= serialVars.indexOf(':', startPos + 1); + if(endPos == -1) return ""; + + lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos)); + startPos= endPos + 2; + endPos= lenStr + startPos; + ret= new String(serialVars.substring(startPos, endPos).toString()); + finalPos += endPos + 2; + break; + case 'i': // integer, i:123; + typeRead= "integer"; + startPos= 1; + endPos= serialVars.indexOf(';', startPos + 1); + if(endPos == -1) return ""; + + ret= new String(serialVars.substring(startPos + 1, endPos).toString()); + finalPos += endPos + 1; + break; + case 'd': // double (float), d:1.23; + typeRead= "double"; + startPos= 1; + endPos= serialVars.indexOf(';', startPos + 1); + if(endPos == -1) return ""; + + ret= new String(serialVars.substring(startPos + 1, endPos).toString()); + finalPos += endPos + 1; + break; + case 'N': // NULL, N; + typeRead= "null"; + ret= "nil"; + finalPos += 2; + break; + case 'b': // bool, b:0 or 1 + typeRead= "boolean"; + ret= (serialVars.charAt(2) == '1')?"true":"false"; + finalPos += endPos + 4; + break; + case 'z': // resource, z:typename_len:"typename":valres; + typeRead= "resource"; + + startPos= 1; + endPos= serialVars.indexOf(':', startPos + 1); + if(endPos == -1) return ""; + + // get resource type name + lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos)); + startPos= endPos + 2; + endPos= lenStr + startPos; + className= new String(serialVars.substring(startPos, endPos).toString()); + + // get resource value + startPos= endPos + 1; + endPos= serialVars.indexOf(';', startPos + 1); + if(endPos == -1) return ""; + ret= new String(serialVars.substring(startPos + 1, endPos)); + finalPos += endPos + 1; + break; + case 'r': + case 'R': + typeRead= "reference"; + startPos= 1; + endPos= serialVars.indexOf(';', startPos + 1); + if(endPos == -1) return "0"; + + ret= new String(serialVars.substring(startPos + 1, endPos)); + finalPos += endPos + 1; + isRef= true; + break; + case ';': + typeRead= "unknown"; + finalPos+= 1; + break; + case '?': + finalPos+= 1; + default: + finalPos+= 1; + typeRead= "unknown"; + break; + } + return ret; + } + + private void doUnserialize(PHPStackFrame stack, Vector vecVars, PHPVariable parent) throws DebugException { + int i, elements= 0; + PHPVariable newVar= null; + String value= new String(""); + String name= new String(""); + String tmp= new String(""); + + if(finalPos > serGlobals.length() || serGlobals.equals("") || serGlobals.substring(finalPos).equals("")) return; + + isRef= false; + hasChildren= false; + isObject= false; + name= readValue(serGlobals.substring(finalPos)); + + if(hasChildren) { + // main array + if(refCounter == 0) { + value= name; + name= ""; + } + } else { + hasChildren= false; + isRef= false; + value= readValue(serGlobals.substring(finalPos)); + } + + if(!name.equals("")) { + if(isRef) { + PHPVariable varPHP; + for(i=0; i < vecVars.size(); i++) { + varPHP= (PHPVariable) vecVars.get(i); + if(varPHP.getObjectId().equals(value)) { + newVar= new PHPVariable(stack, name, "local", true, (PHPValue)varPHP.getValue()); + break; + } + } + if(newVar == null) { + newVar= new PHPVariable(stack, name, "local", false, null); + } + } else { + refCounter++; + newVar= new PHPVariable(stack, name, "local", value, typeRead, hasChildren, Integer.toString(refCounter), className); + } + newVar.setParent(parent); + vecVars.add(newVar); + } + if(hasChildren) { + elements= Integer.parseInt(value); + for(i=0; i < elements; i++) + doUnserialize(stack, vecVars, newVar); + + // skip "}" + finalPos += 1; + } + } + + public int readResponse() throws IOException { + int bytesToRead=0, nextFrame=0, i=0, cmdReceived=0, stackIndex=0; + 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]; + Vector rawList= new Vector(); + Vector stackList= new Vector(); + PHPStackFrame[] newStackList; + + 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]; + bytesToRead= dbg_header_struct[3]; + + System.out.println("Response Received: " + cmdReceived); + + char[] entirePack= new char[bytesToRead]; + + if(bytesToRead > 0) { + if(readInput(entirePack, bytesToRead) < bytesToRead) return 0; + } + + // 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]) { + 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 + + stackIndex++; + if(!getModByNo(dbg_stack_new[1]).equals("")) { + PHPStackFrame newStack= new PHPStackFrame(null, getModByNo(dbg_stack_new[1]), dbg_stack_new[0], stackIndex, getRawFrameData(entirePack, dbg_stack_new[3])); + stackList.add(newStack); + } + break; + case PHPDBGBase.FRAME_SOURCE: + break; + case PHPDBGBase.FRAME_SRC_TREE: + break; + case PHPDBGBase.FRAME_RAWDATA: + break; + case PHPDBGBase.FRAME_ERROR: + 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: + 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); + + // 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); + break; + } + } + + // add breakpoint to vector + 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); + PHPDBGMod modNew= new PHPDBGMod(dbg_bpl_new[0], fileName); + DBGMods.add(modNew); + } + break; + case PHPDBGBase.FRAME_VER: + break; + case PHPDBGBase.FRAME_SID: + 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]; + } + + // Now process command + switch(cmdReceived) { + case PHPDBGBase.DBGC_REPLY: + break; + case PHPDBGBase.DBGC_STARTUP: + break; + case PHPDBGBase.DBGC_END: + sessionEnded= true; + break; + case PHPDBGBase.DBGC_BREAKPOINT: + newStackList= new PHPStackFrame[stackList.size()]; + newStackList= (PHPStackFrame[]) stackList.toArray(newStackList); + DBGStackList= newStackList; + BPUnderHit= getBPUnderHit(); + break; + case PHPDBGBase.DBGC_STEPINTO_DONE: + case PHPDBGBase.DBGC_STEPOVER_DONE: + case PHPDBGBase.DBGC_STEPOUT_DONE: + case PHPDBGBase.DBGC_EMBEDDED_BREAK: + BPUnderHit= 1; + newStackList= new PHPStackFrame[stackList.size()]; + newStackList= (PHPStackFrame[]) stackList.toArray(newStackList); + DBGStackList= newStackList; + break; + case PHPDBGBase.DBGC_ERROR: + newStackList= new PHPStackFrame[stackList.size()]; + newStackList= (PHPStackFrame[]) stackList.toArray(newStackList); + DBGStackList= newStackList; + break; + case PHPDBGBase.DBGC_LOG: + break; + case PHPDBGBase.DBGC_SID: + break; + case PHPDBGBase.DBGC_PAUSE: + break; + } + } + + return cmdReceived; + } + + 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++; + } + else + break; + } + return bytesRead; + } + + public void setShouldStop() { + this.shouldStop= true; + } + + public void waitResponse(long milliseconds) throws IOException { + long timeout= System.currentTimeMillis() + milliseconds; + while(System.currentTimeMillis() < timeout) { + if(in.ready() || shouldStop) { + break; + } + } + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGMod.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGMod.java new file mode 100644 index 0000000..f973f8d --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGMod.java @@ -0,0 +1,40 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + Vicente Fernando - www.alfersoft.com.ar - Initial implementation +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core; + +public class PHPDBGMod { + private int modNo; + private String modName; + + public PHPDBGMod() { + } + + public PHPDBGMod(int modNo, String modName) { + this.modNo= modNo; + this.modName= modName; + } + + public int getNo() { + return modNo; + } + + public String getName() { + return modName; + } + + public void setNo(int modNo) { + this.modNo= modNo; + } + + public void setName(String modName) { + this.modName= modName; + } +} \ No newline at end of file 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 new file mode 100644 index 0000000..03d3350 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGPacket.java @@ -0,0 +1,56 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + Vicente Fernando - www.alfersoft.com.ar - Initial implementation +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core; + +import java.io.OutputStream; +import java.util.Vector; +import java.io.IOException; +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); + } + + public void addFrame(PHPDBGFrame frame) { + frames.add(frame); + packetSize+= frame.getSize(); + } + + 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(); + } + } + } +} \ 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 new file mode 100644 index 0000000..3f6ca08 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/PHPDBGProxy.java @@ -0,0 +1,330 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.Socket; +import java.net.ServerSocket; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IBreakpoint; +import net.sourceforge.phpdt.internal.debug.core.model.IPHPDebugTarget; +import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame; +import net.sourceforge.phpdt.internal.debug.core.model.PHPThread; +import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable; +import net.sourceforge.phpdt.internal.debug.core.SocketUtil; +import net.sourceforge.phpdt.internal.debug.core.PHPDBGInterface; +import net.sourceforge.phpdt.internal.debug.core.breakpoints.PHPLineBreakpoint; +import net.sourceforge.phpdt.internal.debug.core.PHPDebugCorePlugin; + +public class PHPDBGProxy { + + private ServerSocket server= null; + private Socket socket; + private BufferedReader reader= null; + private PHPDBGInterface DBGInt= null; + private IPHPDebugTarget debugTarget; + private PHPLoop phpLoop; + private PHPThread PHPMainThread; + private int port; + + public PHPDBGProxy() { + } + + public void start() { + createServerSocket(); + this.startPHPLoop(); + } + + public void stop() { + phpLoop.setShouldStop(); + if(DBGInt != null) DBGInt.setShouldStop(); + phpLoop.notifyWait(); + } + + protected ServerSocket getServerSocket() throws IOException { + if (server == null) { + createServerSocket(); + } + return server; + } + + protected void createServerSocket() { + port = SocketUtil.findUnusedLocalPort("localhost", 10001, 10101); + 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(); + } + } + + protected 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 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++) { + addBreakpoint(breakpoints[i]); + } + } + + public void addBreakpoint(IBreakpoint breakpoint) { + if (DBGInt == null) return; + int bpNo= 0; + try { + PHPLineBreakpoint phpLBP; + if(breakpoint.getModelIdentifier() == PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier()) { + phpLBP= (PHPLineBreakpoint)breakpoint; + bpNo= DBGInt.addBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), 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.getDefault().getDescriptor().getUniqueIdentifier()) { + phpLBP= (PHPLineBreakpoint)breakpoint; + DBGInt.removeBreakpoint(phpLBP.getMarker().getResource().getLocation().toOSString(), phpLBP.getLineNumber(), phpLBP.getDBGBpNo()); + } + } catch (IOException e) { + PHPDebugCorePlugin.log(e); + stop(); + } catch (CoreException e) { + PHPDebugCorePlugin.log(e); + stop(); + } + } + + public void startPHPLoop() { + phpLoop = new PHPLoop(); + phpLoop.start(); + } + + public void resume(PHPThread thread) { + try { + DBGInt.continueExecution(); + phpLoop.notifyWait(); + } catch (IOException e) { + PHPDebugCorePlugin.log(e); + stop(); + } + } + + protected IPHPDebugTarget getDebugTarget() { + return debugTarget; + } + + public void setDebugTarget(IPHPDebugTarget 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[] readInstanceVariables(PHPVariable variable) { + try { + return DBGInt.getInstVars(variable); + } 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; + } + + public synchronized void notifyWait() { + notify(); + } + + public void run() { + try { + char[] buf= new char[16]; + int i, pos; + long interval= 1000*20; + String line; + PHPStackFrame[] StackList; + + System.out.println("Waiting for breakpoints."); + try{ + socket = server.accept(); + System.out.println("Accepted! : " + socket.toString()); + } catch (IOException e) { + PHPDebugCorePlugin.log(e); + return; + } + + PHPMainThread= new PHPThread(getDebugTarget(), 100); + PHPMainThread.setName("Thread [main]"); + getDebugTarget().addThread(PHPMainThread); + setDBGInterface(new PHPDBGInterface(getReader(), getOutputStream())); + + DBGInt.flushAllPackets(); + + // Check version and session ID + + setBreakPoints(); + DBGInt.continueExecution(); + + while (!shouldStop) { + 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); + } + PHPMainThread.setStackFrames(StackList); + } + PHPMainThread.suspend(); + + synchronized(this) { + wait(); + } + } + if(PHPMainThread.isTerminated() || getDebugTarget().getProcess().isTerminated()) break; + } + } catch (Exception ex) { + PHPDebugCorePlugin.log(ex); + System.out.println(ex); + } finally { + getDebugTarget().terminate(); + try { + 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/SocketUtil.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/SocketUtil.java new file mode 100644 index 0000000..dac0f05 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/SocketUtil.java @@ -0,0 +1,78 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core; + +import java.io.IOException; +import java.net.ConnectException; +import java.net.Socket; +import java.util.Random; + +/** + * Utility class to find a port to debug on. + */ +public class SocketUtil { + private static final Random fgRandom= new Random(System.currentTimeMillis()); + + /** + * Returns a free port number on the specified host within the given range, + * or -1 if none found. + * + * @param host name or IP addres of host on which to find a free port + * @param searchFrom the port number from which to start searching + * @param searchTo the port number at which to stop searching + * @return a free port in the specified range, or -1 of none found + */ + public static int findUnusedLocalPort(String host, int searchFrom, int searchTo) { + + // First look at the five first ports starting on searchFrom + for (int i= searchFrom; i <= searchFrom + 5; i++) { + Socket s= null; + int port= i; + try { + s= new Socket(host, port); + } catch (ConnectException e) { + return port; + } catch (IOException e) { + } finally { + if (s != null) { + try { + s.close(); + } catch (IOException ioe) { + } + } + } + } + // No free port found then look at 5 random ports numbers + for (int i= 0; i < 5; i++) { + Socket s= null; + int port= getRandomPort(searchFrom, searchTo); + try { + s= new Socket(host, port); + } catch (ConnectException e) { + return port; + } catch (IOException e) { + } finally { + if (s != null) { + try { + s.close(); + } catch (IOException ioe) { + } + } + } + } + return -1; + } + + private static int getRandomPort(int low, int high) { + return (int)(fgRandom.nextFloat() * (high-low)) + low; + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/breakpoints/PHPBreakpoint.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/breakpoints/PHPBreakpoint.java new file mode 100644 index 0000000..55be0de --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/breakpoints/PHPBreakpoint.java @@ -0,0 +1,193 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core.breakpoints; + +import net.sourceforge.phpdt.internal.debug.core.PHPDebugCorePlugin; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.Breakpoint; + +/** + * A breakpoint is capable of suspending the execution of a + * program at a specific location when a program is running + * in debug mode. Each breakpoint has an associated marker which + * stores and persists all attributes associated with a breakpoint. + *

+ * A breakpoint is defined in two parts: + *

    + *
  1. By an extension of kind "org.eclipse.debug.core.breakpoints"
  2. + *
  3. By a marker definition that corresponds to the above breakpoint extension
  4. + *
+ *

+ * For example, following is a definition of corresponding breakpoint + * and breakpoint marker definitions. Note that the markerType + * attribute defined by the breakpoint extension corresponds to the + * type of the marker definition. + *

+ * <extension point="org.eclipse.debug.core.breakpoints">
+ *   <breakpoint 
+ *      id="com.example.Breakpoint"
+ *      class="com.example.Breakpoint"
+ *      markerType="com.example.BreakpointMarker">
+ *   </breakpoint>
+ * </extension>
+ * <extension point="org.eclipse.core.resources.markers">
+ *   <marker 
+ *      id="com.example.BreakpointMarker"
+ *      super type="org.eclipse.debug.core.breakpointMarker"
+ *      attribute name ="exampleAttribute">
+ *   </marker>
+ * </extension>
+ * 
+ *

+ * The breakpoint manager instantiates persisted breakpoints by + * traversing all markers that are a subtype of + * "org.eclipse.debug.core.breakpointMarker", and + * instantiating the class defined by the class attribute + * on the associated breakpoint extension. The method setMarker + * is then called to associate a marker with the breakpoint. + *

+ *

+ * Breakpoints may or may not be registered with the breakpoint manager, and + * are persisted and restored as such. Since marker definitions only allow + * all or none of a specific marker type to be persisted, breakpoints define + * a PERSISTED attribute for selective persistence of breakpoints + * of the same type. + *

+ * + * @since 2.0 + */ + +public abstract class PHPBreakpoint extends Breakpoint implements IBreakpoint { + + /** + * Breakpoint attribute storing a breakpoint's hit count value + * (value "net.sourceforge.phpeclipse.debug.hitCount"). This attribute is stored as an + * int. + */ + protected static final String HIT_COUNT = "net.sourceforge.phpeclipse.debug.hitCount"; //$NON-NLS-1$ + + /** + * Breakpoint attribute storing the fully qualified name of the type + * this breakpoint is located in. + * (value "net.sourceforge.phpeclipse.debug.typeName"). This attribute is a String. + */ + protected static final String TYPE_NAME = "net.sourceforge.phpeclipse.debug.typeName"; //$NON-NLS-1$ + + /** + * Root breakpoint marker type + * (value "org.eclipse.debug.core.breakpoint"). + */ + public static final String BREAKPOINT_MARKER = DebugPlugin.getUniqueIdentifier() + ".breakpointMarker"; //$NON-NLS-1$ + + /** + * Line breakpoint marker type + * (value "org.eclipse.debug.core.lineBreakpoint"). + */ + public static final String LINE_BREAKPOINT_MARKER = DebugPlugin.getUniqueIdentifier() + ".lineBreakpointMarker"; //$NON-NLS-1$ + + /** + * Enabled breakpoint marker attribute (value "org.eclipse.debug.core.enabled"). + * The attribute is a boolean corresponding to the + * enabled state of a breakpoint. + * + * @see org.eclipse.core.resources.IMarker#getAttribute(String, boolean) + */ + public static final String ENABLED= "org.eclipse.debug.core.enabled"; //$NON-NLS-1$ + + /** + * Debug model identifier breakpoint marker attribute (value "org.eclipse.debug.core.id"). + * The attribute is a String corresponding to the + * identifier of the debug model a breakpoint is associated with. + */ + public static final String ID= "org.eclipse.debug.core.id"; //$NON-NLS-1$ + + /** + * Registered breakpoint marker attribute (value "org.eclipse.debug.core.registered"). + * The attribute is a boolean corresponding to + * whether a breakpoint has been registered with the breakpoint manager. + * + * @see org.eclipse.core.resources.IMarker#getAttribute(String, boolean) + */ + public static final String REGISTERED= "org.eclipse.debug.core.registered"; //$NON-NLS-1$ + + /** + * Persisted breakpoint marker attribute (value "org.eclipse.debug.core.persisted"). + * The attribute is a boolean corresponding to + * whether a breakpoint is to be persisted accross workspace + * invocations. + * + * @see org.eclipse.core.resources.IMarker#getAttribute(String, boolean) + */ + public static final String PERSISTED= "org.eclipse.debug.core.persisted"; //$NON-NLS-1$ + + private int DBGBpNo=0; + + public PHPBreakpoint() { + } + + /** + * @see IBreakpoint#setMarker(IMarker) + */ + public void setMarker(IMarker marker) throws CoreException { + super.setMarker(marker); + } + + /** + * Add this breakpoint to the breakpoint manager, + * or sets it as unregistered. + */ + protected void register(boolean register) throws CoreException { + if (register) { + DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(this); + } else { + setRegistered(false); + } + } + + /** + * Execute the given workspace runnable + */ + protected void run(IWorkspaceRunnable wr) throws DebugException { + try { + ResourcesPlugin.getWorkspace().run(wr, null); + } catch (CoreException e) { + throw new DebugException(e.getStatus()); + } + } + + /** + * @see IBreakpoint#getModelIdentifier() + */ + public String getModelIdentifier() { + if (PHPDebugCorePlugin.getDefault() == null) { + // If the default instance is not yet initialized, + // return a static identifier. This identifier must + // match the plugin id defined in plugin.xml + return "net.sourceforge.phpeclipse.debug.core"; //$NON-NLS-1$ + } + return PHPDebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier(); + } + + public void setDBGBpNo(int bpNo) { + this.DBGBpNo= bpNo; + } + + public int getDBGBpNo() { + return this.DBGBpNo; + } +} diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/breakpoints/PHPLineBreakpoint.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/breakpoints/PHPLineBreakpoint.java new file mode 100644 index 0000000..75a3c1f --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/breakpoints/PHPLineBreakpoint.java @@ -0,0 +1,94 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + Vicente Fernando - Initial implementation - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core.breakpoints; + +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.ILineBreakpoint; + +/** + * A breakpoint that can be located at a specific line of source code. + */ +public class PHPLineBreakpoint extends PHPBreakpoint implements IBreakpoint, ILineBreakpoint { + + private static final String PHP_LINE_BREAKPOINT = "net.sourceforge.phpeclipse.debug.core.phpLineBreakpointMarker"; //$NON-NLS-1$ + + public PHPLineBreakpoint() { + } + + public PHPLineBreakpoint(IResource resource, int lineNumber, int charStart, int charEnd, int hitCount, boolean add, Map attributes) throws DebugException { + this(resource, lineNumber, charStart, charEnd, hitCount, add, attributes, PHP_LINE_BREAKPOINT); + } + + protected PHPLineBreakpoint(final IResource resource, final int lineNumber, final int charStart, final int charEnd, final int hitCount, final boolean add, final Map attributes, final String markerType) throws DebugException { + IWorkspaceRunnable wr= new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + + // create the marker + setMarker(resource.createMarker(markerType)); + + // add attributes + addLineBreakpointAttributes(attributes, getModelIdentifier(), true, lineNumber, charStart, charEnd); + + // set attributes + ensureMarker().setAttributes(attributes); + + // add to breakpoint manager if requested + register(add); + } + }; + run(wr); + } + + public void addLineBreakpointAttributes(Map attributes, String modelIdentifier, boolean enabled, int lineNumber, int charStart, int charEnd) { + attributes.put(IBreakpoint.ID, modelIdentifier); + attributes.put(IBreakpoint.ENABLED, new Boolean(enabled)); + attributes.put(IMarker.LINE_NUMBER, new Integer(lineNumber)); + attributes.put(IMarker.CHAR_START, new Integer(charStart)); + attributes.put(IMarker.CHAR_END, new Integer(charEnd)); + attributes.put(TYPE_NAME, "typeName"); + } + + /** + * @see ILineBreakpoint#getLineNumber() + */ + public int getLineNumber() throws CoreException { + return ensureMarker().getAttribute(IMarker.LINE_NUMBER, -1); + } + + /** + * @see ILineBreakpoint#getCharStart() + */ + public int getCharStart() throws CoreException { + return ensureMarker().getAttribute(IMarker.CHAR_START, -1); + } + + /** + * @see ILineBreakpoint#getCharEnd() + */ + public int getCharEnd() throws CoreException { + return ensureMarker().getAttribute(IMarker.CHAR_END, -1); + } + + /** + * Returns the type of marker associated with Java line breakpoints + */ + public static String getMarkerType() { + return PHP_LINE_BREAKPOINT; + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/IPHPDebugTarget.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/IPHPDebugTarget.java new file mode 100644 index 0000000..65f5960 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/IPHPDebugTarget.java @@ -0,0 +1,24 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core.model; + +import org.eclipse.debug.core.model.IDebugTarget; +import net.sourceforge.phpdt.internal.debug.core.PHPDBGProxy; + +public interface IPHPDebugTarget extends IDebugTarget { + + public final static String MODEL_IDENTIFIER = "net.sourceforge.phpdt.debug.core"; + public void terminate(); + public void setPHPDBGProxy(PHPDBGProxy phpDBGProxy); + public void addThread(PHPThread phpThread); + +} diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPDebugTarget.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPDebugTarget.java new file mode 100644 index 0000000..9ecd65e --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPDebugTarget.java @@ -0,0 +1,241 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core.model; + +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IBreakpointManager; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchListener; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IProcess; +import org.eclipse.debug.core.model.IThread; + +import net.sourceforge.phpdt.internal.debug.core.PHPDebugCorePlugin; +import net.sourceforge.phpdt.internal.debug.core.PHPDBGProxy; + +/** + * Debug target for PHP debug model. + */ +public class PHPDebugTarget implements IPHPDebugTarget, ILaunchListener, IDebugEventSetListener { + + private IProcess process; + private boolean isTerminated; + private ILaunch launch; + private PHPThread[] threads; + private PHPDBGProxy phpDBGProxy; + + public PHPDebugTarget(ILaunch launch, IProcess process) { + this.launch = launch; + this.process = process; + this.threads = new PHPThread[0]; + IBreakpointManager manager= DebugPlugin.getDefault().getBreakpointManager(); + manager.addBreakpointListener(this); + DebugPlugin.getDefault().addDebugEventListener(this); + initialize(); + } + + protected synchronized void initialize() { + DebugEvent ev = new DebugEvent(this, DebugEvent.CREATE); + DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev }); + } + + public void addThread(PHPThread phpThread) { + int i; + PHPThread[] updatedThreads = new PHPThread[threads.length + 1]; + + for(i=0; i < threads.length; i++) { + updatedThreads[i] = threads[i]; + } + updatedThreads[i] = phpThread; + threads = updatedThreads; + + fireChangeEvent(); + } + + private void fireChangeEvent() { + DebugEvent ev = new DebugEvent(this, DebugEvent.CHANGE); + DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev }); + } + + protected PHPThread getThreadById(int id) { + for (int i = 0; i < threads.length; i++) { + if (threads[i].getId() == id) { + return threads[i]; + } + } + return null; + } + + public IThread[] getThreads() { + return threads; + } + + public boolean hasThreads() throws DebugException { + return threads.length > 0; + } + + public String getName() throws DebugException { + return "PHP Debugger at localhost:" + getPHPDBGProxy().getPort(); + } + + public boolean supportsBreakpoint(IBreakpoint arg0) { + return false; + } + + public String getModelIdentifier() { + return PHPDebugCorePlugin.getUniqueIdentifier(); + } + + public IDebugTarget getDebugTarget() { + return this; + } + + public ILaunch getLaunch() { + return launch; + } + + public boolean canTerminate() { + return !isTerminated; + } + + public boolean isTerminated() { + return isTerminated; + } + + public void terminate() { + phpDBGProxy.stop(); + this.threads = new PHPThread[0]; + isTerminated = true; + fireChangeEvent(); + } + + public boolean canResume() { + return false; + } + + public boolean canSuspend() { + return false; + } + + public boolean isSuspended() { + return false; + } + + public void resume() throws DebugException { + } + + public void suspend() throws DebugException { + } + + public void breakpointAdded(IBreakpoint breakpoint) { + this.getPHPDBGProxy().addBreakpoint(breakpoint) ; + } + + public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta arg1) { + this.getPHPDBGProxy().removeBreakpoint(breakpoint) ; + } + + public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta arg1) { + // is called e.g. after a line has been inserted before a breakpoint + // but then the debugger is out of sync with the file anyway, so debugging + // should be stopped here. + } + + public boolean canDisconnect() { + return false; + } + + public void disconnect() throws DebugException { + } + + public boolean isDisconnected() { + return false; + } + + public boolean supportsStorageRetrieval() { + return false; + } + + public IMemoryBlock getMemoryBlock(long arg0, long arg1) throws DebugException { + return null; + } + + public Object getAdapter(Class arg0) { + return null; + } + + public IProcess getProcess() { + return process; + } + + public void setProcess(IProcess process) { + this.process = process; + } + + public PHPDBGProxy getPHPDBGProxy() { + return phpDBGProxy; + } + + public void setPHPDBGProxy(PHPDBGProxy phpDBGProxy) { + this.phpDBGProxy = phpDBGProxy; + } + + /** + * @see ILaunchListener#launchRemoved(ILaunch) + */ + public void launchRemoved(ILaunch launch) { + if (!isTerminated()) { + return; + } + if (launch.equals(getLaunch())) { + // This target has been deregistered, but it hasn't successfully terminated. + // Update internal state to reflect that it is disconnected + terminate(); + } + } + + /** + * @see ILaunchListener#launchAdded(ILaunch) + */ + public void launchAdded(ILaunch launch) { + } + + /** + * @see ILaunchListener#launchChanged(ILaunch) + */ + public void launchChanged(ILaunch launch) { + } + + /** + * When a debug target or process terminates, terminate DBG Proxy. + * + * @see IDebugEventSetListener#handleDebugEvents(DebugEvent[]) + */ + public void handleDebugEvents(DebugEvent[] events) { + for (int i = 0; i < events.length; i++) { + DebugEvent event = events[i]; + if (event.getKind() == DebugEvent.TERMINATE) { + Object source = event.getSource(); + if (source instanceof PHPDebugTarget || source instanceof IDebugTarget || source instanceof IProcess) { + getPHPDBGProxy().stop(); + } + } + } + } +} + diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPExpression.java b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPExpression.java new file mode 100644 index 0000000..9ca57f1 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPExpression.java @@ -0,0 +1,58 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core.model; + +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IExpression; +import org.eclipse.debug.core.model.IValue; + +public class PHPExpression implements IExpression { + + private PHPVariable inspectionResult; + private String expression; + + public PHPExpression(String expression, PHPVariable inspectionResult) { + this.inspectionResult = inspectionResult; + this.expression = expression; + + } + + public String getExpressionText() { + return expression; + } + + public IValue getValue() { + return inspectionResult.getValue(); + } + + public IDebugTarget getDebugTarget() { + return inspectionResult.getDebugTarget(); + } + + public void dispose() { + + } + + public String getModelIdentifier() { + return this.getDebugTarget().getModelIdentifier(); + } + + public ILaunch getLaunch() { + return this.getDebugTarget().getLaunch(); + } + + public Object getAdapter(Class arg0) { + return null; + } + +} 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 new file mode 100644 index 0000000..bf59b50 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPStackFrame.java @@ -0,0 +1,208 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core.model; + +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IRegisterGroup; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.core.model.IVariable; +import net.sourceforge.phpdt.internal.debug.core.PHPDBGProxy; +import net.sourceforge.phpdt.internal.debug.core.model.PHPDebugTarget; + +public class PHPStackFrame implements IStackFrame { + + private PHPThread thread; + private String file; + private int lineNumber; + private int index; + private PHPVariable[] variables; + private String description; + + public PHPStackFrame(PHPThread thread, String file, int line, int index, String desc) { + this.lineNumber = line; + this.index = index; + this.file = file; + this.thread = thread; + this.description = desc; + } + + public PHPStackFrame(PHPThread thread, String file, int line, int index) { + this.lineNumber = line; + this.index = index; + this.file = file; + this.thread = thread; + } + + public IThread getThread() { + return thread; + } + + public void setThread(PHPThread thread) { + this.thread = thread; + } + + public IVariable[] getVariables() throws DebugException { + if (variables == null) { + variables = this.getPHPDBGProxy().readVariables(this); + } + return variables; + } + + public boolean hasVariables() throws DebugException { + if (variables == null) { + return false; + } + return variables.length > 0; + } + + public int getLineNumber() { + return lineNumber; + } + + public int getCharStart() throws DebugException { + // not supported + return -1; + } + + public int getCharEnd() throws DebugException { + // not supported + return -1; + } + + public String getName() { + if(!this.getDescription().equals("")) + return this.getDescription() + " [line: " + this.getLineNumber() + "]"; + else + return this.getFileName() + " [line: " + this.getLineNumber() + "]"; + } + + public String getFileName() { + return file; + } + + public void setDescription(String desc) { + this.description= desc; + } + + public String getDescription() { + return this.description; + } + + public IRegisterGroup[] getRegisterGroups() throws DebugException { + return null; + } + + public boolean hasRegisterGroups() throws DebugException { + return false; + } + + public String getModelIdentifier() { + return this.getThread().getModelIdentifier(); + } + + public IDebugTarget getDebugTarget() { + return this.getThread().getDebugTarget(); + } + + public ILaunch getLaunch() { + return this.getDebugTarget().getLaunch(); + } + + public boolean canStepInto() { + return canResume(); + } + + public boolean canStepOver() { + return canResume(); + } + + public boolean canStepReturn() { + return canResume(); + } + + public boolean isStepping() { + 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 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 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 boolean canResume() { + return this.getThread().canResume(); + } + + public boolean canSuspend() { + return this.getThread().canSuspend(); + } + + public boolean isSuspended() { + return this.getThread().isSuspended(); + } + + public void resume() throws DebugException { + this.getThread().resume(); + } + + public void suspend() throws DebugException { + } + + public boolean canTerminate() { + return this.getThread().canTerminate(); + } + + public boolean isTerminated() { + return this.getThread().isTerminated(); + } + + public void terminate() throws DebugException { + getPHPDBGProxy().stop(); + } + + public Object getAdapter(Class arg0) { + return null; + } + + public int getIndex() { + return index; + } + + public PHPDBGProxy getPHPDBGProxy() { + PHPDebugTarget DebugTarget; + DebugTarget= (PHPDebugTarget)thread.getDebugTarget(); + return DebugTarget.getPHPDBGProxy(); + } + +} 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 new file mode 100644 index 0000000..3d4c2b0 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPThread.java @@ -0,0 +1,209 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core.model; + +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.core.model.IThread; + +public class PHPThread implements IThread { + + private PHPStackFrame[] frames; + private IDebugTarget target; + private boolean isSuspended = false; + private boolean isTerminated = false; + private boolean isStepping = false; + private String name ; + private int id ; + + public PHPThread(IDebugTarget target, int id) { + this.target = target; + this.setId(id) ; + this.createName() ; + } + + public IStackFrame[] getStackFrames() throws DebugException { + return frames; + } + + public int getStackFramesSize() { + return frames.length; + } + + public boolean hasStackFrames() { + if (frames == null) { + return false; + } + return frames.length > 0; + } + + public int getPriority() throws DebugException { + return 0; + } + + public IStackFrame getTopStackFrame() throws DebugException { + if (frames == null || frames.length == 0) { + return null; + } + return (IStackFrame) frames[0]; + } + + + public IBreakpoint[] getBreakpoints() { + return null; + } + + public String getModelIdentifier() { + return this.getDebugTarget().getModelIdentifier(); + } + + public IDebugTarget getDebugTarget() { + return target; + } + + public ILaunch getLaunch() { + return this.getDebugTarget().getLaunch(); + } + + public boolean canResume() { + return isSuspended; + } + + public boolean canSuspend() { + return !isSuspended; + } + + public boolean isSuspended() { + return isSuspended; + } + + protected void setSuspended(boolean isSuspended) { + this.isSuspended = isSuspended; + } + + protected void prepareForResume() { + isSuspended = false; + this.createName() ; + this.frames = null ; + DebugEvent ev = new DebugEvent(this, DebugEvent.RESUME, DebugEvent.CLIENT_REQUEST); + DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev }); + } + + public void resume() throws DebugException { + this.prepareForResume() ; + ((PHPDebugTarget) this.getDebugTarget()).getPHPDBGProxy().resume(this); + } + + /* + public void doSuspend(SuspensionPoint suspensionPoint) { +// this.getPHPDebuggerProxy().readFrames(this); + this.createName(suspensionPoint) ; + this.suspend() ; + } + */ + + public void suspend() { + isStepping = false ; + isSuspended = true; + DebugEvent ev = new DebugEvent(this, DebugEvent.SUSPEND, DebugEvent.BREAKPOINT); + DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { ev }); + } + + public boolean canStepInto() { + return isSuspended && this.hasStackFrames(); + } + + public boolean canStepOver() { + return isSuspended && this.hasStackFrames(); + } + + public boolean canStepReturn() { + return false; + } + + public boolean isStepping() { + return isStepping; + } + + public void stepInto() throws DebugException { + isStepping = true ; + this.createName() ; + this.frames = null ; + frames[0].stepInto(); + } + + public void stepOver() throws DebugException { + isStepping = true ; + this.createName() ; + this.frames = null ; + frames[0].stepOver() ; + } + + public void stepReturn() throws DebugException { + } + + public boolean canTerminate() { + return !isTerminated; + } + + public boolean isTerminated() { + return isTerminated; + } + + public void terminate() throws DebugException { + isTerminated = true; + this.frames = null; + } + + public Object getAdapter(Class arg0) { + return null; + } + + public void setStackFrames(PHPStackFrame[] frames) { + this.frames = frames; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + protected void createName() { + //this.createName(null) ; + } + + /* + protected void createName(SuspensionPoint suspensionPoint) { + this.name = "PHP Thread - " + this.getId() ; + if (suspensionPoint != null) { + this.name += " (" + suspensionPoint + ")" ; + } + } + */ + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + +} 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 new file mode 100644 index 0000000..beca6a3 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPValue.java @@ -0,0 +1,124 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core.model; + +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; + +/** + * @author Administrator + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class PHPValue implements IValue { + + private String valueString ; + private String referenceTypeName ; + private boolean hasChildren= false ; + private PHPVariable owner ; + private PHPVariable[] variables ; + + public PHPValue(PHPVariable owner) { + this(owner, "nil", null, false) ; + } + + public PHPValue(PHPVariable owner, String valueString, String type, boolean hasChildren) { + this.valueString = valueString ; + this.owner = owner ; + this.hasChildren = hasChildren ; + this.referenceTypeName = type ; + } + + + /** + * @see org.eclipse.debug.core.model.IValue#getReferenceTypeName() + */ + public String getReferenceTypeName() { + return this.referenceTypeName; + } + + /** + * @see org.eclipse.debug.core.model.IValue#getValueString() + */ + public String getValueString() { + return valueString; + } + + /** + * @see org.eclipse.debug.core.model.IValue#isAllocated() + */ + public boolean isAllocated() throws DebugException { + return false; + } + + /** + * @see org.eclipse.debug.core.model.IValue#getVariables() + */ + public IVariable[] getVariables() throws DebugException { + if (!hasChildren) { + return new PHPVariable[0] ; + } + if (variables == null) { + variables = ((PHPDebugTarget) this.getDebugTarget()).getPHPDBGProxy().readInstanceVariables(owner); + } + return variables; + } + + /** + * @see org.eclipse.debug.core.model.IValue#hasVariables() + */ + public boolean hasVariables() throws DebugException { + return hasChildren; + } + + /** + * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier() + */ + public String getModelIdentifier() { + return owner.getModelIdentifier(); + } + + /** + * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget() + */ + public IDebugTarget getDebugTarget() { + return owner.getDebugTarget(); + } + + /** + * @see org.eclipse.debug.core.model.IDebugElement#getLaunch() + */ + public ILaunch getLaunch() { + return this.getDebugTarget().getLaunch(); + } + + /** + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class) + */ + public Object getAdapter(Class adapter) { + return null; + } + + public String toString() { + if (this.getReferenceTypeName() == null) { + return this.getValueString() ; + } + return this.getValueString() ; + } + +} 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 new file mode 100644 index 0000000..7534052 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/model/PHPVariable.java @@ -0,0 +1,228 @@ +/********************************************************************** +Copyright (c) 2000, 2002 IBM Corp. and others. +All rights reserved. This program and the accompanying materials +are made available under the terms of the Common Public License v1.0 +which accompanies this distribution, and is available at +http://www.eclipse.org/legal/cpl-v10.html + +Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar +**********************************************************************/ +package net.sourceforge.phpdt.internal.debug.core.model; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +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 boolean isBoolean; + private boolean isString; + private boolean isResource; + private boolean isObject; + private boolean isLocal; + private PHPStackFrame stackFrame; + private String name; + private String objectId; + private String className; + private PHPValue value; + private PHPVariable parent; + + public PHPVariable(PHPStackFrame stackFrame, String name, String scope) { + this.initialize(stackFrame, name, scope, null, new PHPValue(this), "", "string"); + } + + public PHPVariable(PHPStackFrame stackFrame, String name, String scope, String value, String type, boolean hasChildren, String objectId, String className) { + this.initialize(stackFrame, name, scope, objectId, new PHPValue(this, value, type, hasChildren), className, type); + } + + public PHPVariable(PHPStackFrame stackFrame, String name, String scope, boolean isRef, PHPValue varPHP) { + if(isRef) + this.initialize(stackFrame, name, scope, "-1", varPHP, "", "string"); + else + this.initialize(stackFrame, name, scope, "-1", new PHPValue(this), "", "string"); + } + + protected final void initialize(PHPStackFrame stackFrame, String name, String scope, String objectId, PHPValue value, String className, String typeName) { + this.stackFrame = stackFrame; + this.value = value; + this.name = name; + this.objectId = objectId; + // scope + this.isLocal = scope.equals("local"); + // type + this.isObject = typeName.equals("object"); + this.isResource = typeName.equals("resource"); + this.isBoolean = typeName.equals("boolean"); + this.isString = typeName.equals("string"); + + this.className = className; + } + + /** + * @see org.eclipse.debug.core.model.IVariable#getValue() + */ + public IValue getValue() { + return value; + } + + /** + * @see org.eclipse.debug.core.model.IVariable#getName() + */ + public String getName() { + return name; + } + + /** + * @see org.eclipse.debug.core.model.IVariable#getReferenceTypeName() + */ + public String getReferenceTypeName() { + return "RefTypeName"; + } + + /** + * @see org.eclipse.debug.core.model.IVariable#hasValueChanged() + */ + public boolean hasValueChanged() throws DebugException { + return false; + } + + /** + * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier() + */ + public String getModelIdentifier() { + return this.getDebugTarget().getModelIdentifier(); + } + + /** + * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget() + */ + public IDebugTarget getDebugTarget() { + return stackFrame.getDebugTarget(); + } + + /** + * @see org.eclipse.debug.core.model.IDebugElement#getLaunch() + */ + public ILaunch getLaunch() { + return this.getDebugTarget().getLaunch(); + } + + /** + * @see org.eclipse.debug.core.model.IValueModification#setValue(String) + */ + public void setValue(String expression) throws DebugException { + } + + /** + * @see org.eclipse.debug.core.model.IValueModification#setValue(IValue) + */ + public void setValue(IValue value) throws DebugException { + } + + /** + * @see org.eclipse.debug.core.model.IValueModification#supportsValueModification() + */ + public boolean supportsValueModification() { + return false; + } + + /** + * @see org.eclipse.debug.core.model.IValueModification#verifyValue(String) + */ + public boolean verifyValue(String expression) throws DebugException { + return false; + } + + /** + * @see org.eclipse.debug.core.model.IValueModification#verifyValue(IValue) + */ + public boolean verifyValue(IValue value) throws DebugException { + return false; + } + + /** + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class) + */ + public Object getAdapter(Class adapter) { + return Platform.getAdapterManager().getAdapter(this, adapter); + } + + public String toString() { + + if(this.isObject()) { + return this.getName() + " [class: " + this.getClassName() + "]"; + } else if(this.isResource()) { + return this.getName() + " [resource: " + this.getClassName() + "] = " + ((PHPValue) this.getValue()); + } else if (this.isHashValue()) { + int elements= Integer.parseInt(((PHPValue) this.getValue()).getValueString()); + switch (elements) { + case 0: + return this.getName() + " [no elements]"; + case 1: + return this.getName() + " [1 element]"; + default: + return this.getName() + " [" + elements + " elements]"; + } + } else { + return this.getName() + " = " + ((PHPValue) this.getValue()); + } + + } + + public PHPStackFrame getStackFrame() { + return stackFrame; + } + + public PHPVariable getParent() { + return parent; + } + + public void setParent(PHPVariable parent) { + this.parent = parent; + } + + public String getQualifiedName() { + return this.getName(); + } + + public boolean isBoolean() { + return isBoolean; + } + + public boolean isResource() { + return isResource; + } + + public boolean isString() { + return isString; + } + + public boolean isLocal() { + return isLocal; + } + + public boolean isObject() { + return isObject; + } + + public String getObjectId() { + return objectId; + } + + public boolean isHashValue() { + try { + return ((PHPValue) this.getValue()).hasVariables(); + } catch (DebugException e) { + return false; + } + } + + public String getClassName() { + return className; + } +} diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/net_sourceforge_phpdt_internal_debug_core_Environment.c b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/net_sourceforge_phpdt_internal_debug_core_Environment.c new file mode 100644 index 0000000..e771f98 --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/net_sourceforge_phpdt_internal_debug_core_Environment.c @@ -0,0 +1,76 @@ +#ifdef WIN32 +# include "windows.h" +#else +# include "string.h" +# include "stdlib.h" +#endif +#define BUFFER 512 + +#include "net_sourceforge_phpdt_internal_debug_core_Environment.h" + +JNIEXPORT jstring JNICALL Java_net_sourceforge_phpdt_internal_debug_core_Environment_getenv + (JNIEnv *env, jclass c, jstring jname) +{ + // Retrieve the argument + char cname[BUFFER]; + const char *str = (*env)->GetStringUTFChars(env, jname, (jboolean *)NULL); + + strncpy(cname, str, BUFFER); + (*env)->ReleaseStringUTFChars(env, jname, str); + + #ifdef WIN32 + char cvalue[BUFFER]; + int result = GetEnvironmentVariable(cname, cvalue, BUFFER); + if (result == 0) + return 0; + else + return (*env)->NewStringUTF(env, cvalue); + #else // UNIX + char *cvalue = getenv(cname); + if (cvalue == 0) + return 0; + else + return (*env)->NewStringUTF(env, cvalue); + #endif +} + +JNIEXPORT jstring JNICALL Java_net_sourceforge_phpdt_internal_debug_core_Environment_setenv + (JNIEnv *env, jclass c, jstring jname, jstring jvalue) +{ + // Retrieve the arguments + char cname[BUFFER], cvalue[BUFFER]; + const char *str = (*env)->GetStringUTFChars(env, jname, (jboolean *)NULL); + + strncpy(cname, str, BUFFER); + (*env)->ReleaseStringUTFChars(env, jname, str); + str = (*env)->GetStringUTFChars(env, jvalue, (jboolean *)NULL); + strncpy(cvalue, str, BUFFER); + (*env)->ReleaseStringUTFChars(env, jvalue, str); + + #ifdef WIN32 + SetEnvironmentVariable(cname, cvalue); + #else // UNIX + char envbuf[BUFFER]; + strncpy(envbuf, cname, BUFFER); + strncat(envbuf, "=", BUFFER-strlen(envbuf)); + strncat(envbuf, cvalue, BUFFER-strlen(envbuf)); + putenv(envbuf); + #endif + return 0; +} + +#ifdef __LCC__ + +/** + * Valentin Valchev (Bulgaria, www.prosyst.com) + * This is the standart implementation of Java 2 OnLoad and OnUnload native + * library calls. This template defines them empty functions + */ +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) +{ + return JNI_VERSION_1_2; +} +JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) +{ +} +#endif diff --git a/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/net_sourceforge_phpdt_internal_debug_core_Environment.h b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/net_sourceforge_phpdt_internal_debug_core_Environment.h new file mode 100644 index 0000000..c0bb9fa --- /dev/null +++ b/net.sourceforge.phpeclipse.debug.core/src/net/sourceforge/phpdt/internal/debug/core/net_sourceforge_phpdt_internal_debug_core_Environment.h @@ -0,0 +1,29 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class net_sourceforge_phpdt_internal_debug_core_Environment */ + +#ifndef _Included_net_sourceforge_phpdt_internal_debug_core_Environment +#define _Included_net_sourceforge_phpdt_internal_debug_core_Environment +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: net_sourceforge_phpdt_internal_debug_core_Environment + * Method: getenv + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_net_sourceforge_phpdt_internal_debug_core_Environment_getenv + (JNIEnv *, jclass, jstring); + +/* + * Class: net_sourceforge_phpdt_internal_debug_core_Environment + * Method: setenv + * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_net_sourceforge_phpdt_internal_debug_core_Environment_setenv + (JNIEnv *, jclass, jstring, jstring); + +#ifdef __cplusplus +} +#endif +#endif