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 / model / PHPDBGEvalString.java
index d74a154..2f4953c 100644 (file)
@@ -31,9 +31,9 @@ public class PHPDBGEvalString {
        /**
         *
         */
-       public PHPDBGEvalString (PHPStackFrame stack, String dataStr) {
-               fStackFrame     = stack;
-               workStr         = dataStr;
+       public PHPDBGEvalString(PHPStackFrame stack, String dataStr) {
+               fStackFrame = stack;
+               workStr = dataStr;
        }
 
        /**
@@ -107,7 +107,6 @@ public class PHPDBGEvalString {
         */
        int ExtractInt (char chstart, char chend, int startIdx) throws DebugException {
                String  subs;
-               int     rslt;
 
                subs = ExtractSubStr (chstart, chend, startIdx);
 
@@ -396,34 +395,67 @@ public class PHPDBGEvalString {
         * @param var_list
         * @param startIdx
         */
-       boolean ParseEvalRef (String name, PHPVariable parent, Vector list, Vector var_list, boolean isSoftRef, int startIdx) throws DebugException {
-               int                     v;
+       private boolean ParseEvalRef (String name, PHPVariable parent, Vector list,
+                                                                 Vector var_list, boolean isSoftRef, int startIdx
+                                                                 ) throws DebugException {
+               int         v;            // The ref ID (index into vector list)
                PHPVariable item;
                PHPVariable var_item;
 
-               v    = ExtractInt(':', ';',startIdx);
-               item = new PHPVariable (fStackFrame, name, parent, "", (isSoftRef) ? (PHPValue.PEVT_SOFTREF) : (PHPValue.PEVT_REF), null);
-               v--;                                                                                                            // ref ID is 1-based, EvalList is 0-based
+               v    = ExtractInt (':', ';', startIdx);
+               item = new PHPVariable (fStackFrame, name, parent, "",
+                                               isSoftRef ? PHPValue.PEVT_SOFTREF : PHPValue.PEVT_REF, null);
+               v--;                                                        // ref ID is 1-based, EvalList is 0-based
 
                if ((var_list == null) ||
-                   (v < 0) ||
-                       (v >= var_list.size ())) {
-//                     item.ref = item; // self-resolving
-//
+                   (v < 0) || (v >= var_list.size ())) {                   // Check ref ID (index) bounds
+                       //item.ref = item; // self-resolving
                        return true;
-               } else {
-                       var_item = (PHPVariable) var_list.get (v);
+               }
+               else {
+// This is the original code without the problems of stackframe overflow
+                       var_item = (PHPVariable) var_list.get (v);              // Get the variable from the list of all variables
 
                        try {
                                item.setValue (var_item.getValue ());
                                item.setReferenceType (var_item.getReferenceType ());
-                               ((PHPValue) item.getValue ()).setParent (item);
+//                             ((PHPValue) item.getValue ()).setParent (item);     // Set the new variable as parent for all child variables
                        } catch (DebugException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace ();
                        }
 
                        list.add (item);
+
+/*************
+ * this code produces a stackframe overflow if the reference contains loop references
+                       var_item = (PHPVariable) var_list.get (v);              // Get the referenced variable from the list of variables
+
+                       PHPValue new_val = (PHPValue) var_item.getValue ();
+
+                       if (isSoftRef) {
+                               // expand reduced structure to full tree
+                               // each value must have its appropriate parent
+                               try {
+                                       new_val = copyItems (new_val, 0);               // Copy the child variables to the new referenced variable
+                               } catch (CloneNotSupportedException e) {
+                                       // never occurs
+                               }
+                       }
+
+                       try {
+                               //item.setValue(var_item.getValue());
+                               //item.setReferenceType(var_item.getReferenceType());
+                               //((PHPValue) item.getValue()).setParent(item);
+                               item.setValue (new_val);
+                               item.setReferenceType (var_item.getReferenceType ());
+                               new_val.setParent (item);
+                       } catch (DebugException e) {
+                               // never occurs
+                       }
+
+                       list.add (item);
+ */
                }
 
                return true;
@@ -433,26 +465,27 @@ public class PHPDBGEvalString {
         *
         * @return The array of PHPVariables
         */
-       public PHPVariable[] getVars () {
-               Vector list     = new Vector ();
-               Vector var_list = new Vector ();
+       public PHPVariable[] getVars() {
+               Vector list = new Vector();
+               Vector var_list = new Vector();
 
-               parse ("", null, list, var_list, false, 0);
+               parse("", null, list, var_list, false, 0);
 
-               return (PHPVariable[]) list.toArray (new PHPVariable[list.size ()]);    // Convert the list to an array and return the array
+               return (PHPVariable[]) list.toArray(new PHPVariable[list.size()]); // Convert the list to an array and return the array
        }
 
        /**
         *
         * @return The PHPVariables as list
         */
-       public Vector getVariables () {
-               Vector list     = new Vector ();
-               Vector var_list = new Vector ();
+       public Vector getVariables() {
+               Vector list = new Vector();
+               Vector var_list = new Vector();
 
-               parse ("", null, list, var_list, false, 0);
+               parse("", null, list, var_list, false, 0);
 
-               return list;                                                                                                                    // return the PHPVariable list
+               //debugDump(list, "");
+               return list; // return the PHPVariable list
        }
 
        /**
@@ -489,10 +522,10 @@ public class PHPDBGEvalString {
                                case 'z': ParseEvalResource (name, parent, list, var_list, startIdx);                            break;
                                case 'R': ParseEvalRef          (name, parent, list, var_list, false, startIdx);                 break;
                                case 'r': ParseEvalRef          (name, parent, list, var_list, true, startIdx);                  break;
+                               case '?': ParseEvalUnknown(name, parent, list, var_list, startIdx);                                      break;
                        }
                } catch (DebugException e) {
-                       // TODO Auto-generated catch block
-                       e.printStackTrace();
+                       PHPDebugCorePlugin.log(e);
                }
 
 /*             if (!ret_val) { // try to recover
@@ -514,4 +547,81 @@ public class PHPDBGEvalString {
 */
                return  ret_val;                                                                                        // Always false
        }
+
+       /*
+        *
+        */
+       private void ParseEvalUnknown(String name, PHPVariable parent, Vector list,
+                       Vector var_list, int startIdx) throws DebugException {
+
+               if ((startIdx >= workStr.length()) || (workStr.charAt(startIdx) != ';')) {
+                       Status status = new Status(Status.ERROR, PHPDebugCorePlugin
+                                       .getUniqueIdentifier(), Status.OK, "unexpected response",
+                                       null);
+                       throw new DebugException(status);
+               }
+
+               workStr = workStr.substring(1);
+               PHPVariable item = new PHPVariable(fStackFrame, name, parent, "?",
+                               PHPValue.PEVT_UNKNOWN, null);
+               list.add(item);
+               if (var_list != null) {
+                       var_list.add(item);
+               }
+       }
+
+       /*
+        * Copy referenced items tree
+        *
+        * @note We have to take care of recursion. We have to stop on recursion else
+        * we get a stack overflow!
+        *
+        * @param val The variable for which we build the tree of all childs
+        */
+       private PHPValue copyItems (PHPValue val, int nDepth) throws CloneNotSupportedException {
+               PHPValue newVal   = (PHPValue) val.clone();
+               Vector   vars     = newVal.getChildVariables();
+               Vector   newVars  = new Vector();
+
+               nDepth++;
+
+               if (nDepth >= 10) {                                         // A very quick and very dirty way to avoid stack overflow
+                       return newVal;
+               }
+
+               for (int i = 0; i < vars.size(); i++) {
+                       PHPVariable newVar = (PHPVariable) ((PHPVariable) vars.get(i)).clone();
+
+                       try {
+                               newVar.setValue (copyItems ((PHPValue) newVar.getValue(), nDepth));
+                       } catch (DebugException e) {
+                               // never occurs
+                       }
+
+                       newVars.add (newVar);
+               }
+
+               val.setVariables (newVars);
+
+               return newVal;
+       }
+
+//     private void debugDump(Vector list, String indent) {
+//             for (int i = 0; i < list.size(); i++) {
+//                     PHPVariable var = (PHPVariable) list.get(i);
+//                     System.out.print(indent + var.getName());
+//                     PHPValue val = (PHPValue) var.getValue();
+//                     try {
+//                             if (val.hasVariables() && !var.getName().equals("['GLOBALS']")) {
+//                                     System.out.println();
+//                                     debugDump(val.getChildVariables(), indent + "    ");
+//                             } else {
+//                                     PHPVariable parent = var.getParent();
+//                                     System.out.println(val.getValueString() + " \t>>" + (parent == null ? "null" : parent.getLongName()));
+//                             }
+//                     } catch (DebugException e) {
+//                             e.printStackTrace();
+//                     }
+//             }
+//     }
 }