Show errors in console
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / PHPDBGInterface.java
1 /**********************************************************************
2 Copyright (c) 2000, 2002 IBM Corp. and others.
3 All rights reserved. This program and the accompanying materials
4 are made available under the terms of the Common Public License v1.0
5 which accompanies this distribution, and is available at
6 http://www.eclipse.org/legal/cpl-v10.html
7
8 Contributors:
9         Vicente Fernando - www.alfersoft.com.ar - Initial implementation
10 **********************************************************************/
11 package net.sourceforge.phpdt.internal.debug.core;
12
13 import java.io.IOException;
14 import java.io.BufferedReader;
15 import java.io.OutputStream;
16 import java.util.Vector;
17
18 import org.eclipse.core.runtime.IStatus;
19 import org.eclipse.core.runtime.Status;
20 import org.eclipse.debug.core.DebugException;
21
22 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
23 import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
24 import net.sourceforge.phpdt.internal.debug.core.model.PHPValue;
25
26 public class PHPDBGInterface {
27
28         // Public
29         public boolean sessionEnded= false;
30         public int sessType= -1;        
31         public int BPUnderHit= 0;
32         public String sessID= new String();
33         
34         // Private
35         private int[] LastBPRead= new int[10];
36         private Vector DBGBPList= new Vector();
37         private PHPStackFrame[] DBGStackList;
38         private PHPVariable[] DBGVariableList;
39         private Vector DBGMods= new Vector();
40         private Vector DBGVars= new Vector();
41         private BufferedReader in;
42         private OutputStream os;
43         private boolean shouldStop= false, isRef= false, hasChildren= false, isObject= false;
44         private String evalRet= new String("");
45         private String serGlobals= new String("");
46         private String typeRead= new String("");
47         private String className= new String("");
48         private int finalPos=0, refCounter=0, rawCounter=1000;
49         private PHPDBGProxy proxy= null;
50         private boolean stopOnError= false;
51         private char[] lastCommand= new char[4];
52          
53         public PHPDBGInterface(BufferedReader in, OutputStream os, PHPDBGProxy proxy) {
54                 DBGBPList.clear();
55                 this.in= in;
56                 this.os= os;
57                 this.proxy= proxy;
58         }
59
60         public int addBreakpoint(String mod_name, int line) throws IOException {
61                 return setBreakpoint(mod_name, "", line, PHPDBGBase.BPS_ENABLED + PHPDBGBase.BPS_UNRESOLVED, 0, 0, 0, 0, 0);
62         }
63
64         public void removeBreakpoint(String mod_name, int line, int bpNo) throws IOException {
65                 setBreakpoint(mod_name, "", line, PHPDBGBase.BPS_DISABLED, 0, 0, 0, bpNo, 0);
66         }
67
68         public void requestDBGVersion() throws IOException {
69                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
70                 PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_VER);
71                 
72                 DBGPacket.addFrame(DBGFrame);
73
74                 if(proxy.getSocket().isClosed()) return;
75                 DBGPacket.sendPacket(os);
76         }
77
78         public void getSourceTree() throws IOException {
79                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
80                 PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_SRC_TREE);
81                 
82                 DBGPacket.addFrame(DBGFrame);
83                 
84                 if(proxy.getSocket().isClosed()) return;
85                 DBGPacket.sendPacket(os);
86
87                 // Wait response (1 second) and read response
88                 waitResponse(1000);
89                 flushAllPackets();
90         }
91
92         public void addDBGModName(String modName) throws IOException {
93                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
94                 PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
95                 
96                 rawCounter++;
97                 DBGFrame.addInt(rawCounter);                            // FRAME_RAWDATA ID
98                 DBGFrame.addInt(modName.length() + 1);          // length of rawdata (+ null char)
99                 DBGFrame.addString(modName);                            // file name
100                 DBGFrame.addChar('\0');                                         // null char
101
102                 DBGPacket.addFrame(DBGFrame);
103                 
104                 if(proxy.getSocket().isClosed()) return;
105                 DBGPacket.sendPacket(os);
106         }
107
108         // Returns DBG Breakpoint ID
109         private int setBreakpoint(String mod_name, String condition, int line, int state, int istemp, int hitcount, int skiphits, int bpno, int isunderhit) throws IOException {
110                 int modNo= 0;
111
112                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
113                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_BPS);
114                 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
115
116                 modNo= getModByName(mod_name);
117                 
118                 if(modNo >= 0) {
119                         DBGFrame1.addInt(modNo);        // mod number
120                 } else {
121                         DBGFrame1.addInt(0);            // mod number (0 use file name)
122                 }
123                 
124                 DBGFrame1.addInt(line);                 // line number
125                 
126                 if(modNo >= 0) {
127                         DBGFrame1.addInt(0);                    // use mod number
128                 } else {
129                         rawCounter++;
130                         DBGFrame1.addInt(rawCounter);   // ID of FRAME_RAWDATA to send file name
131                 }
132
133                 DBGFrame1.addInt(state);                // state BPS_*
134                 DBGFrame1.addInt(istemp);               // istemp
135                 DBGFrame1.addInt(hitcount);             // hit count
136                 DBGFrame1.addInt(skiphits);             // skip hits
137                 DBGFrame1.addInt(0);                    // ID of condition
138                 DBGFrame1.addInt(bpno);                 // breakpoint number
139                 DBGFrame1.addInt(isunderhit);   // is under hit
140                 
141                 if(modNo < 0) {
142                         DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
143                         DBGFrame2.addInt(mod_name.length() + 1);        // length of rawdata (+ null char)
144                         DBGFrame2.addString(mod_name);                          // file name
145                         DBGFrame2.addChar('\0');                                        // null char
146                         // First add file name data
147                         DBGPacket.addFrame(DBGFrame2);
148                 }
149
150                 // Second add command data
151                 DBGPacket.addFrame(DBGFrame1);
152
153                 if(proxy.getSocket().isClosed()) return 0;
154                 DBGPacket.sendPacket(os);
155
156                 clearLastBP();
157
158                 // Wait response (1 second) and read response
159                 waitResponse(1000);
160                 flushAllPackets();
161
162                 return LastBPRead[8];
163         }
164
165         private void clearLastBP() {
166                 int i;
167
168                 for(i=0; i < LastBPRead.length; i++)
169                         LastBPRead[i]= 0;
170         }
171
172         private void copyToLastBP(int[] BPBody) {
173                 int i;
174
175                 for(i=0; i < LastBPRead.length; i++)
176                         LastBPRead[i]= BPBody[i];
177         }
178
179         public void continueExecution() throws IOException {
180                 BPUnderHit= 0;
181                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_CONTINUE);
182                 if(proxy.getSocket().isClosed()) return;
183                 DBGPacket.sendPacket(os);
184                 lastCommand= PHPDBGBase.DBGA_CONTINUE;
185         }
186
187         public void pauseExecution() throws IOException {
188                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.IntToChar4(PHPDBGBase.DBGC_PAUSE));
189                 if(proxy.getSocket().isClosed()) return;
190                 DBGPacket.sendPacket(os);
191         }
192
193         private int getBPUnderHit() {
194                 int i, BPUnder=0;
195                 int[] dbg_bpl_body= new int[10];
196
197                 // look for bp under hit
198                 for(i=0; i < DBGBPList.size(); i++) {
199                         dbg_bpl_body= (int[]) DBGBPList.get(i);
200                         if(dbg_bpl_body[9] == 1) {
201                                 BPUnder= dbg_bpl_body[8];
202                         }
203                 }
204                 return BPUnder;
205         }
206
207         public void stepInto() throws IOException {
208                 BPUnderHit= 0;
209                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPINTO);
210                 if(proxy.getSocket().isClosed()) return;
211                 DBGPacket.sendPacket(os);
212                 lastCommand= PHPDBGBase.DBGA_STEPINTO;
213         }
214
215         public void stepOver() throws IOException {
216                 BPUnderHit= 0;
217                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOVER);
218                 if(proxy.getSocket().isClosed()) return;
219                 DBGPacket.sendPacket(os);
220                 lastCommand= PHPDBGBase.DBGA_STEPOVER;
221         }
222
223         public void stepOut() throws IOException {
224                 BPUnderHit= 0;
225                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOUT);
226                 if(proxy.getSocket().isClosed()) return;
227                 DBGPacket.sendPacket(os);
228                 lastCommand= PHPDBGBase.DBGA_STEPOUT;
229         }
230
231         public void stopExecution() throws IOException {
232                 BPUnderHit= 0;
233                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STOP);
234                 if(proxy.getSocket().isClosed()) return;
235                 DBGPacket.sendPacket(os);
236         }
237
238         public PHPVariable[] getVariables(PHPStackFrame stack) throws IOException, DebugException  {
239                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
240                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
241         
242                 DBGFrame1.addInt(0);                                            // istr = raw data ID
243                 DBGFrame1.addInt(1);                                            // scope_id = -1 means current location, 0 never used, +1 first depth
244                 
245                 // Add command data
246                 DBGPacket.addFrame(DBGFrame1);
247                 
248                 if(proxy.getSocket().isClosed()) return null;
249                 DBGPacket.sendPacket(os);
250
251                 waitResponse(1000);
252                 flushAllPackets();
253                 
254                 // Process serialized variables
255                 DBGVariableList= procVars(stack);
256
257                 return DBGVariableList;
258         }
259
260         public void log(String logString) throws IOException, DebugException  {
261                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
262                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_LOG);
263                 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
264
265                 rawCounter++;
266                 DBGFrame1.addInt(rawCounter);                           // ilog
267                 DBGFrame1.addInt(1);                                            // type
268                 DBGFrame1.addInt(0);                                            // mod_no
269                 DBGFrame1.addInt(0);                                            // line_no
270                 DBGFrame1.addInt(0);                                            // imod_name
271                 DBGFrame1.addInt(0);                                            // ext_info             
272
273                 DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
274                 DBGFrame2.addInt(logString.length() + 1);       // length of rawdata (+ null char)
275                 DBGFrame2.addString(logString);                         // log string
276                 DBGFrame2.addChar('\0');                                        // null char
277
278                 // Add raw data first
279                 DBGPacket.addFrame(DBGFrame2);
280                 // Add command data
281                 DBGPacket.addFrame(DBGFrame1);
282                 
283                 if(proxy.getSocket().isClosed()) return;
284                 DBGPacket.sendPacket(os);
285
286                 waitResponse(1000);
287                 flushAllPackets();
288         }
289
290         public void evalBlock(String evalString) throws IOException, DebugException  {
291                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
292                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
293                 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
294
295                 rawCounter++;
296                 DBGFrame1.addInt(rawCounter);                           // istr = raw data ID
297                 DBGFrame1.addInt(-1);                                           // scope_id = -1 means current location, 0 never used, +1 first depth
298
299                 DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
300                 DBGFrame2.addInt(evalString.length() + 1);      // length of rawdata (+ null char)
301                 DBGFrame2.addString(evalString);                        // eval block
302                 DBGFrame2.addChar('\0');                                        // null char
303
304                 // Add raw data first
305                 DBGPacket.addFrame(DBGFrame2);
306                 // Add command data
307                 DBGPacket.addFrame(DBGFrame1);
308                 
309                 if(proxy.getSocket().isClosed()) return;
310                 DBGPacket.sendPacket(os);
311
312                 waitResponse(1000);
313                 flushAllPackets();
314         }
315
316         public void flushAllPackets() throws IOException {
317                 while(readResponse() != 0);
318         }
319
320         public String getModByNo(int modNo) {
321                 int i;
322                 PHPDBGMod dbg_mod;
323
324                 // look for mod
325                 for(i=0; i < DBGMods.size(); i++) {
326                         dbg_mod= (PHPDBGMod) DBGMods.get(i);
327                         if(dbg_mod.getNo() == modNo) {
328                                 return dbg_mod.getName(); 
329                         }
330                 }
331                 return "";
332         }
333
334         private int getModByName(String modName) {
335                 int i;
336                 PHPDBGMod dbg_mod;
337
338                 // look for mod
339                 for(i=0; i < DBGMods.size(); i++) {
340                         dbg_mod= (PHPDBGMod) DBGMods.get(i);
341                         if(dbg_mod.getName().equalsIgnoreCase(modName)) {
342                                 return dbg_mod.getNo(); 
343                         }
344                 }
345                 return -1;
346         }
347
348         private String getRawFrameData(char[] framesInfo, int frameNo) {
349                 int nextFrame= 0;
350                 int[] dbg_frame= new int[2];
351                 
352                 while(nextFrame < framesInfo.length) {
353                         dbg_frame[0] = PHPDBGBase.Char4ToInt(framesInfo, nextFrame);            // frame name
354                         dbg_frame[1] = PHPDBGBase.Char4ToInt(framesInfo, nextFrame + 4);        // frame size
355
356                         nextFrame += 8;
357                         if(dbg_frame[1] == 0) return "";
358
359                         switch(dbg_frame[0]) {
360                                 case PHPDBGBase.FRAME_RAWDATA:
361                                         if(frameNo == PHPDBGBase.Char4ToInt(framesInfo, nextFrame)) {
362                                                 int toRead= PHPDBGBase.Char4ToInt(framesInfo, nextFrame + 4);
363                                                 return String.copyValueOf(framesInfo, nextFrame + 8, toRead);
364                                         }
365                                         break;
366                         }
367                         // go to next frame
368                         nextFrame += dbg_frame[1];
369                 }
370                 return "";
371         }
372
373         public PHPVariable[] getInstVars(PHPVariable phpVar) throws DebugException {
374                 Vector vecVars= new Vector();
375                 PHPVariable localPHPVar;
376                 int i=0;
377                 
378                 // already unserialized
379                 for(i=0; i < DBGVars.size(); i++) {
380                         localPHPVar= (PHPVariable)DBGVars.get(i);
381                         if(localPHPVar.getParent() == phpVar) {
382                                 vecVars.add(localPHPVar);
383                         }
384                 }
385                 PHPVariable[] arrVars= new PHPVariable[vecVars.size()];
386                 arrVars= (PHPVariable[]) vecVars.toArray(arrVars);
387
388                 return arrVars;
389         }
390         
391         private PHPVariable[] procVars(PHPStackFrame stack) throws DebugException {
392                 Vector vecVars= new Vector();
393                 
394                 // unserialize
395                 finalPos= 0;
396                 refCounter= 0;
397                 doUnserialize(stack, vecVars, null);
398
399                 DBGVars= vecVars;
400                 
401                 return(getInstVars(null));
402         }
403
404         private String readValue(String serialVars) throws DebugException {
405                 int startPos=0, endPos=0, lenStr=0, i=0, elements=0;
406                 String ret= new String("");
407
408                 switch(serialVars.charAt(0)) {
409                         case 'a':       // associative array, a:elements:{[index][value]...}
410                                 typeRead= "hash";
411                                 startPos= 1;
412                                 endPos= serialVars.indexOf(':', startPos + 1);
413                                 if(endPos == -1) return "";
414                                 finalPos += endPos + 2;
415                                 ret= new String(serialVars.substring(startPos + 1, endPos));
416                                 
417                                 hasChildren= true;
418                                 break;
419                         case 'O':       // object, O:name_len:"name":elements:{[attribute][value]...}
420                                 typeRead= "object";
421                                 
422                                 startPos= 1;
423                                 endPos= serialVars.indexOf(':', startPos + 1);
424                                 if(endPos == -1) return "";
425                                 
426                                 // get object class
427                                 lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos));
428                                 startPos= endPos + 2;
429                                 endPos= lenStr + startPos;
430                                 className= new String(serialVars.substring(startPos, endPos).toString());
431
432                                 // get num of elements
433                                 startPos= endPos + 1;
434                                 endPos= serialVars.indexOf(':', startPos + 1);
435                                 if(endPos == -1) return "";
436                                 finalPos += endPos + 2;
437                                 ret= new String(serialVars.substring(startPos + 1, endPos));
438
439                                 isObject= true;
440                                 hasChildren= true;                              
441                                 break;
442                         case 's':       // string, s:length:"data";
443                                 typeRead= "string";
444                                 startPos= 1;
445                                 endPos= serialVars.indexOf(':', startPos + 1);
446                                 if(endPos == -1) return "";
447
448                                 lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos));
449                                 startPos= endPos + 2;
450                                 endPos= lenStr + startPos;
451                                 ret= new String(serialVars.substring(startPos, endPos).toString());
452                                 finalPos += endPos + 2; 
453                                 break;
454                         case 'i':       // integer, i:123;
455                                 typeRead= "integer";
456                                 startPos= 1;
457                                 endPos= serialVars.indexOf(';', startPos + 1);
458                                 if(endPos == -1) return "";
459
460                                 ret= new String(serialVars.substring(startPos + 1, endPos).toString());
461                                 finalPos += endPos + 1;
462                                 break;
463                         case 'd':       // double (float), d:1.23;
464                                 typeRead= "double";
465                                 startPos= 1;
466                                 endPos= serialVars.indexOf(';', startPos + 1);
467                                 if(endPos == -1) return "";
468         
469                                 ret= new String(serialVars.substring(startPos + 1, endPos).toString());
470                                 finalPos += endPos + 1;
471                                 break;
472                         case 'N':       // NULL, N;
473                                 typeRead= "null";
474                                 ret= "nil";
475                                 finalPos += 2;
476                                 break;
477                         case 'b':       // bool, b:0 or 1
478                                 typeRead= "boolean";
479                                 ret= (serialVars.charAt(2) == '1')?"true":"false";
480                                 finalPos += endPos + 4;
481                                 break;
482                         case 'z':       // resource, z:typename_len:"typename":valres;
483                                 typeRead= "resource";
484                                 
485                                 startPos= 1;
486                                 endPos= serialVars.indexOf(':', startPos + 1);
487                                 if(endPos == -1) return "";
488                 
489                                 // get resource type name
490                                 lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos));
491                                 startPos= endPos + 2;
492                                 endPos= lenStr + startPos;
493                                 className= new String(serialVars.substring(startPos, endPos).toString());
494
495                                 // get resource value
496                                 startPos= endPos + 1;
497                                 endPos= serialVars.indexOf(';', startPos + 1);
498                                 if(endPos == -1) return "";
499                                 ret= new String(serialVars.substring(startPos + 1, endPos));
500                                 finalPos += endPos + 1;
501                                 break;
502                         case 'r':
503                         case 'R':
504                                 typeRead= "reference";
505                                 startPos= 1;
506                                 endPos= serialVars.indexOf(';', startPos + 1);
507                                 if(endPos == -1) return "0";
508
509                                 ret= new String(serialVars.substring(startPos + 1, endPos));
510                                 finalPos += endPos + 1;
511                                 isRef= true;
512                                 break;
513                         case ';':
514                                 typeRead= "unknown";
515                                 finalPos+= 1;
516                                 break;
517                         case '?':
518                                 finalPos+= 1;
519                         default:
520                                 finalPos+= 1;
521                                 typeRead= "unknown";
522                                 break;
523                 }
524                 return ret;
525         }
526
527         private void doUnserialize(PHPStackFrame stack, Vector vecVars, PHPVariable parent) throws DebugException {
528                 int i, elements= 0;
529                 PHPVariable newVar= null;
530                 String value= new String("");
531                 String name= new String("");
532                 String tmp= new String("");
533                 String[] tmpSplit;
534
535                 if(finalPos > serGlobals.length() || serGlobals.equals("") || serGlobals.substring(finalPos).equals("")) return;
536
537                 isRef= false;
538                 hasChildren= false;
539                 isObject= false;
540                 name= readValue(serGlobals.substring(finalPos));
541                 
542                 if(hasChildren) {
543                         // main array
544                         if(refCounter == 0) {
545                                 value= name;
546                                 name= "";
547                         }
548                 } else {
549                         hasChildren= false;
550                         isRef= false;
551                         value= readValue(serGlobals.substring(finalPos));
552                         // replaceAll doesn't work, why???
553                         tmpSplit= value.split("\\\\");
554                         value= "";
555                         for(i= 0; i < tmpSplit.length; i++) {
556                                 value= value + tmpSplit[i];
557                                 if(!tmpSplit[i].equals("")) {
558                                         if(i < (tmpSplit.length - 1)) {
559                                                 value= value + "\\";
560                                         }
561                                 }
562                         }
563                 }
564                 
565                 if(!name.equals("")) {
566                         if(isRef) {
567                                 PHPVariable varPHP;
568                                 for(i=0; i < vecVars.size(); i++) {
569                                         varPHP= (PHPVariable) vecVars.get(i);
570                                         if(varPHP.getObjectId().equals(value)) {
571                                                 newVar= new PHPVariable(stack, name, "local", true, (PHPValue)varPHP.getValue());
572                                                 break;                                          
573                                         }
574                                 }
575                                 if(newVar == null) {
576                                         newVar= new PHPVariable(stack, name, "local", false, null);
577                                 }
578                         } else {
579                                 refCounter++;
580                                 newVar= new PHPVariable(stack, name, "local", value, typeRead, hasChildren, Integer.toString(refCounter), className);
581                         }
582                         newVar.setParent(parent);
583                         vecVars.add(newVar);
584                 }
585                 if(hasChildren) {
586                         elements= Integer.parseInt(value);
587                         for(i=0; i < elements; i++)
588                                 doUnserialize(stack, vecVars, newVar);
589
590                         // skip "}"
591                         finalPos += 1;
592                 }
593         }
594
595         public int readResponse() throws IOException {
596                 int bytesToRead=0, nextFrame=0, i=0, cmdReceived=0, stackIndex=0;
597                 boolean errorStack= false;
598                 char[] dbg_header_struct_read= new char[16];
599                 int[] dbg_header_struct= new int[4];
600                 int[] dbg_bpl_tmp= new int[10];
601                 int[] dbg_frame= new int[2];
602                 int[] dbg_eval_tmp= new int[3];
603                 int[] dbg_src_tree_tmp= new int[4];
604                 int[] dbg_error_tmp= new int[2];
605                 Vector rawList= new Vector();
606                 Vector stackList= new Vector();
607                 PHPStackFrame[] newStackList;
608                 
609                 rawList.clear();
610                 stackList.clear();
611                 // Read from input
612                 while(readInput(dbg_header_struct_read, 16) != 0) {
613                         dbg_header_struct[0] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 0);
614                         dbg_header_struct[1] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 4);
615                         dbg_header_struct[2] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 8);
616                         dbg_header_struct[3] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 12);
617                         
618                         // Check DBG sync bytes
619                         if(dbg_header_struct[0] != 0x5953) return 0;
620                         
621                         cmdReceived= dbg_header_struct[1];
622                         bytesToRead= dbg_header_struct[3];
623
624                         //System.out.println("Response Received: " + cmdReceived);
625                         char[] entirePack= new char[bytesToRead];
626
627                         if(bytesToRead > 0) {
628                                 if(readInput(entirePack, bytesToRead) < bytesToRead) return 0;
629                         }
630                         
631                         // First process frames
632                         nextFrame= 0;
633                         while(nextFrame < bytesToRead) {
634                                 dbg_frame[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame);            // frame name
635                                 dbg_frame[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);        // frame size
636                                 nextFrame += 8;
637                                 if(dbg_frame[1] == 0) return 0;
638                                 switch(dbg_frame[0]) {
639                                         case PHPDBGBase.FRAME_STACK:
640                                                 int[] dbg_stack_new= new int[4];
641                                                 dbg_stack_new[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);    // line no
642                                                 dbg_stack_new[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);    // mod no
643                                                 dbg_stack_new[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8);    // scope id
644                                                 dbg_stack_new[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12);   // id of description string
645
646                                                 if(dbg_stack_new[1] != 0 && !errorStack) {
647                                                         stackIndex++;
648                                                         PHPStackFrame newStack= new PHPStackFrame(null, getModByNo(dbg_stack_new[1]), dbg_stack_new[0], stackIndex, getRawFrameData(entirePack, dbg_stack_new[3]), dbg_stack_new[1]);
649                                                         stackList.add(newStack);
650                                                 }
651                                                 errorStack= false;
652                                                 break;
653                                         case PHPDBGBase.FRAME_SOURCE:
654                                                 break;
655                                         case PHPDBGBase.FRAME_SRC_TREE:
656                                                 dbg_src_tree_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);         // parent_mod_no
657                                                 dbg_src_tree_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);         // parent_line_no               /* NOT USED */
658                                                 dbg_src_tree_tmp[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8);         // mod_no
659                                                 dbg_src_tree_tmp[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12);        // imod_name
660
661                                                 if(getModByNo(dbg_src_tree_tmp[2]).equals("")) {
662                                                         String fileName= new String(getRawFrameData(entirePack, dbg_src_tree_tmp[3]));
663                                                         // Remove '\0' char
664                                                         if(fileName.length() > 0) fileName= fileName.substring(0, fileName.length() - 1);
665
666                                                         if(dbg_src_tree_tmp[2] != 0) {
667                                                                 PHPDBGMod modNew= new PHPDBGMod(dbg_src_tree_tmp[2], fileName);
668                                                                 DBGMods.add(modNew);
669                                                         }
670                                                 }
671                                                 break;
672                                         case PHPDBGBase.FRAME_RAWDATA:
673                                                 break;
674                                         case PHPDBGBase.FRAME_ERROR:
675                                                 errorStack= true;
676                                                 dbg_error_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);            // type                 /* type of error */
677                                                 dbg_error_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);            // imessage             /* ID of error message */
678                                                 
679                                                 String error= "\n";
680                                                 switch(dbg_error_tmp[0]) {
681                                                         case PHPDBGBase.E_ERROR:
682                                                                 error+= "[Error]";
683                                                                 break;
684                                                         case PHPDBGBase.E_WARNING:
685                                                                 error+= "[Warning]";
686                                                                 break;
687                                                         case PHPDBGBase.E_PARSE:
688                                                                 error+= "[Parse Error]";
689                                                                 break;
690                                                         case PHPDBGBase.E_NOTICE:
691                                                                 error+= "[Notice]";
692                                                                 break;
693                                                         case PHPDBGBase.E_CORE_ERROR:
694                                                                 error+= "[Core Error]";
695                                                                 break;
696                                                         case PHPDBGBase.E_CORE_WARNING:
697                                                                 error+= "[Core Warning]";
698                                                                 break;
699                                                         case PHPDBGBase.E_COMPILE_ERROR:
700                                                                 error+= "[Compile Error]";
701                                                                 break;
702                                                         case PHPDBGBase.E_COMPILE_WARNING:
703                                                                 error+= "[Compile Warning]";
704                                                                 break;
705                                                         case PHPDBGBase.E_USER_ERROR:
706                                                                 error+= "[User Error]";
707                                                                 break;
708                                                         case PHPDBGBase.E_USER_WARNING:
709                                                                 error+= "[User Warning]";
710                                                                 break;
711                                                         case PHPDBGBase.E_USER_NOTICE:
712                                                                 error+= "[User Notice]";
713                                                                 break;
714                                                         default:
715                                                                 error+= "[Unexpected Error]";
716                                                                 break;
717                                                 }
718                                                 error+= ": ";
719                                                 error+= new String(getRawFrameData(entirePack, dbg_error_tmp[1]));
720                                                 // Remove '\0' char
721                                                 if(error.length() > 0) error= error.substring(0, error.length() - 1);
722                                                 error+= "\n";
723
724                                                 PHPDebugCorePlugin.log(new DebugException(new Status(IStatus.WARNING, PHPDebugCorePlugin.PLUGIN_ID, IStatus.OK, error, null)));
725                                                 // To print errors on the console, I must execute a code in the
726                                                 // php context, that write the stderr... I didn't found a better way
727                                                 // TODO: Find a better way????
728                                                 String codeExec= "";
729                                                 codeExec= "fwrite(fopen('php://stderr', 'w'),\\\"" + error + "\\\");";
730                                                 try {
731                                                         evalBlock("eval(\"" + codeExec + "\");");
732                                                 } catch (DebugException e) {
733                                                         PHPDebugCorePlugin.log(e);
734                                                 }
735                                                 if(!stopOnError) {
736                                                         if(lastCommand.equals(PHPDBGBase.DBGA_CONTINUE)) {
737                                                                 continueExecution();
738                                                         } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPINTO)) {
739                                                                 stepInto();
740                                                         } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPOUT)) {
741                                                                 stepOut();
742                                                         } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPOVER)) {
743                                                                 stepOver();
744                                                         }
745                                                 }
746                                                 break;
747                                         case PHPDBGBase.FRAME_EVAL:
748                                                 String evalString= new String("");
749                                                 dbg_eval_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); // istr
750                                                 dbg_eval_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); // iresult
751                                                 dbg_eval_tmp[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8); // ierror
752
753                                                 evalRet= getRawFrameData(entirePack, dbg_eval_tmp[1]);
754                                                 evalString= getRawFrameData(entirePack, dbg_eval_tmp[0]);
755                                                 serGlobals= evalRet;
756                                                 break;
757                                         case PHPDBGBase.FRAME_BPS:
758                                                 break;
759                                         case PHPDBGBase.FRAME_BPL:
760                                                 int[] dbg_bpl_new= new int[10];
761                                                 dbg_bpl_new[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);
762                                                 dbg_bpl_new[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);
763                                                 dbg_bpl_new[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8);
764                                                 dbg_bpl_new[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12);
765                                                 dbg_bpl_new[4] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 16);
766                                                 dbg_bpl_new[5] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 20);
767                                                 dbg_bpl_new[6] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 24);
768                                                 dbg_bpl_new[7] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 28);
769                                                 dbg_bpl_new[8] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 32);
770                                                 dbg_bpl_new[9] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 36);
771         
772                                                 // look if breakpoint already exists in vector
773                                                 for(i=0; i < DBGBPList.size(); i++) {
774                                                         dbg_bpl_tmp= (int[]) DBGBPList.get(i);
775                                                         if(dbg_bpl_tmp[8] == dbg_bpl_new[8]) {
776                                                                 DBGBPList.remove(i);
777                                                                 break;
778                                                         }
779                                                 }
780
781                                                 // add breakpoint to vector
782                                                 DBGBPList.add(dbg_bpl_new);
783                                                 copyToLastBP(dbg_bpl_new);
784                                                 
785                                                 // mod no returned?
786                                                 if(getModByNo(dbg_bpl_new[0]).equals("")) {
787                                                         String fileName= new String(getRawFrameData(entirePack, dbg_bpl_new[2]));
788                                                         // Remove '\0' char
789                                                         if(fileName.length() > 0) fileName= fileName.substring(0, fileName.length() - 1);
790                                                         if(dbg_bpl_new[0] != 0) {
791                                                                 PHPDBGMod modNew= new PHPDBGMod(dbg_bpl_new[0], fileName);
792                                                                 DBGMods.add(modNew);
793                                                         }
794                                                 }                                                       
795                                                 break;
796                                         case PHPDBGBase.FRAME_VER:
797                                                 break;
798                                         case PHPDBGBase.FRAME_SID:
799                                                 break;
800                                         case PHPDBGBase.FRAME_SRCLINESINFO:
801                                                 break;
802                                         case PHPDBGBase.FRAME_SRCCTXINFO:
803                                                 break;
804                                         case PHPDBGBase.FRAME_LOG:
805                                                 break;
806                                         case PHPDBGBase.FRAME_PROF:
807                                                 break;
808                                         case PHPDBGBase.FRAME_PROF_C:
809                                                 break;
810                                         case PHPDBGBase.FRAME_SET_OPT:
811                                                 break;
812                                 }
813                                 // go to next frame
814                                 nextFrame += dbg_frame[1];
815                         }
816                         
817                         // Now process command
818                         switch(cmdReceived) {
819                                 case PHPDBGBase.DBGC_REPLY:
820                                         break;
821                                 case PHPDBGBase.DBGC_STARTUP:
822                                         break;
823                                 case PHPDBGBase.DBGC_END:
824                                         sessionEnded= true;
825                                         break;
826                                 case PHPDBGBase.DBGC_BREAKPOINT:
827                                         newStackList= new PHPStackFrame[stackList.size()];
828                                         newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
829                                         DBGStackList= newStackList;
830                                         BPUnderHit= getBPUnderHit();
831                                         break;
832                                 case PHPDBGBase.DBGC_STEPINTO_DONE:
833                                 case PHPDBGBase.DBGC_STEPOVER_DONE:
834                                 case PHPDBGBase.DBGC_STEPOUT_DONE:
835                                 case PHPDBGBase.DBGC_EMBEDDED_BREAK:
836                                 case PHPDBGBase.DBGC_PAUSE:
837                                         BPUnderHit= 1;
838                                         newStackList= new PHPStackFrame[stackList.size()];
839                                         newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
840                                         DBGStackList= newStackList;
841                                         break;
842                                 case PHPDBGBase.DBGC_ERROR:
843                                         stackList.clear();
844                                         newStackList= new PHPStackFrame[stackList.size()];
845                                         newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
846                                         DBGStackList= newStackList;
847                                         break;
848                                 case PHPDBGBase.DBGC_LOG:
849                                         break;
850                                 case PHPDBGBase.DBGC_SID:
851                                         break;
852                         }
853                 }
854                 return cmdReceived;
855         }
856
857         public PHPStackFrame[] getStackList() {
858                 return DBGStackList;
859         }
860
861         private int readInput(char[] buffer, int bytes) throws IOException {
862                 int bytesRead= 0;
863
864                 for(int i=0; i < bytes; i++) {
865                         if(in.ready()) {
866                                 buffer[i]= (char) (in.read() & 0x00FF);
867                                 bytesRead++;
868                         }
869                         else
870                                 break;                          
871                 }
872                 return bytesRead;
873         }
874         
875         public void setShouldStop() {
876                 this.shouldStop= true;
877         }
878
879         public void waitResponse(long milliseconds) throws IOException {
880                 long timeout= System.currentTimeMillis() + milliseconds;
881                 while(System.currentTimeMillis() < timeout) {
882                         if(in.ready() || shouldStop) {
883                                 break;
884                         }
885                 }
886         }
887 }