Dead
[official-gcc.git] / gomp-20050608-branch / libjava / gnu / gcj / util / Debug.java
blobd19ab694d803142b330656e75a323d5678d94c54
1 /* Copyright (C) 2004 Free Software Foundation
3 This file is part of libgcj.
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
7 details. */
9 /* Utility methods that allow an object to be converted to a textual
10 representation on an OutputStream. The intention here is that this
11 class be used for debugging, so we provide information about all
12 fields, public or otherwise. */
14 package gnu.gcj.util;
16 import java.lang.reflect.*;
17 import java.io.*;
18 import java.util.*;
20 class Debug
22 private final PrintStream p;
23 private final int maxdepth;
24 private final int maxArrayLength;
25 private final boolean printStaticFields;
26 private int depth;
28 Debug(PrintStream writer, int maxdepth, int maxArrayLength, boolean printStaticFields)
30 p = writer;
31 this.maxdepth = maxdepth;
32 this.maxArrayLength = maxArrayLength;
33 this.printStaticFields = printStaticFields;
36 Debug(PrintStream writer)
38 this(writer, 0, 10, false);
41 Debug(int maxdepth, boolean printStaticFields)
43 this(new PrintStream
44 (new FileOutputStream(FileDescriptor.err), true),
45 maxdepth,
46 maxdepth > 0 ? 1000 : 10, printStaticFields);
49 Debug(int maxdepth)
51 this(maxdepth, false);
54 Debug()
56 this(0, false);
59 private final void indent()
61 for (int i = 0; i < depth; i++)
62 p.print(" ");
65 private final java.util.IdentityHashMap h =
66 new java.util.IdentityHashMap();
68 private static native Field[] getDeclaredFields(Class c);
69 private static native Object getField(Object o, Field f);
70 private static native long getAddr(Object o);
72 // Return an array containing all the fields of a class and its
73 // superclasses.
74 private Field[] internalGetFields(Class c)
76 HashSet set = new HashSet();
77 set.addAll(Arrays.asList(getDeclaredFields(c)));
78 Class[] interfaces = c.getInterfaces();
79 for (int i = 0; i < interfaces.length; i++)
80 set.addAll(Arrays.asList(internalGetFields(interfaces[i])));
81 Class superClass = c.getSuperclass();
82 if (superClass != null)
83 set.addAll(Arrays.asList(internalGetFields(superClass)));
84 return (Field[])set.toArray(new Field[set.size()]);
87 // FIXME: We could just use getClass() here, but this is a
88 // workaround for a C++ bug that is causing getClass() to be
89 // miscompiled.
90 static private Class getItsClass(Object O)
92 return O.getClass();
95 // Print a reasonably readable textual representation of an object
96 // on our OutputStream. Objects are only printed once, no matter
97 // how many references point to them.
98 private void print(Object O)
100 int savedDepth = depth;
101 h.put(O, O);
104 Class C = getItsClass(O);
105 p.print(C.getName() + "@");
106 p.println(Long.toHexString(getAddr(O)));
108 if (C.isArray())
110 indent(); p.println("{");
111 depth++;
112 indent();
113 C = C.getComponentType();
115 int len = Array.getLength(O);
116 for (int i = 0; i < len; i++)
118 Object thing = Array.get(O, i);
119 print0(thing, C);
120 p.print(", ");
121 if (i > maxArrayLength)
123 p.print("...");
124 break;
127 depth--;
128 p.println();
129 indent(); p.print("}");
130 return;
133 indent(); p.println("{");
134 depth++;
135 if (C == java.lang.Class.class)
137 indent();
138 p.println ("class = " + O.toString() + ",");
140 else if (C == java.lang.reflect.Field.class)
142 indent();
143 p.println ("<field> = \"" + O.toString() + "\",");
145 else if (C == java.lang.String.class)
147 indent();
148 p.println ("<string> = \"" + O.toString() + "\",");
150 Field[] f = internalGetFields(C);
151 for (int i = 0; i < f.length; i++)
153 Class type = f[i].getType();
154 boolean isStatic = (f[i].getModifiers() & Modifier.STATIC) != 0;
156 if (isStatic && ! printStaticFields)
157 continue;
159 indent();
160 if (isStatic)
161 p.print("static ");
162 p.print(type.getName() +" " +f[i].getName() + " = ");
163 Object thing = getField(O, f[i]);
164 print0(thing, type);
165 p.println(",");
167 depth--;
168 indent(); p.print("}");
170 catch (Throwable t)
172 p.print("error: 0x" + Long.toHexString(getAddr(O)) + ";");
173 depth = savedDepth;
177 private void print0(Object thing, Class C)
181 if (thing == null)
183 p.print("null");
184 return;
186 else if (C == gnu.gcj.RawData.class ||
187 C == gnu.gcj.RawDataManaged.class)
190 else if (C.isPrimitive())
192 if (getItsClass(thing) == Character.class)
193 p.print("'" + thing + "'");
194 else
195 p.print(thing);
196 return;
198 else if (getItsClass(thing) == String.class)
200 p.print("\"" + thing + "\"");
201 return;
203 else if (depth < maxdepth && h.get(thing) == null)
205 depth++;
206 print(thing);
207 depth--;
208 return;
211 catch (Throwable t)
215 // The default action: just print the address.
216 p.print("0x"+ Long.toHexString(getAddr(thing)));
219 // Print the textual representation of an object on System.err.
220 public void write(Object O)
222 depth = 0;
223 print(O);
224 p.flush();