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