1439ed9d65ff17ca7c00f5b15707bc2de64ae7a0
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / model / PHPDBGEvalString.java
1 package net.sourceforge.phpdt.internal.debug.core.model;
2
3 /*
4  * Created on 17.04.2004
5  *
6  * To change the template for this generated file go to
7  * Window - Preferences - Java - Code Generation - Code and Comments
8  */
9 /**
10  * @author Chris Admin
11  *
12  * To change the template for this generated type comment go to
13  * Window - Preferences - Java - Code Generation - Code and Comments
14  */
15
16 import java.util.Vector;
17
18 import net.sourceforge.phpdt.internal.debug.core.PHPDebugCorePlugin;
19
20 import org.eclipse.core.runtime.Status;
21 import org.eclipse.debug.core.DebugException;
22
23 /**
24  *
25  */
26 public class PHPDBGEvalString {
27
28         String                            workStr;
29         private PHPStackFrame fStackFrame;
30
31         /**
32          *
33          */
34         public PHPDBGEvalString(PHPStackFrame stack, String dataStr) {
35                 fStackFrame = stack;
36                 workStr = dataStr;
37         }
38
39         /**
40          *
41          * @param chstart
42          * @param chend
43          * @param startIdx
44          * @return
45          */
46         String ExtractSubStr (char chstart, char chend, int startIdx) throws DebugException {
47                 int     idx;
48                 int     i;
49                 String  rslt;
50                 Status  status;
51
52                 idx = startIdx;
53
54                 if (idx >= (workStr.length () - 1) ||
55                     workStr.charAt (idx) != chstart) {
56                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "worng startIdx!", null);
57
58                         throw new DebugException (status);
59                 }
60
61                 i = ++idx;
62                 i = workStr.indexOf(chend, i);
63
64                 if (i == -1) {
65                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "endchar not found!", null);
66
67                         throw new DebugException (status);
68                 }
69                 rslt    = workStr.substring (idx, i);
70                 workStr = workStr.substring (i + 1);
71
72                 return rslt;
73         }
74
75         /**
76          * @param slen
77          * @param startIdx
78          * @return
79          */
80         String ExtractQuotedSubStr (int slen, int startIdx) throws DebugException {
81                 int     idx;
82                 String  rslt;
83                 Status  status;
84
85                 idx = startIdx;
86
87                 if ((idx + slen + 1) >= workStr.length () ||
88                                 workStr.charAt (idx)!= '"' ||
89                                 workStr.charAt (idx + slen + 1) != '"') {
90                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "no quoted substring found!", null);
91
92                         throw new DebugException (status);
93                 }
94
95                 rslt    = workStr.substring (idx + 1, idx + 1 + slen);
96                 workStr = workStr.substring (idx + 2 + slen);
97
98                 return rslt;
99         }
100
101         /**
102          *
103          * @param chstart
104          * @param chend
105          * @apram startIdx
106          * @return
107          */
108         int ExtractInt (char chstart, char chend, int startIdx) throws DebugException {
109                 String  subs;
110
111                 subs = ExtractSubStr (chstart, chend, startIdx);
112
113                 return (Integer.parseInt (subs));
114         }
115
116         /**
117          * @param name
118          * @param parent
119          * @param list       The list of PHPVariables
120          * @param var_list
121          * @param classname
122          * @param atype      The type of the variable (Either PEVT_ARRAY or PEVT_OBJECT)
123          * @return
124          */
125         PHPVariable ParseEvalArray (String name, PHPVariable parent, Vector list, Vector var_list, String classname, int atype)  throws DebugException {
126                 long            arritems;                                                                               // The number of items (or fields or entries) for the array (or short, array size)
127                 PHPVariable item;
128                 Vector          subitems = null;
129                 Status      status;
130
131                 arritems = ExtractInt (':', ':', 0);                                            // Get the number of items/fields for the array
132                                                                                                                                         // E.g. :12: means there are 12 entries in array
133
134                 if ((workStr.length () > 0) &&                              // Is there still something to parse?
135                     (workStr.charAt (0) != '{')) {                          // And the next character is not a '{', then output an error
136                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "no array startcharacter!", null);
137
138                         throw new DebugException (status);
139                 }
140
141                 workStr = workStr.substring (1);                            // Remove the '{'
142                 item    = new PHPVariable (fStackFrame, name, parent, classname, atype, null);  // Create a new (empty) PHPVariable
143
144                 list.add (item);                                            // Add the newly created PHPVariable to list
145
146                 if (var_list != null) {                                     //
147                         var_list.add (item);                                    // Add the PHPVariable also to the var_list
148                 }
149
150                 if (arritems > 0) {                                         // If the array is not empty
151                         subitems = new Vector ();                               // Create a new child variable list for the array
152                 } else if (workStr.charAt (0) != '}') {                     // If the array is empty the next character has to be '}'
153                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "no array endcharacter!", null);
154
155                         throw new DebugException (status);
156                 }
157
158                 while ((workStr.length () > 0) &&                           // Is there still something to parse?
159                        (workStr.charAt (0) != '}')) {                       // And the next character is not '}'
160                         Vector tmplst = new Vector ();                          // Create a temporary list
161
162                         parse ("", null, tmplst, null, false, 0);               // And parse the string for the array's name.
163
164                         if (tmplst.size () != 1) {                              // Parsing should return exactly on entry (which is the name)
165                                 status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "no name found!", null);
166
167                                 throw new DebugException (status);
168                         }
169                                                                                                                                         // Go for the array values
170                         parse (((PHPVariable) tmplst.elementAt (0)).getValue ().getValueString (), item, subitems, var_list, true, 0);
171                 }
172
173                 ((PHPValue) item.getValue ()).addVariable (subitems);       // Append the list of all child variables to this PHPVariables PHPValue
174                 workStr = workStr.substring (1);                            // Remove the '}'
175
176                 return item;                                                // And return the PHPVariable we just build
177         }
178
179         /**
180          *
181          * @param name
182          * @param parent
183          * @param list
184          * @param var_list
185          * @param startIdx
186          */
187         void ParseEvalNULL (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
188                 int             idx;
189                 PHPVariable item;
190                 Status          status;
191
192                 idx = startIdx;
193
194                 if ((idx >= workStr.length ()) ||
195                     (workStr.charAt (idx) != ';')) {
196                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "NULL not found!", null);
197
198                         throw new DebugException(status);
199                 }
200
201                 workStr = workStr.substring (1);
202                 item    = new PHPVariable (fStackFrame, name, parent, "NULL", PHPValue.PEVT_UNKNOWN, null);
203
204                 list.add (item);
205
206                 if (var_list != null) {
207                         var_list.add (item);
208                 }
209         }
210
211         /**
212          *
213          * @param name
214          * @param parent
215          * @param list
216          * @param var_list
217          * @param startIdx
218          */
219         boolean ParseEvalInt (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
220                 String          subs;
221                 PHPVariable item;
222
223                 subs = ExtractSubStr (':', ';', startIdx);
224                 item = new PHPVariable (fStackFrame, name, parent, subs, PHPValue.PEVT_LONG, null);
225
226                 list.add (item);
227
228                 if (var_list != null) {
229                         var_list.add (item);
230                 }
231
232                 return true;
233         }
234
235         /**
236          *
237          * @param name
238          * @param parent
239          * @param list
240          * @param var_list
241          * @param startIdx
242          */
243         boolean ParseEvalDouble (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
244                 String          subs;
245                 PHPVariable item;
246
247                 subs = ExtractSubStr (':', ';', startIdx);
248                 item = new PHPVariable (fStackFrame, name, parent, subs, PHPValue.PEVT_DOUBLE, null);
249
250                 list.add (item);
251
252                 if (var_list != null) {
253                         var_list.add (item);
254                 }
255
256                 return true;
257         }
258
259         /**
260          *
261          * @param name
262          * @param parent
263          * @param list
264          * @param var_list
265          * @param MakePhpStr
266          * @param startIdx
267          */
268         boolean ParseEvalString (String name, PHPVariable parent, Vector list, Vector var_list, boolean MakePhpStr, int startIdx)
269                                         throws DebugException {
270                 int                     slen;
271                 Status          status;
272                 String          subs;
273                 PHPVariable item;
274
275                 slen = ExtractInt( ':', ':',startIdx);
276
277                 if ((workStr.length () <= slen) ||
278                     (workStr.charAt (0) != '"')) {
279                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (), Status.OK, "no String startcharecter!", null);
280
281                         throw new DebugException (status);
282                 }
283
284                 workStr = workStr.substring (1);
285                 subs    = workStr.substring (0, slen);
286
287                 // replace \\ with \
288                 subs = subs.replaceAll ("\\\\\\\\","\\\\");
289
290                 if (workStr.charAt (slen) != '"') {
291                         status = new Status (Status.ERROR, PHPDebugCorePlugin.getUniqueIdentifier (),Status.OK, "no String endcharecter!", null);
292                         throw new DebugException (status);
293                 }
294
295                 workStr = workStr.substring (slen + 2);
296
297 /*              if (MakePhpStr) {
298                         ConvertToPhpString(subs, &subs);
299                 }
300 */
301                 item = new PHPVariable (fStackFrame, name, parent, subs, PHPValue.PEVT_STRING, null);
302
303                 list.add (item);
304
305                 if (var_list != null) {
306                         var_list.add (item);
307                 }
308
309                 return true;
310         }
311
312         /**
313          *
314          * @param name
315          * @param parent
316          * @param list
317          * @param var_list
318          * @param startIdx
319          */
320         boolean ParseEvalBool (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
321                 long            v;
322                 PHPVariable item;
323
324                 v    = ExtractInt (':', ';', startIdx);
325                 item = new PHPVariable (fStackFrame, name, parent, (v==0) ? ("FALSE") : ("TRUE"), PHPValue.PEVT_BOOLEAN, null);
326
327                 list.add (item);
328
329                 if (var_list != null) {
330                         var_list.add (item);
331                 }
332
333                 return true;
334         }
335
336         /**
337          *
338          * @param name
339          * @param parent
340          * @param list
341          * @param var_list
342          * @param startIdx
343          */
344         boolean ParseEvalObject (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
345                 int             slen;
346                 String  classname;
347
348                 slen      = ExtractInt (':', ':', startIdx);
349                 classname = ExtractQuotedSubStr (slen, startIdx);
350
351                 if ((int) classname.length () != slen) {
352                         return false;
353                 }
354
355                 ParseEvalArray (name,parent, list, var_list, classname,PHPValue.PEVT_OBJECT);
356
357                 return true;
358         }
359
360         /**
361          *
362          * @param name
363          * @param parent
364          * @param list
365          * @param var_list
366          * @param startIdx
367          */
368         boolean ParseEvalResource (String name, PHPVariable parent, Vector list, Vector var_list, int startIdx) throws DebugException {
369                 PHPVariable item;
370                 int                     slen;
371                 String          restype;
372                 String          val;
373
374                 slen    = ExtractInt (':', ':', startIdx);
375                 restype = ExtractQuotedSubStr (slen, startIdx);
376                 val     = ExtractSubStr (':', ';', startIdx);
377
378                 item = new PHPVariable (fStackFrame, name, parent, restype + ":" + val, PHPValue.PEVT_RESOURCE, null);
379
380                 list.add (item);
381
382                 if (var_list != null) {
383                         var_list.add (item);
384                 }
385
386                 return true;
387         }
388
389
390         /**
391          *
392          * @param name
393          * @param parent
394          * @param list
395          * @param var_list
396          * @param startIdx
397          */
398         private boolean ParseEvalRef(String name, PHPVariable parent, Vector list,
399                         Vector var_list, boolean isSoftRef, int startIdx)
400                         throws DebugException {
401                 int v;
402                 PHPVariable item;
403                 PHPVariable var_item;
404
405                 v = ExtractInt(':', ';', startIdx);
406                 item = new PHPVariable(fStackFrame, name, parent, "",
407                                 isSoftRef ? PHPValue.PEVT_SOFTREF : PHPValue.PEVT_REF, null);
408                 v--; // ref ID is 1-based, EvalList is 0-based
409
410                 if ((var_list == null) || (v < 0) || (v >= var_list.size())) {
411                         //item.ref = item; // self-resolving
412                         return true;
413                 } else {
414                         var_item = (PHPVariable) var_list.get(v);
415
416                         PHPValue new_val = (PHPValue) var_item.getValue();
417                         if (isSoftRef) {
418                                 // expand reduced structure to full tree
419                                 // each value must have its appropriate parent
420                                 try {
421                                         new_val = copyItems(new_val);
422                                 } catch (CloneNotSupportedException e) {
423                                         // never occurs
424                                 }
425                         }
426
427                         try {
428                                 //item.setValue(var_item.getValue());
429                                 //item.setReferenceType(var_item.getReferenceType());
430                                 //((PHPValue) item.getValue()).setParent(item);
431                                 item.setValue(new_val);
432                                 item.setReferenceType(var_item.getReferenceType());
433                                 new_val.setParent(item);
434                         } catch (DebugException e) {
435                                 // never occurs
436                         }
437
438                         list.add(item);
439                 }
440
441                 return true;
442         }
443
444         /**
445          *
446          * @return The array of PHPVariables
447          */
448         public PHPVariable[] getVars() {
449                 Vector list = new Vector();
450                 Vector var_list = new Vector();
451
452                 parse("", null, list, var_list, false, 0);
453
454                 return (PHPVariable[]) list.toArray(new PHPVariable[list.size()]); // Convert the list to an array and return the array
455         }
456
457         /**
458          *
459          * @return The PHPVariables as list
460          */
461         public Vector getVariables() {
462                 Vector list = new Vector();
463                 Vector var_list = new Vector();
464
465                 parse("", null, list, var_list, false, 0);
466
467                 //debugDump(list, "");
468                 return list; // return the PHPVariable list
469         }
470
471         /**
472          *
473          *
474          *
475          * @param name        The name of the PHPVariable
476          * @param parent      The PHPVariable to which this parsing belongs
477          * @param list
478          * @param var_list
479          * @param MakePhpStr
480          * @param startIdx
481          */
482         boolean parse (String name, PHPVariable parent, Vector list, Vector var_list, boolean MakePhpStr, int startIdx) {
483                 boolean ret_val = false;
484                 char    ch;
485
486                 if (startIdx >= workStr.length ()) {                        // Is there something to parse
487                         return false;                                           // No, then leave here
488                 }
489
490                 ch              = workStr.charAt (startIdx);                        // The first character denotes the type of variable
491                 workStr = workStr.substring (1);                            // Remove the 'variable type' character
492
493                 try {
494                         switch (ch) {                                           // Switch according the 'variable type'
495                                 case 'N': ParseEvalNULL         (name, parent, list, var_list, startIdx);                                break;
496                                 case 'i': ParseEvalInt          (name, parent, list, var_list, startIdx);                                break;
497                                 case 'd': ParseEvalDouble       (name, parent, list, var_list, startIdx);                                break;
498                                 case 's': ParseEvalString       (name, parent, list, var_list, MakePhpStr, startIdx);    break;
499                                 case 'a': ParseEvalArray        (name, parent, list, var_list, "", PHPValue.PEVT_ARRAY); break;
500                                 case 'O': ParseEvalObject       (name, parent, list, var_list, startIdx);                                break;
501                                 case 'b': ParseEvalBool         (name, parent, list, var_list, startIdx);                                break;
502                                 case 'z': ParseEvalResource (name, parent, list, var_list, startIdx);                            break;
503                                 case 'R': ParseEvalRef          (name, parent, list, var_list, false, startIdx);                 break;
504                                 case 'r': ParseEvalRef          (name, parent, list, var_list, true, startIdx);                  break;
505                                 case '?': ParseEvalUnknown(name, parent, list, var_list, startIdx);                                      break;
506                         }
507                 } catch (DebugException e) {
508                         PHPDebugCorePlugin.log(e);
509                 }
510
511 /*              if (!ret_val) { // try to recover
512                         unsigned int i=*startIdx;
513                         while (i<str.length() && str[i]!='{' && str[i]!=';') i++;
514                         if (i<str.length() && str[i] == '{') {
515                                 unsigned int cnt=1;
516                                 i++;
517                                 while (i<str.length() && cnt!=0) {
518                                         if (str[i] == '{')
519                                                 cnt++;
520                                         else if (str[i] == '}')
521                                                 cnt--;
522                                         i++;
523                                 }
524                         }
525                         *startIdx = i;
526                 }
527 */
528                 return  ret_val;                                                                                        // Always false
529         }
530
531         /*
532          *
533          */
534         private void ParseEvalUnknown(String name, PHPVariable parent, Vector list,
535                         Vector var_list, int startIdx) throws DebugException {
536
537                 if ((startIdx >= workStr.length()) || (workStr.charAt(startIdx) != ';')) {
538                         Status status = new Status(Status.ERROR, PHPDebugCorePlugin
539                                         .getUniqueIdentifier(), Status.OK, "unexpected response",
540                                         null);
541                         throw new DebugException(status);
542                 }
543
544                 workStr = workStr.substring(1);
545                 PHPVariable item = new PHPVariable(fStackFrame, name, parent, "?",
546                                 PHPValue.PEVT_UNKNOWN, null);
547                 list.add(item);
548                 if (var_list != null) {
549                         var_list.add(item);
550                 }
551         }
552
553         /*
554          * Copy referenced items tree
555          */
556         private PHPValue copyItems(PHPValue val) throws CloneNotSupportedException {
557                 PHPValue newVal = (PHPValue) val.clone();
558                 Vector vars = newVal.getChildVariables();
559                 Vector newVars = new Vector();
560                 for (int i = 0; i < vars.size(); i++) {
561                         PHPVariable newVar = (PHPVariable) ((PHPVariable) vars.get(i)).clone();
562                         try {
563                                 newVar.setValue(copyItems((PHPValue) newVar.getValue()));
564                         } catch (DebugException e) {
565                                 // never occurs
566                         }
567                         newVars.add(newVar);
568                 }
569                 val.setVariables(newVars);
570                 return newVal;
571         }
572
573 //      private void debugDump(Vector list, String indent) {
574 //              for (int i = 0; i < list.size(); i++) {
575 //                      PHPVariable var = (PHPVariable) list.get(i);
576 //                      System.out.print(indent + var.getName());
577 //                      PHPValue val = (PHPValue) var.getValue();
578 //                      try {
579 //                              if (val.hasVariables() && !var.getName().equals("['GLOBALS']")) {
580 //                                      System.out.println();
581 //                                      debugDump(val.getChildVariables(), indent + "    ");
582 //                              } else {
583 //                                      PHPVariable parent = var.getParent();
584 //                                      System.out.println(val.getValueString() + " \t>>" + (parent == null ? "null" : parent.getLongName()));
585 //                              }
586 //                      } catch (DebugException e) {
587 //                              e.printStackTrace();
588 //                      }
589 //              }
590 //      }
591 }