OSDN Git Service

Add missing file from gcj-abi-2-dev-branch merge.
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Nov 2004 11:50:45 +0000 (11:50 +0000)
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Nov 2004 11:50:45 +0000 (11:50 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91284 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/gnu/gcj/util/Debug.java [new file with mode: 0644]

diff --git a/libjava/gnu/gcj/util/Debug.java b/libjava/gnu/gcj/util/Debug.java
new file mode 100644 (file)
index 0000000..d19ab69
--- /dev/null
@@ -0,0 +1,226 @@
+/*  Copyright (C) 2004  Free Software Foundation
+
+This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+/* Utility methods that allow an object to be converted to a textual
+   representation on an OutputStream.  The intention here is that this
+   class be used for debugging, so we provide information about all
+   fields, public or otherwise. */
+
+package gnu.gcj.util;
+
+import java.lang.reflect.*;
+import java.io.*;
+import java.util.*;
+
+class Debug 
+{
+  private final PrintStream p;
+  private final int maxdepth;
+  private final int maxArrayLength;
+  private final boolean printStaticFields;
+  private int depth; 
+
+  Debug(PrintStream writer, int maxdepth, int maxArrayLength, boolean printStaticFields)
+  {
+    p = writer;
+    this.maxdepth = maxdepth;
+    this.maxArrayLength = maxArrayLength;
+    this.printStaticFields = printStaticFields;
+  }
+
+  Debug(PrintStream writer)
+  {
+    this(writer, 0, 10, false);
+  }
+
+  Debug(int maxdepth, boolean printStaticFields)
+  {
+    this(new PrintStream
+        (new FileOutputStream(FileDescriptor.err), true), 
+        maxdepth, 
+        maxdepth > 0 ? 1000 : 10, printStaticFields);
+  }
+
+  Debug(int maxdepth)
+  {
+    this(maxdepth, false);
+  }
+
+  Debug()
+  {
+    this(0, false);
+  }
+  
+  private final void indent()
+  {
+    for (int i = 0; i < depth; i++)
+      p.print("  ");
+  }
+
+  private final java.util.IdentityHashMap h = 
+  new java.util.IdentityHashMap();
+
+  private static native Field[] getDeclaredFields(Class c);
+  private static native Object getField(Object o, Field f);
+  private static native long getAddr(Object o);
+
+  // Return an array containing all the fields of a class and its
+  // superclasses.
+  private Field[] internalGetFields(Class c)
+  {
+    HashSet set = new HashSet();
+    set.addAll(Arrays.asList(getDeclaredFields(c)));
+    Class[] interfaces = c.getInterfaces();
+    for (int i = 0; i < interfaces.length; i++)
+      set.addAll(Arrays.asList(internalGetFields(interfaces[i])));
+    Class superClass = c.getSuperclass();
+    if (superClass != null)
+      set.addAll(Arrays.asList(internalGetFields(superClass)));
+    return (Field[])set.toArray(new Field[set.size()]);
+  }
+
+  // FIXME: We could just use getClass() here, but this is a
+  // workaround for a C++ bug that is causing getClass() to be
+  // miscompiled.
+  static private Class getItsClass(Object O)
+  {
+    return O.getClass();
+  }
+
+  // Print a reasonably readable textual representation of an object
+  // on our OutputStream.  Objects are only printed once, no matter
+  // how many references point to them.
+  private void print(Object O)
+  {
+    int savedDepth = depth;
+    h.put(O, O);
+    try
+      {
+       Class C = getItsClass(O);
+       p.print(C.getName() + "@");
+       p.println(Long.toHexString(getAddr(O)));
+
+       if (C.isArray())
+         {
+           indent(); p.println("{");
+           depth++;
+           indent();
+           C = C.getComponentType();
+
+           int len = Array.getLength(O);
+           for (int i = 0; i < len; i++)
+             {
+               Object thing = Array.get(O, i);
+               print0(thing, C);
+               p.print(", ");
+               if (i > maxArrayLength)
+                 {
+                   p.print("...");
+                   break;
+                 }
+             }
+           depth--;
+           p.println();
+           indent(); p.print("}");
+           return;
+         }
+
+       indent(); p.println("{");
+       depth++;
+       if (C == java.lang.Class.class)
+         {
+           indent();
+           p.println ("class = " + O.toString() + ",");
+         }
+       else if (C == java.lang.reflect.Field.class)
+         {
+           indent();
+           p.println ("<field> = \"" + O.toString() + "\",");
+         }
+       else if (C == java.lang.String.class)
+         {
+           indent();
+           p.println ("<string> = \"" + O.toString() + "\",");
+         }
+       Field[] f = internalGetFields(C);
+       for (int i = 0; i < f.length; i++)
+         {
+           Class type = f[i].getType();
+           boolean isStatic = (f[i].getModifiers() & Modifier.STATIC) != 0;
+           if (isStatic && ! printStaticFields)
+             continue;
+
+           indent();
+           if (isStatic)
+             p.print("static ");
+           p.print(type.getName() +" " +f[i].getName() + " = ");
+           Object thing = getField(O, f[i]);
+           print0(thing, type);
+           p.println(",");
+         }
+       depth--;
+       indent(); p.print("}");
+      }
+    catch (Throwable t)
+      {
+       p.print("error: 0x" + Long.toHexString(getAddr(O)) + ";");
+       depth = savedDepth;
+      }
+  }
+
+  private void print0(Object thing, Class C)
+  {
+    try
+      {
+       if (thing == null)
+         {
+           p.print("null");
+           return;
+         }
+       else if (C == gnu.gcj.RawData.class || 
+                C == gnu.gcj.RawDataManaged.class)
+         {
+         }
+       else if (C.isPrimitive())
+         {
+           if (getItsClass(thing) == Character.class)                          
+             p.print("'" + thing + "'");
+           else
+             p.print(thing);
+           return;
+         }
+       else if (getItsClass(thing) == String.class)
+         {                       
+           p.print("\"" + thing + "\"");
+           return;
+         }
+       else if (depth < maxdepth && h.get(thing) == null)
+         {
+           depth++;
+           print(thing);
+           depth--;
+           return;
+         }
+      }
+    catch (Throwable t)
+      {
+      }
+    
+    // The default action: just print the address.
+    p.print("0x"+ Long.toHexString(getAddr(thing)));    
+  }
+
+  // Print the textual representation of an object on System.err.
+  public void write(Object O)
+  {
+    depth = 0;
+    print(O);
+    p.flush();
+  }
+}