Modified: 1764120 - Variables View doesn't show global vars in class context
[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         Christian Perkonig - remote debug
11 **********************************************************************/
12 package net.sourceforge.phpdt.internal.debug.core;
13
14 import java.io.BufferedReader;
15 import java.io.IOException;
16 import java.io.OutputStream;
17 import java.util.Collections;
18 import java.util.Vector;
19
20 import net.sourceforge.phpdt.internal.debug.core.model.PHPDBGEvalString;
21 import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
22 import net.sourceforge.phpdt.internal.debug.core.model.PHPValue;
23 import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
24
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.Status;
27 import org.eclipse.debug.core.DebugException;
28
29 /**
30  * The interface object are created by the proxy
31  *
32  */
33 public class PHPDBGInterface {
34         public boolean                  sessionEnded = false;
35         public int                              sessType = -1;
36         public int                              BPUnderHit = 0;
37         public String                           sessID = new String();
38
39         private int[]                           LastBPRead = new int[10];
40         private Vector                  DBGBPList = new Vector();
41         private Vector                  DBGVarList = new Vector();
42         private PHPStackFrame[]         DBGStackList = new PHPStackFrame[0];
43         private Vector                  DBGMods = new Vector();                         // The module names and their numbers
44         private Vector                  stackListOld = new Vector();
45         private BufferedReader  in;
46         private OutputStream            os;                                                             // The stream which goes to DBG
47         private boolean                         shouldStop = false;
48         private String                  evalRet = new String("");
49         private int                             rawCounter = 1000;                                      // An rawData frame ID counter
50         private PHPDBGProxy             proxy = null;
51         private int                             lastCmd = -1;
52         private int                             sid = 0;
53         private boolean                         stopOnError = false;
54         private char[]                  lastCommand = new char[4];
55
56         private static final String GlobalVariablesTitle = PHPDebugCorePlugin
57                         .getResourceString("VariablesView.GlobalVariables.title");
58
59         /**
60          * @param in    The input stream (communication from DBG).
61          * @param os    The output stream (communication to DBG).
62          * @param proxy The proxy to which this interface belongs.
63          */
64         public PHPDBGInterface (BufferedReader in, OutputStream os, PHPDBGProxy proxy) {
65                 DBGBPList.clear ();
66
67                 this.in         = in;
68                 this.os         = os;
69                 this.proxy      = proxy;
70         }
71
72         /**
73          *
74          * @param mod_name  The module (source file) to which we add the breakpoint.
75          * @param line      The line where the breakpoint is set.
76          * @param hitCount  The number of hit counts before suspend.
77          * @param condition The break condition
78          * @return          Breakpoint ID ???.
79          */
80         public int addBreakpoint (String mod_name, int line, int hitCount, String condition) throws IOException {
81                 return setBreakpoint (mod_name, condition, line, PHPDBGBase.BPS_ENABLED + PHPDBGBase.BPS_UNRESOLVED, 0, hitCount, 0, 0, 0);
82         }
83
84         /**
85          *
86          * @param mod_name The module (source file) to which we add the breakpoint.
87          * @param line     The line where the breakpoint is set.
88          * @param bpNo     The breakpoint ID ???.
89          */
90         public void removeBreakpoint (String mod_name, int line, int bpNo) throws IOException {
91                 setBreakpoint (mod_name, "", line, PHPDBGBase.BPS_DISABLED, 0, 0, 0, bpNo, 0);
92         }
93
94         /**
95          * Is this method used anywhere?
96          *
97          */
98         public void requestDBGVersion () throws IOException {
99                 PHPDBGPacket DBGPacket;                                     // A DBG message packet
100                 PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
101
102                 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
103                 DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_VER);         // We want the version of DBG
104
105                 DBGPacket.addFrame (DBGFrame);                              // Add the 'what we want' to the DBG packet
106
107                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
108                         return;                                                 //  No
109                 }
110
111                 DBGPacket.sendPacket (os);                                                                      // Send the request to DBG
112         }
113
114         /**
115          * Called by the proxy
116          *
117          */
118         public void getSourceTree () throws IOException {
119                 PHPDBGPacket DBGPacket;                                     // A DBG message packet
120                 PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
121
122                 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
123                 DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_SRC_TREE);        // We want a source tree from DBG
124
125                 DBGPacket.addFrame (DBGFrame);                              // Add the 'what we want' to the DBG packet
126
127                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
128                         return;                                                                                                 //  No
129                 }
130
131                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
132
133                 waitResponse (1000);                                        // Wait for the DBG response (1 second)
134                 flushAllPackets ();                                                                             // Read and process the response from DBG
135         }
136
137         /**
138          * Is this method called from anywhere?
139          *
140          * @param modName The modul (filename).
141          */
142         public void addDBGModName (String modName) throws IOException {
143                 PHPDBGPacket DBGPacket;                                     // A DBG message packet
144                 PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
145
146                 DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
147                 DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);     // We want Module name from DBG
148
149                 rawCounter++;                                               // Increment the rawData ID counter
150                 DBGFrame.addInt (rawCounter);                                                           // FRAME_RAWDATA ID
151                 DBGFrame.addInt (modName.length () + 1);                                        // The length of rawdata string (incl. null char termination)
152                 DBGFrame.addString (modName);                                                           // The file name (module name)
153                 DBGFrame.addChar ('\0');                                                                        // Add the C-String null termination
154
155                 DBGPacket.addFrame (DBGFrame);
156
157                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
158                         return;                                                                                                 //  No
159                 }
160
161                 DBGPacket.sendPacket (os);
162         }
163
164         /**
165          * This method is called for adding or removing breakpoints.
166          *
167          * @param mod_name      The module name (file name).
168          * @param condition     Info about the condition when to break (not used at the moment).
169          * @param line          The breakpoints line.
170          * @param state         Info whether this breakpoint has to be dis- or enabled.
171          * @param istep         Always 0.
172          * @param hitcount      Always 0.
173          * @param skiphits      Always 0.
174          * @param bpno          The breakpoint ID.
175          * @param isunderhit    ???
176          * @return
177          */
178         private int setBreakpoint (String mod_name, String condition, int line, int state, int istemp, int hitcount, int skiphits, int bpno, int isunderhit) throws IOException {
179                 PHPDBGPacket    DBGPacket;
180                 PHPDBGFrame     DBGFrame1;
181                 PHPDBGFrame     DBGFrame2;
182                 PHPDBGFrame             DBGFrame3;
183                 int                     modNo;
184
185                 DBGPacket       = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);
186                 DBGFrame1       = new PHPDBGFrame (PHPDBGBase.FRAME_BPS);
187                 DBGFrame2       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
188                 DBGFrame3       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
189
190                 modNo           = getModByName (mod_name);                                              // Get the module ID by name
191
192                 if (modNo >= 0) {                                           // Did we find a module ID for the module name?
193                         DBGFrame1.addInt (modNo);                                                               // Add the module ID to frame 1
194                 } else {
195                         DBGFrame1.addInt (0);                                                                   // mod number (0 use file name)
196                 }
197
198                 DBGFrame1.addInt (line);                                                                        // line number
199
200                 if (modNo >= 0) {                                           // Did we find a module ID for the module name?
201                         DBGFrame1.addInt (0);                                                                   // use mod number
202                 } else {
203                         rawCounter++;
204                         DBGFrame1.addInt (rawCounter);                                                  // ID of FRAME_RAWDATA to send file name
205                 }
206
207                 if (modNo < 0) {                                            // Did we find a module ID for the module name?
208                         DBGFrame2.addInt (rawCounter);                                      // FRAME_RAWDATA ID
209                         DBGFrame2.addInt (mod_name.length() + 1);                   // length of rawdata (+ null char)
210                         DBGFrame2.addString (mod_name);                                     // file name
211                         DBGFrame2.addChar ('\0');                                                   // null char
212
213                         DBGPacket.addFrame (DBGFrame2);                         // First add file name data
214                 }
215
216                 DBGFrame1.addInt (state);                                       // state BPS_*
217                 DBGFrame1.addInt (istemp);                                      // istemp
218                 DBGFrame1.addInt (0);                                               // hit count; this is not supported as one might think
219                 DBGFrame1.addInt (hitcount);                                // skip hits is what we think is hit count.
220
221                 if (!condition.equals ("")) {                                                           // Do we have a condition for breakpoint
222                         rawCounter++;                                                                                   // Set to new ID
223                         DBGFrame1.addInt (rawCounter);                          // ID of condition
224
225                         DBGFrame3.addInt (rawCounter);                                      // FRAME_RAWDATA ID
226                         DBGFrame3.addInt (condition.length() + 1);                  // length of rawdata (+ null char)
227                         DBGFrame3.addString (condition);                                        // The break condition
228                         DBGFrame3.addChar ('\0');                                                   // null char
229
230                         DBGPacket.addFrame (DBGFrame3);                         // First add break condition
231                 }
232                 else {
233                         DBGFrame1.addInt (0);                                           // ID of condition is 0, because there is no condition
234                 }
235
236                 DBGFrame1.addInt (bpno);                                            // breakpoint number
237                 DBGFrame1.addInt (isunderhit);                                  // is under hit
238
239                 DBGPacket.addFrame (DBGFrame1);                                                         // Second add command data
240
241                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
242                         return 0;                                               //  No
243                 }
244
245                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
246
247                 clearLastBP ();
248
249                 waitResponse (1000);                                        // Wait for the DBG response (1 second)
250                 flushAllPackets ();                                         // Read and process the response from DBG
251
252                 return LastBPRead[8];                                                                           // Return what ???
253         }
254
255         /**
256          *
257          */
258         private void clearLastBP () {
259                 int i;
260
261                 for (i = 0; i < LastBPRead.length; i++) {
262                         LastBPRead[i] = 0;
263                 }
264         }
265
266         /**
267          *
268          */
269         private void copyToLastBP (int[] BPBody) {
270                 int i;
271
272                 for (i = 0; i < LastBPRead.length; i++) {
273                         LastBPRead[i] = BPBody[i];
274                 }
275         }
276
277         /**
278          *
279          */
280         public void continueExecution () throws IOException {
281                 PHPDBGPacket DBGPacket;
282
283                 BPUnderHit = 0;
284                 DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_CONTINUE);
285
286                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
287                         return;                                                 //  No
288                 }
289
290                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
291
292                 lastCommand = PHPDBGBase.DBGA_CONTINUE;                     // Store the info about the command we sent
293         }
294
295         /**
296          *
297          */
298         public void pauseExecution () throws IOException {
299                 PHPDBGPacket DBGPacket;
300
301                 DBGPacket = new PHPDBGPacket (PHPDBGBase.IntToChar4 (PHPDBGBase.DBGC_PAUSE));
302
303                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
304                          return;                                                //  No
305                 }
306
307                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
308         }
309
310         /**
311          *
312          */
313         private int getBPUnderHit () {
314                 int i;
315                 int BPUnder             = 0;
316                 int[] dbg_bpl_body      = new int[10];
317
318                 for (i = 0; i < DBGBPList.size (); i++) {                               // look for bp under hit
319                         dbg_bpl_body = (int[]) DBGBPList.get (i);
320
321                         if (dbg_bpl_body[9] == 1) {
322                                 BPUnder = dbg_bpl_body[8];
323                         }
324                 }
325
326                 return BPUnder;
327         }
328
329         public int getLastCmd()
330         {
331                 return lastCmd;
332         }
333
334         public int getSID()
335         {
336           return sid;
337         }
338
339         public void setLastCmd (int cmd)
340         {
341                 lastCmd = cmd;
342         }
343
344         /**
345          *
346          */
347         public void stepInto () throws IOException {
348                 PHPDBGPacket DBGPacket;
349
350                 BPUnderHit = 0;
351                 DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPINTO);
352
353                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
354                         return;                                                 //  No
355                 }
356
357                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
358
359                 lastCommand = PHPDBGBase.DBGA_STEPINTO;                                         // Store the info about the command we sent
360         }
361
362         /**
363          *
364          */
365         public void stepOver () throws IOException {
366                 PHPDBGPacket DBGPacket;
367
368                 BPUnderHit = 0;
369                 DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOVER);
370
371                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
372                         return;                                                 //  No
373                 }
374
375                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
376
377                 lastCommand = PHPDBGBase.DBGA_STEPOVER;                     // Store the info about the command we sent
378         }
379
380         /**
381          *
382          */
383         public void stepOut () throws IOException {
384                 PHPDBGPacket DBGPacket;
385
386                 BPUnderHit = 0;
387                 DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOUT);
388
389                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
390                         return;                                                 //  No
391                 }
392
393                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
394
395                 lastCommand = PHPDBGBase.DBGA_STEPOUT;                      // Store the info about the command we sent
396         }
397
398         /**
399          *
400          */
401         public void stopExecution () throws IOException {
402                 PHPDBGPacket DBGPacket;
403
404                 BPUnderHit = 0;
405                 DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STOP);
406
407                 if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
408                         return;                                                 //  No
409                 }
410
411                 DBGPacket.sendPacket (os);                                  // Send the request to DBG
412         }
413
414         /**
415          * This method is called by the proxy.
416          * It sends a request to DBG to get the current variables
417          * with their values. It waits for the response and processes
418          * the input from DBG.
419          *
420          * @param stack The stackframe for which we want the variables.
421          * @return      The array of variables
422          */
423         public synchronized Vector getVariables(PHPStackFrame stack) throws IOException, DebugException {
424                 PHPDBGPacket            DBGPacket;
425                 PHPDBGFrame             DBGFrame1;
426                 PHPDBGEvalString        evalStr;
427
428                 // get global variables (and assign them to 'main()' stackframe)
429                 Vector globalList = new Vector();
430                 globalList = getVariables(DBGStackList[DBGStackList.length - 1], PHPDBGBase.GLOBAL_SCOPE_ID);
431                 if (!globalList.isEmpty()) {
432                         // remove unexpected '$this=?' variable
433                         PHPVariable var = (PHPVariable) globalList.get(0);
434                         PHPValue val = (PHPValue) var.getValue();
435                         Vector workList = val.getChildVariables();
436                         for (int i = 0; i < workList.size(); i++) {
437                                 if (((PHPVariable) workList.get(i)).getName().equals("$this")) {
438                                         workList.remove(i);
439                                         break;
440                                 }
441                         }
442                         var.setName(GlobalVariablesTitle);
443                         var.setModifiable(false);
444                 }
445
446                 int scopeID = stack.getScopeID();
447                 if (!globalList.isEmpty()
448                                 && ((DBGStackList.length == 1)
449                                                 || (scopeID == PHPDBGBase.CURLOC_SCOPE_ID + 1))) {
450                         // 'main()' stackframe
451                         PHPVariable var = (PHPVariable) globalList.get(0);
452                         PHPValue val = (PHPValue) var.getValue();
453                         DBGVarList = val.getChildVariables();
454                         return DBGVarList;
455
456                 } else if (scopeID == PHPDBGBase.CURLOC_SCOPE_ID) {
457                         // current stackframe
458                         DBGVarList = getVariables(stack, PHPDBGBase.CURLOC_SCOPE_ID);
459
460                 } else {
461                         // back-trace stackframe
462                         DBGVarList = getVariables(stack, scopeID);
463                         // DBG 2.15.5 causes Application Error (on win32) in some cases
464                         //DBGVarList.clear();
465                 }
466
467                 if (DBGVarList.size() > 0) {                                                            // Did we get back variables?
468                         PHPVariable var = (PHPVariable) DBGVarList.get(0);              // Yes, then get the first PHPVariable
469                         PHPValue    val = (PHPValue) var.getValue();                    // Get the value
470
471                         if (var.getName().equals("")) {                                                 // Is the root node an empty node (usually it is)
472                                 DBGVarList = val.getChildVariables();                           // Then remove the empty node.
473                                                                                                                                         // With removing the empty root node, it wouldn't be necessary to
474                                                                                                                                         // set the name to an empty string. So the code below is just for
475                                                                                                                                         // info or in case the users want to have the empty root node.
476
477                                                                                                                                         // The eclipse variable view cannot handle Variables which have an empty name
478                                                                                                                                         // when it comes to variable tree restore operation. Without a name, no restore!
479                                 //var.setName (" ");                                                            // Give a name to the variable root node. Even if it is only a space :-)
480                         }                                                                                                               // TODO the best would be to remove the empty root node, but this would
481                                                                                                                                         // require a understanding and reworking of the PHPDBGEvalstring class.
482                 }
483
484                 if (!globalList.isEmpty()) {
485                         DBGVarList.add(globalList.get(0));
486                 }
487
488                 return DBGVarList;                                                                                      // Return the variables as list
489         }
490
491         /**
492          * 
493          * @throws IOException 
494          */
495         private Vector getVariables(PHPStackFrame stack, int scope_id) throws IOException {
496                 PHPDBGPacket DBGPacket = new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
497                 PHPDBGFrame DBGFrame1 = new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
498
499                 DBGFrame1.addInt(0);
500                 DBGFrame1.addInt(scope_id);
501
502                 DBGPacket.addFrame(DBGFrame1);
503                 evalRet = "";
504
505                 if (proxy.getSocket().isClosed()) {
506                         return new Vector();
507                 }
508                 DBGPacket.sendPacket(os);
509                 waitResponse(1000);
510                 flushAllPackets();
511
512                 PHPDBGEvalString evalStr = new PHPDBGEvalString(stack, evalRet);
513                 return evalStr.getVariables();
514         }
515
516         /**
517          *
518          * @param logString
519          */
520         public void log(String logString) throws IOException, DebugException  {
521                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
522                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_LOG);
523                 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
524
525                 rawCounter++;
526                 DBGFrame1.addInt(rawCounter);                           // ilog
527                 DBGFrame1.addInt(1);                                            // type
528                 DBGFrame1.addInt(0);                                            // mod_no
529                 DBGFrame1.addInt(0);                                            // line_no
530                 DBGFrame1.addInt(0);                                            // imod_name
531                 DBGFrame1.addInt(0);                                            // ext_info
532
533                 DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
534                 DBGFrame2.addInt(logString.length() + 1);       // length of rawdata (+ null char)
535                 DBGFrame2.addString(logString);                         // log string
536                 DBGFrame2.addChar('\0');                                        // null char
537
538                 // Add raw data first
539                 DBGPacket.addFrame(DBGFrame2);
540                 // Add command data
541                 DBGPacket.addFrame(DBGFrame1);
542
543                 if (proxy.getSocket ().isClosed ()) {                   // Do we have a socket for DBG communication?
544                         return;                                                                                         //  No, then leave here
545                 }
546
547                 DBGPacket.sendPacket(os);
548
549                 waitResponse(1000);
550                 flushAllPackets();
551         }
552
553         public synchronized PHPVariable[] evalBlock(PHPStackFrame stack, String evalString) throws IOException, DebugException {
554                 PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
555                 PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
556                 PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
557
558                 rawCounter++;
559                 DBGFrame1.addInt(rawCounter);                           // istr = raw data ID
560                 //DBGFrame1.addInt(1);                                          // scope_id = -1 means current location, 0 never used, +1 first depth
561                 int scope_id = stack.getScopeID();
562                 if (DBGStackList.length == 1 || scope_id == PHPDBGBase.CURLOC_SCOPE_ID + 1) {
563                         scope_id = PHPDBGBase.GLOBAL_SCOPE_ID;
564                 } //-
565                 DBGFrame1.addInt(scope_id);
566
567                 DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
568                 DBGFrame2.addInt(evalString.length() + 1);      // length of rawdata (+ null char)
569                 DBGFrame2.addString(evalString);                        // eval block
570                 DBGFrame2.addChar('\0');                                        // null char
571
572                 // Add raw data first
573                 DBGPacket.addFrame(DBGFrame2);
574                 // Add command data
575                 DBGPacket.addFrame(DBGFrame1);
576
577                 if (proxy.getSocket().isClosed()) {                     // Do we have a socket for DBG communication?
578                         return null;                                                    //  No, then leave here
579                 }
580                 DBGPacket.sendPacket(os);
581
582                 waitResponse(1000);
583                 flushAllPackets();
584
585                 PHPDBGEvalString evalStr=new PHPDBGEvalString(stack,evalRet);
586
587                 return evalStr.getVars();
588         }
589
590         /**
591          * Read and process everthing we got from DBG
592          */
593         public void flushAllPackets () throws IOException {
594                 while (readResponse() != 0);
595         }
596
597         /**
598          * Get the modules name by its number
599          *
600          * @param modNo The number (id) of the module
601          * @return      The name of the module
602          */
603         public String getModByNo (int modNo) {
604                 int             i;
605                 PHPDBGMod       dbg_mod;
606
607                 for (i = 0; i < DBGMods.size (); i++) {                         // For all the modules we have within the array
608                         dbg_mod = (PHPDBGMod) DBGMods.get (i);                      // Get the module
609
610                         if (dbg_mod.getNo () == modNo) {                            // Is the module from the array the module we want?
611                                 return dbg_mod.getName ();                              //  Yes, return the name of the module
612                         }
613                 }
614
615                 return "";                                                      // If nothing was found return emtpy string
616         }
617
618         /**
619          *
620          * @param  modName The name of the module for which we want the ID
621          * @return
622          * - The ID of the module
623          * - -1 if nothing was found
624          */
625         private int getModByName (String modName) {
626                 int             i;
627                 PHPDBGMod       dbg_mod;
628
629                 for (i = 0; i < DBGMods.size (); i++) {                         // For all the modules we have within the array
630                         dbg_mod = (PHPDBGMod) DBGMods.get (i);                      // Get the module
631
632                         if (dbg_mod.getName ().equalsIgnoreCase (modName)) {            // Is the module from the array the module we want?
633                                 return dbg_mod.getNo ();                                //  Yes, return the name of the module
634                         }
635                 }
636
637                 return -1;                                                      // If nothing was found return -1
638         }
639
640         /**
641          * Return the string for the given frame number
642          *
643          * @param framesInfo The buffer which is to read
644          * @param frameNo    The frame number
645          * @return
646          */
647         private String getRawFrameData (char[] framesInfo, int frameNo) {
648                 int   nextFrame = 0;                                                    // The current read position within the buffer
649                 int[] dbg_frame = new int[2];                                           // The two frame header numbers
650
651                 while (nextFrame < framesInfo.length) {                                 // As long we have something within the buffer
652                         dbg_frame[0] = PHPDBGBase.Char4ToInt (framesInfo, nextFrame);           // The frame type
653                         dbg_frame[1] = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4);       // The frame size
654
655                         nextFrame   += 8;                                                   // The current read position
656
657                         if (dbg_frame[1] == 0) {                                            // If frame size is 0
658                                 return "";                                                      //  return an emtpy string
659                         }
660
661                         switch (dbg_frame[0]) {                                                     // Switch for the frame type
662                                 case PHPDBGBase.FRAME_RAWDATA:                                                  // The only frame type we are interrested in
663                                         if (frameNo == PHPDBGBase.Char4ToInt (framesInfo, nextFrame)) {         // Is it correct  number of the frame
664                                                 int toRead;                                                     //
665
666                                                 toRead = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4);     // The size of the string
667
668                                                 if ((int) framesInfo[nextFrame + 8 + toRead - 1] == 0) {                                // Is there a string termination at the end?
669                                                         return String.copyValueOf (framesInfo, nextFrame + 8, toRead - 1);      // Then copy frame content to String without the \0 and return
670                                                 }
671
672                                                 return String.copyValueOf (framesInfo, nextFrame + 8, toRead);  // Copy frame content to String and return
673                                         }
674                                         break;
675                         }
676
677                         nextFrame += dbg_frame[1];                                                                      // Go for the next frame (add the length of the current one)
678                 }
679
680                 return "";                                                                                                                                              // We did not found any FRAM_RAWDATA, so return an emtpy strin
681         }
682
683         /**
684          * Reset the availability flag for all stackframes in the list.
685          *
686          * @param list          The list of old stackframes
687          */
688         private void resetAvailability (Vector list) {
689                 int             i;
690
691                 for (i = 0; i < list.size (); i++) {
692                         ((PHPStackFrame) list.get(i)).setAvailable (false);                                     //
693                 }
694         }
695
696         /**
697          * Check whether the new stackframe is in the list of old stackframes.
698          * Test for identical stackframe (identical means same description and same line number).
699          *
700          * @param stackFrameNew The stackframe to check whether he is already within the old stackframe list
701          * @param list          The list of old stackframes
702          * @return
703          *  - true if we have found the identical stackframe within the list
704          *  - false if we did not find the identical stackframe within the list
705          */
706         private boolean isStackFrameInList (PHPStackFrame stackFrameNew, Vector list) {
707                 int             i;
708                 PHPStackFrame   stackFrameOld;
709
710                 for (i = 0; i < list.size (); i++) {
711                         stackFrameOld = (PHPStackFrame) list.get (i);                                           //
712
713                         if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ()) &&
714                                 stackFrameNew.getLineNumber () == stackFrameOld.getLineNumber ()) {     // Did we find the sent stackframe within the list of old stackframes?
715                                 stackFrameOld.setAvailable (true);                                      // We found the new stackframe in the list of old stack frames
716                 stackFrameOld.setIndex (stackFrameNew.getIndex ());
717                 stackFrameOld.setScopeID(stackFrameNew.getScopeID());
718                                 return true;                                                            // The stackframe was found in the list
719                         }
720                 }
721
722                 return false;
723         }
724
725         /**
726          * Check whether the new stackframe is in the list of old stackframes.
727          * Test for exact stackframe (exact means same description and same line number).
728          *
729          * @param stackFrameNew The stackframe to check whether he is already within the old stackframe list
730          * @param list          The list of old stackframes
731          * @return
732          *  - true if we have exactly this stackframe within the list
733          *  - false if we did not find the exact stackframe within the list
734          */
735         private void markIdenticalStackFrames (Vector oldList, Vector newList) {
736                 int             i;
737                 PHPStackFrame   stackFrameNew;
738
739                 resetAvailability (oldList);                                                    // Reset the availability flag of the old stack frames
740                 resetAvailability (newList);                                                    // Reset the availability flag of the old stack frames
741
742                 for (i = 0; i < newList.size (); i++) {                                                                                 // For all stackList entries
743                         stackFrameNew = (PHPStackFrame) newList.get (i);
744
745                         if (isStackFrameInList (stackFrameNew, oldList)) {                          // Is this stackframe in the list
746                                 stackFrameNew.setAvailable (true);                                                                              //
747                                                                                                                                                                                 //
748                                 break;
749                         }
750                 }
751         }
752
753         /**
754          *
755          * The stackList contains the currently read stackframes which were sent
756          * from DBG. The DBG interface holds a list of the active stack frames.
757          * This method replicates the 'static' stackframe list with the DBG stackframe list
758          * Replication is done in the following way:
759          * <ul>
760          * <li> It looks for new stackframes within the DBG stackframe list and
761          *      adds them to the 'static' list.
762          * <li> It looks for stackframes within the 'static' list, and removes them
763          *              from the 'static' list in case they do not appear within the DBG list.
764          * <li> It looks for stackframes which are already existent and replicates the
765          *              line number and the index number.
766          * <li> At the end, the 'static' stackframe list has to be sorted by the stackframes
767          *              index numbers.
768          * </ul>
769          *
770          * Removes the unused stackframes from the list, or adds stackframes which
771          * are not yet in the list.
772          *
773          *
774          * @param stackList
775          */
776         private void updateStackFrameList (Vector stackList) {
777                 int                     i;
778                 int             n;
779                 PHPStackFrame   stackFrameNew;
780                 PHPStackFrame   stackFrameOld;
781                 PHPStackFrame[] newStackList;
782
783                 markIdenticalStackFrames (stackListOld, stackList);                     // Check whether the newly send stack frames can be found in the list
784                                                                                                                                                                 // of old stack frames
785
786                 for (i = 0; i < stackList.size (); i++) {                                                               // For all stackList entries
787                         stackFrameNew = (PHPStackFrame) stackList.get(i);
788
789                         for (n = 0; n < stackListOld.size (); n++) {                                    // For all StackFrames in the StackFrame list
790                                 stackFrameOld = (PHPStackFrame) stackListOld.get (n);                   //
791
792                                 if (stackFrameOld.isAvailable ()) {                             // If this stack frame was already found in the new list skip it
793                                         continue;
794                                 }
795
796                                 if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ())) {// Did we find the sent stackframe within the list of old stackframes?
797                                         stackFrameOld.setLineNumber (stackFrameNew.getLineNumber ());
798                                         stackFrameOld.setIndex (stackFrameNew.getIndex ());
799                                         stackFrameOld.setScopeID(stackFrameNew.getScopeID());
800
801                                         stackFrameOld.setAvailable (true);                                                      // And mark this stack frame as available
802                                         stackFrameNew.setAvailable (true);                                                      // And mark this stack frame as available
803
804                                         break;                                                                  //  Yes, then break;
805                                 }
806                         }
807
808                         if (!stackFrameNew.isAvailable ()) {                                // Did not find the new stackframe within the list?
809                                  stackFrameNew.setAvailable (true);                                                             // Mark the stack frame as available and
810                                  stackListOld.add (stackFrameNew);                              //  then add the new stackframe
811                         }
812                 }
813
814                 // And now for removing unused stackframes from list
815
816                 for (n = 0; n < stackListOld.size (); n++) {                                            // For all StackFrames in the StackFrame list
817                         stackFrameOld = (PHPStackFrame) stackListOld.get (n);                           //
818
819                         i = 0;
820                         if (!stackFrameOld.isAvailable ()) {
821                                 i = stackList.size ();
822                         }
823
824                         if (i == stackList.size ()) {                                           // Did not find the old stackframe within the list of new ones
825                                  stackListOld.remove (n);                                       //  then remove the old stackframe from list
826                                  n -= 1;                                                        // Adjust the stack list index
827                         }
828                 }
829
830                 Collections.sort (stackListOld);                                                                                // Sort the 'static' stackframe list by the stackframe index numbers.
831                                                                                                                                                                 //
832                 newStackList = new PHPStackFrame[stackListOld.size ()];
833                 newStackList = (PHPStackFrame[]) stackListOld.toArray (newStackList);
834                 DBGStackList = newStackList;
835         }
836
837     /**
838      * Read the response from DBG and process the frame
839      *
840          * @return
841          * - The received command
842          * - or 0 if something was wrong
843      */
844         public int readResponse () throws IOException {
845         int     bytesToRead            = 0;                         // The number of byte to read for the current DBG block
846         int     nextFrame              = 0;                         // The current read position within entirePack
847         int     i                      = 0;
848         int     cmdReceived            = 0;
849         int     stackIndex             = 0;
850         boolean errorStack             = false;
851         char[]  dbg_header_struct_read = new char[16];              // The buffer for the first 16 bytes of a block
852         int[]   dbg_header_struct      = new int[4];                // The first four numbers (long) of a block
853         int[]   dbg_bpl_tmp            = new int[10];
854         int[]   dbg_frame              = new int[2];
855         int[]   dbg_eval_tmp           = new int[3];
856         int[]   dbg_src_tree_tmp       = new int[4];                //
857         int[]   dbg_error_tmp          = new int[2];
858         Vector  rawList                = new Vector();
859         Vector  stackList              = new Vector();              // Intermediate stacklist which is build up in FRAME_STACK frame
860
861         rawList.clear ();
862         stackList.clear ();
863
864                 // Read from input
865         while (readInput (dbg_header_struct_read, 16) != 0) {                               // Read 16 byte from input stream
866                         dbg_header_struct[0] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 0);               // Debug sync header
867             dbg_header_struct[1] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 4);           // Command
868             dbg_header_struct[2] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 8);       //
869             dbg_header_struct[3] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 12);      // Bytes within this block
870
871             if (dbg_header_struct[0] != 0x5953) {                                           // Check DBG sync bytes
872                 return 0;                                                                   // Wrong header
873             }
874
875             cmdReceived = dbg_header_struct[1];                                             // Get the command
876             setLastCmd (cmdReceived);                                                                                                           // Store the info about the current command
877             bytesToRead = dbg_header_struct[3];                                                                                         // Get the number of bytes to read for this block
878
879                         //System.out.println("Response Received: " + cmdReceived);
880                         char[] entirePack = new char[bytesToRead];                                      // Store the block data into buffer 'entirePack'
881
882             if (bytesToRead > 0) {                                                          // If there is something within the frame
883                 if (readInput (entirePack, bytesToRead) < bytesToRead) {                    // Read the frame into the buffer
884                     return 0;                                                               // We did not read enough bytes, error
885                 }
886                         }
887                         
888                         nextFrame = 0;                                                                  // Start with the first frame
889
890                         while (nextFrame < bytesToRead) {                                               // As long as we have something within this block
891                                 dbg_frame[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame);                           // The name of the frame
892                                 dbg_frame[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);               // The size of the frame
893                                 nextFrame   += 8;                                                           // The next read position
894
895                                 if (dbg_frame[1] == 0) {                                                    // Something within the frame?
896                                         return 0;                                                               //  Nothing to read, error
897                                 }
898
899                                 switch (dbg_frame[0]) {
900                                         case PHPDBGBase.FRAME_STACK:
901                                                 int[] dbg_stack_new = new int[4];                                       //
902
903                                                 dbg_stack_new[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);   // Source line number
904                                                 dbg_stack_new[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);   // Module number
905                                                 dbg_stack_new[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);   // Scope id
906                                                 dbg_stack_new[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12);  // ID of description string
907
908                                                 if ((dbg_stack_new[1] != 0) && !errorStack) {
909                                                         PHPStackFrame newStack;
910
911                                                         stackIndex++;
912                                                         newStack = new PHPStackFrame (null,                                 // The thread
913                                                                                       getModByNo (dbg_stack_new[1]),        // The name of the module (file)
914                                                                                       dbg_stack_new[0],                     // The source line number
915                                                                                                                   stackIndex,
916                                                                                                                   getRawFrameData (entirePack,          // Get the string from this packet
917                                                                                                                                    dbg_stack_new[3]),   // The frame ID for which we want the string
918                                                                                                                   dbg_stack_new[1],                                     // The module number
919                                                                                                                   dbg_stack_new[2]);
920                                                         stackList.add (newStack);
921                                                 }
922
923                                                 errorStack = false;
924                                                 break;
925
926                                         case PHPDBGBase.FRAME_SOURCE:                                                   // Nothing to be done here
927                                                 break;                                                                      // TODO: what's with that frame? Something interesting
928
929                                         case PHPDBGBase.FRAME_SRC_TREE:                                                 //
930                                                 dbg_src_tree_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);        // The parent module number
931                                                 dbg_src_tree_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);        // The parent line number (not used)
932                                                 dbg_src_tree_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);        // The module number
933                                                 dbg_src_tree_tmp[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12);       // The filename number
934
935                                                 if (getModByNo (dbg_src_tree_tmp[2]).equals ("")) {
936                                                         String fileName;
937
938                                                         fileName = new String (getRawFrameData (entirePack, dbg_src_tree_tmp[3]));      // Get the filename
939
940                                                         if (dbg_src_tree_tmp[2] != 0) {                                             // If there is a module number
941                                                                 PHPDBGMod modNew;
942
943                                                                 modNew = new PHPDBGMod (dbg_src_tree_tmp[2], fileName);                 // Create a module object
944
945                                                                 DBGMods.add (modNew);                                                   // And store it to array
946                                                         }
947                                                 }
948                                                 break;
949
950                                         case PHPDBGBase.FRAME_RAWDATA:                                                      // Nothing to be done here
951                                                 break;                                                                          //  FRAME_RAWDATA are processed within getRawFrameData
952
953                                         case PHPDBGBase.FRAME_ERROR:                                                                                                            // An error frame
954                                                 errorStack       = true;                                                                                                                // Yes, we have an error stack
955                                                 dbg_error_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);                   // Error type
956                                                 dbg_error_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);                   // Error message ID
957
958                                                 String error = "\n";                                                            //
959
960                                                 switch (dbg_error_tmp[0]) {                                                                                                             // Switch on error type
961                                                         case PHPDBGBase.E_ERROR:                        error += "[Error]";                     break;
962                                                         case PHPDBGBase.E_WARNING:                      error += "[Warning]";                   break;
963                                                         case PHPDBGBase.E_PARSE:                        error += "[Parse Error]";               break;
964                                                         case PHPDBGBase.E_NOTICE:                       error += "[Notice]";                    break;
965                                                         case PHPDBGBase.E_CORE_ERROR:           error += "[Core Error]";                break;
966                                                         case PHPDBGBase.E_CORE_WARNING:         error += "[Core Warning]";              break;
967                                                         case PHPDBGBase.E_COMPILE_ERROR:        error += "[Compile Error]";             break;
968                                                         case PHPDBGBase.E_COMPILE_WARNING:      error += "[Compile Warning]";   break;
969                                                         case PHPDBGBase.E_USER_ERROR:           error += "[User Error]";                break;
970                                                         case PHPDBGBase.E_USER_WARNING:         error += "[User Warning]";              break;
971                                                         case PHPDBGBase.E_USER_NOTICE:          error += "[User Notice]";               break;
972                                                         default:                                                        error += "[Unexpected Error]";  break;
973                                                 }
974
975                                                 error += ": ";
976                                                 error += new String (getRawFrameData (entirePack, dbg_error_tmp[1]));                   // Add the error string for this error message ID
977                                                 error += "\n";                                                                  // Append a CR
978
979                                                 PHPDebugCorePlugin.log (new DebugException (new Status (IStatus.WARNING,
980                                                                                                         PHPDebugCorePlugin.PLUGIN_ID,
981                                                                                                                                                                 IStatus.OK,
982                                                                                                                                                                 error, null)));
983
984                                                 // To print errors on the console, I must execute a code in the
985                                                 // php context, that write the stderr... I didn't found a better way
986                                                 // TODO: Find a better way????
987
988 //                                              String codeExec= "";
989 //                                              codeExec= "fwrite(fopen('php://stderr', 'w'),\\\"" + error + "\\\");";
990 //                                              try {
991 //                                                      evalBlock("eval(\"" + codeExec + "\");");
992 //                                              } catch (DebugException e) {
993 //                                                      PHPDebugCorePlugin.log(e);
994 //                                              }
995 //
996                                                 if (!stopOnError) {                                                             // Is always false (Did not see where this is set to true!?)
997                                                         if (lastCommand.equals (PHPDBGBase.DBGA_CONTINUE)) {                        // If last command for PHP was a 'continue',
998                                                                 continueExecution ();                                                   //  send continue again
999                                                         } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPINTO)) {                 // If last command for PHP was a 'step into',
1000                                                                 stepInto ();                                                            //  send 'step into' again
1001                                                         } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPOUT)) {                  // If last command for PHP was a 'step out',
1002                                                                 stepOut ();                                                             //  send 'step out' again
1003                                                         } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPOVER)) {                 // If last command for PHP was a 'step over',
1004                                                                 stepOver ();                                                            //  send 'step over' again
1005                                                         }
1006                                                 }
1007                                                 break;
1008
1009                                         case PHPDBGBase.FRAME_EVAL:
1010                                                 String evalString;
1011
1012                                                 evalString      = new String ("");
1013                                                 dbg_eval_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);                    // istr
1014                                                 dbg_eval_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);                    // iresult
1015                                                 dbg_eval_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);                    // ierror
1016
1017                                                 evalRet                 = getRawFrameData (entirePack, dbg_eval_tmp[1]);                //
1018                                                 evalString              = getRawFrameData (entirePack, dbg_eval_tmp[0]);                //
1019                                                 break;
1020
1021                                         case PHPDBGBase.FRAME_BPS:                                                          //
1022                                                 break;                                                                          //
1023
1024                                         case PHPDBGBase.FRAME_BPL:
1025                                                 int[] dbg_bpl_new;
1026
1027                                                 dbg_bpl_new        = new int[10];
1028                                                 dbg_bpl_new[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);
1029                                                 dbg_bpl_new[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);
1030                                                 dbg_bpl_new[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);
1031                                                 dbg_bpl_new[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12);
1032                                                 dbg_bpl_new[4] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 16);
1033                                                 dbg_bpl_new[5] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 20);
1034                                                 dbg_bpl_new[6] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 24);
1035                                                 dbg_bpl_new[7] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 28);
1036                                                 dbg_bpl_new[8] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 32);
1037                                                 dbg_bpl_new[9] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 36);
1038
1039                                                 // look if breakpoint already exists in vector
1040                                                 for (i = 0; i < DBGBPList.size (); i++) {
1041                                                         dbg_bpl_tmp = (int[]) DBGBPList.get (i);
1042
1043                                                         if (dbg_bpl_tmp[8] == dbg_bpl_new[8]) {
1044                                                                 DBGBPList.remove (i);
1045
1046                                                                 break;
1047                                                         }
1048                                                 }
1049
1050                                                 // add breakpoint to vector
1051                                                 DBGBPList.add (dbg_bpl_new);
1052                                                 copyToLastBP (dbg_bpl_new);
1053
1054                                                 // mod no returned?
1055                                                 if (getModByNo (dbg_bpl_new[0]).equals ("")) {
1056                                                         String fileName;
1057
1058                                                         fileName = new String (getRawFrameData (entirePack, dbg_bpl_new[2]));
1059
1060                                                         if (dbg_bpl_new[0] != 0) {
1061                                                                 PHPDBGMod modNew;
1062
1063                                                                 modNew = new PHPDBGMod (dbg_bpl_new[0], fileName);
1064
1065                                                                 DBGMods.add (modNew);
1066                                                         }
1067                                                 }
1068                                                 break;
1069
1070                                         case PHPDBGBase.FRAME_VER:
1071                                                 break;
1072
1073                                         case PHPDBGBase.FRAME_SID:
1074                                                 sid = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);
1075                                                 break;
1076
1077                                         case PHPDBGBase.FRAME_SRCLINESINFO:
1078                                                 break;
1079
1080                                         case PHPDBGBase.FRAME_SRCCTXINFO:
1081                                                 break;
1082
1083                                         case PHPDBGBase.FRAME_LOG:
1084                                                 break;
1085
1086                                         case PHPDBGBase.FRAME_PROF:
1087                                                 break;
1088
1089                                         case PHPDBGBase.FRAME_PROF_C:
1090                                                 break;
1091
1092                                         case PHPDBGBase.FRAME_SET_OPT:
1093                                                 break;
1094                                 }
1095
1096                                 nextFrame += dbg_frame[1];                                                      // go to next frame
1097                         }
1098
1099                         // Now process command
1100                         switch(cmdReceived) {
1101                                 case PHPDBGBase.DBGC_REPLY:
1102                                         break;
1103
1104                                 case PHPDBGBase.DBGC_STARTUP:
1105                                         break;
1106
1107                                 case PHPDBGBase.DBGC_END:
1108                                         sessionEnded = true;
1109                                         this.proxy.setTerminated();
1110                                         break;
1111
1112                                 case PHPDBGBase.DBGC_BREAKPOINT:
1113                                         BPUnderHit   = getBPUnderHit ();
1114                                         updateStackFrameList (stackList);
1115                                         break;
1116
1117                                 case PHPDBGBase.DBGC_STEPINTO_DONE:
1118                                 case PHPDBGBase.DBGC_STEPOVER_DONE:
1119                                 case PHPDBGBase.DBGC_STEPOUT_DONE:
1120                                 case PHPDBGBase.DBGC_EMBEDDED_BREAK:
1121                                 case PHPDBGBase.DBGC_PAUSE:
1122                                         BPUnderHit   = 1;
1123                                         updateStackFrameList (stackList);
1124                                         break;
1125
1126                                 case PHPDBGBase.DBGC_ERROR:
1127                                         stackList.clear ();
1128                                         updateStackFrameList (stackList);
1129                                         break;
1130
1131                                 case PHPDBGBase.DBGC_LOG:
1132                                         break;
1133
1134                                 case PHPDBGBase.DBGC_SID:
1135                                         break;
1136                         }
1137                 }
1138
1139                 return cmdReceived;                                         // Return the command we received with this block
1140         }
1141
1142     /**
1143      *
1144      */
1145
1146         public PHPStackFrame[] getStackList() {
1147                 return DBGStackList;
1148         }
1149
1150         /**
1151          * Reads from input buffer (response sent from DBG) the given number of chars
1152          * into frame buffer.
1153          *
1154          * @param buffer  The frame buffer where to store the read data from DBG.
1155          * @param bytes   The number of bytes (chars) which are to read from input stream.
1156          * @return        The number of bytes actually read.
1157          */
1158         private int readInput (char[] buffer, int bytes) throws IOException {
1159                 int bytesRead = 0;                                                                                      // Reset the bytes read counter
1160
1161                 for (int i = 0; i < bytes; i++) {                           // For the number of bytes we should read
1162                         if (in.ready ()) {                                                                              // If input stream is ready for reading
1163                                 buffer[i] = (char) (in.read () & 0x00FF);           // Read a char and store only the least significant 8-bits
1164                                 bytesRead++;                                        // Increment the bytes read counter
1165                         }
1166                         else {                                                  // Input stream is not ready
1167                                 break;                                              // Break the loop
1168                         }
1169                 }
1170
1171                 return bytesRead;                                                                                       // Return the number of bytes actually read
1172         }
1173
1174         /**
1175          * PHPProxy could stop the waiting for a response with this method.
1176          *
1177          */
1178         public void setShouldStop () {
1179                 this.shouldStop = true;
1180         }
1181
1182         /**
1183          * @param milliseconds The maximum time in milliseconds we wait for something
1184          *                     to be send from DBG.
1185          * @return             - true if something was received from DBG
1186          *                                         - false if nothing was send from DBG within the given time
1187          *
1188          */
1189         public boolean waitResponse (long milliseconds) throws IOException {
1190                 long timeout;
1191
1192                 timeout = System.currentTimeMillis () + milliseconds;           // Calculate the system time till we wait.
1193
1194                 while (System.currentTimeMillis () < timeout) {             // Is waiting time running out?
1195                         if (in.ready () || shouldStop) {                        //  No, so did we get something or should we stop now
1196                                 break;                                              //   Yes, break the waiting
1197                         }
1198                 }
1199
1200                 return in.ready ();                                         // true if we got something from DBG
1201         }
1202 }