| // Throwable.java - Superclass for all exceptions. |
| |
| /* Copyright (C) 1998, 1999 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. */ |
| |
| package java.lang; |
| import java.io.PrintStream; |
| import java.io.PrintWriter; |
| import java.io.Serializable; |
| import java.io.OutputStreamWriter; |
| import java.io.OutputStream; |
| import java.io.FilterOutputStream; |
| import java.io.IOException; |
| |
| /** |
| * @author Tom Tromey <tromey@cygnus.com> |
| * @date October 30, 1998 |
| */ |
| |
| /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 |
| * "The Java Language Specification", ISBN 0-201-63451-1 |
| * Status: Sufficient for compiled code, but methods applicable to |
| * bytecode not implemented. JDK 1.1. |
| */ |
| |
| /* A CPlusPlusDemangler sits on top of a PrintWriter. All input is |
| * passed through the "c++filt" program (part of GNU binutils) which |
| * demangles internal symbols to their C++ source form. |
| * |
| * Closing a CPlusPlusDemangler doesn't close the underlying |
| * PrintWriter; it does, however close underlying process and flush |
| * all its buffers, so it's possible to guarantee that after a |
| * CPlusPlusDemangler has been closed no more will ever be written to |
| * the underlying PrintWriter. |
| * |
| * FIXME: This implictly converts data from the input stream, which is |
| * a stream of characters, to a stream of bytes. We need a way of |
| * handling Unicode characters in demangled identifiers. */ |
| |
| class CPlusPlusDemangler extends OutputStream |
| { |
| java.io.OutputStream procOut; |
| java.io.InputStream procIn; |
| java.lang.Process proc; |
| PrintWriter p; |
| |
| /* The number of bytes written to the underlying PrintWriter. This |
| provides a crude but fairly portable way to determine whether or |
| not the attempt to exec c++filt worked. */ |
| public int written = 0; |
| |
| CPlusPlusDemangler (PrintWriter writer) throws IOException |
| { |
| p = writer; |
| proc = Runtime.getRuntime ().exec ("c++filt -s java"); |
| procOut = proc.getOutputStream (); |
| procIn = proc.getInputStream (); |
| } |
| |
| public void write (int b) throws IOException |
| { |
| procOut.write (b); |
| while (procIn.available () != 0) |
| { |
| int c = procIn.read (); |
| if (c == -1) |
| break; |
| else |
| { |
| p.write (c); |
| written++; |
| } |
| } |
| } |
| |
| public void close () throws IOException |
| { |
| procOut.close (); |
| int c; |
| while ((c = procIn.read ()) != -1) |
| { |
| p.write (c); |
| written++; |
| } |
| p.flush (); |
| try |
| { |
| proc.waitFor (); |
| } |
| catch (InterruptedException _) |
| { |
| } |
| } |
| } |
| |
| public class Throwable implements Serializable |
| { |
| public native Throwable fillInStackTrace (); |
| |
| public String getLocalizedMessage () |
| { |
| return getMessage (); |
| } |
| |
| public String getMessage () |
| { |
| return detailMessage; |
| } |
| |
| public void printStackTrace () |
| { |
| printStackTrace (System.err); |
| } |
| |
| public void printStackTrace (PrintStream ps) |
| { |
| PrintWriter writer = new PrintWriter (ps); |
| printStackTrace (writer); |
| } |
| |
| public void printStackTrace (PrintWriter wr) |
| { |
| try |
| { |
| CPlusPlusDemangler cPlusPlusFilter = new CPlusPlusDemangler (wr); |
| PrintWriter writer = new PrintWriter (cPlusPlusFilter); |
| printRawStackTrace (writer); |
| writer.close (); |
| if (cPlusPlusFilter.written == 0) // The demangler has failed... |
| printRawStackTrace (wr); |
| } |
| catch (Exception e1) |
| { |
| printRawStackTrace (wr); |
| } |
| } |
| |
| public Throwable () |
| { |
| detailMessage = null; |
| fillInStackTrace (); |
| } |
| |
| public Throwable (String message) |
| { |
| detailMessage = message; |
| fillInStackTrace (); |
| } |
| |
| public String toString () |
| { |
| return ((detailMessage == null) |
| ? getClass().getName() |
| : getClass().getName() + ": " + getMessage ()); |
| } |
| |
| private native final void printRawStackTrace (PrintWriter wr); |
| |
| // Name of this field comes from serialization spec. |
| private String detailMessage; |
| |
| // Setting this flag to false prevents fillInStackTrace() from running. |
| static boolean trace_enabled = true; |
| private transient byte stackTrace[]; |
| private static final long serialVersionUID = -3042686055658047285L; |
| } |