4aa21399c5ab445b259e7bad21aacb1824ba0803
[platform/upstream/gcc.git] / libjava / java / lang / Throwable.java
1 // Throwable.java - Superclass for all exceptions.
2
3 /* Copyright (C) 1998, 1999  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 package java.lang;
12 import java.io.PrintStream;
13 import java.io.PrintWriter;
14 import java.io.Serializable;
15 import java.io.OutputStreamWriter;
16 import java.io.OutputStream;
17 import java.io.FilterOutputStream;
18 import java.io.IOException;
19
20 /**
21  * @author Tom Tromey <tromey@cygnus.com>
22  * @date October 30, 1998 
23  */
24
25 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
26  * "The Java Language Specification", ISBN 0-201-63451-1
27  * Status: Sufficient for compiled code, but methods applicable to
28  * bytecode not implemented.  JDK 1.1.
29  */
30
31 /* A CPlusPlusDemangler sits on top of a PrintWriter.  All input is
32  * passed through the "c++filt" program (part of GNU binutils) which
33  * demangles internal symbols to their C++ source form.
34  *
35  * Closing a CPlusPlusDemangler doesn't close the underlying
36  * PrintWriter; it does, however close underlying process and flush
37  * all its buffers, so it's possible to guarantee that after a
38  * CPlusPlusDemangler has been closed no more will ever be written to
39  * the underlying PrintWriter.
40  *
41  * FIXME: This implictly converts data from the input stream, which is
42  * a stream of characters, to a stream of bytes.  We need a way of
43  * handling Unicode characters in demangled identifiers.  */
44
45 class CPlusPlusDemangler extends OutputStream
46 {
47   java.io.OutputStream procOut;
48   java.io.InputStream procIn;
49   java.lang.Process proc;
50   PrintWriter p;
51
52   /* The number of bytes written to the underlying PrintWriter.  This
53      provides a crude but fairly portable way to determine whether or
54      not the attempt to exec c++filt worked. */  
55   public int written = 0;
56
57   CPlusPlusDemangler (PrintWriter writer) throws IOException
58   {
59     p = writer;
60     proc = Runtime.getRuntime ().exec ("c++filt");
61     procOut = proc.getOutputStream ();
62     procIn = proc.getInputStream ();
63   }
64
65   public void write (int b) throws IOException
66   {
67     procOut.write (b);
68     while (procIn.available () != 0)
69       {
70         int c = procIn.read ();
71         if (c == -1)
72           break;
73         else
74           {
75             p.write (c);
76             written++;
77           }
78       }
79   }
80   
81   public void close () throws IOException
82   {
83     procOut.close ();
84     int c;
85     while ((c = procIn.read ()) != -1)
86       {
87         p.write (c);
88         written++;
89       }
90     p.flush ();
91     try
92       {
93         proc.waitFor ();
94       }
95     catch (InterruptedException _)
96       {
97       }
98   }    
99 }
100
101 public class Throwable implements Serializable
102 {
103   public native Throwable fillInStackTrace ();
104
105   public String getLocalizedMessage ()
106   {
107     return getMessage ();
108   }
109
110   public String getMessage ()
111   {
112     return detailMessage;
113   }
114
115   public void printStackTrace ()
116   {
117     printStackTrace (System.err);
118   }
119
120   public void printStackTrace (PrintStream ps)
121   {
122     PrintWriter writer = new PrintWriter (ps);
123     printStackTrace (writer);
124   }
125
126   public void printStackTrace (PrintWriter wr)
127   {
128     try
129       {
130         CPlusPlusDemangler cPlusPlusFilter = new CPlusPlusDemangler (wr);
131         PrintWriter writer = new PrintWriter (cPlusPlusFilter);
132         printRawStackTrace (writer);    
133         writer.close ();
134         if (cPlusPlusFilter.written == 0) // The demangler has failed...
135           printRawStackTrace (wr);
136       }
137     catch (Exception e1)
138       {
139         printRawStackTrace (wr);
140       }
141   }
142
143   public Throwable ()
144   {
145     detailMessage = null;
146     fillInStackTrace ();
147   }
148
149   public Throwable (String message)
150   {
151     detailMessage = message;
152     fillInStackTrace ();
153   }
154
155   public String toString ()
156   {
157     return ((detailMessage == null)
158             ? getClass().getName()
159             : getClass().getName() + ": " + getMessage ());
160   }
161
162   private native final void printRawStackTrace (PrintWriter wr);
163   
164   // Name of this field comes from serialization spec.
165   private String detailMessage;
166
167   // Setting this flag to false prevents fillInStackTrace() from running.
168   static boolean trace_enabled = true;
169   private transient byte stackTrace[];
170   private static final long serialVersionUID = -3042686055658047285L;
171 }