001: package jsint;
002:
003: /**
004: * A jsint.BacktraceException is used to capture and report on
005: * uncaught Exceptions thrown in a Jscheme program.
006: * @author Ken R. Anderson, Copyright 2000, kanderso@bbn.com, <a href="license.txt">license</a>
007: * subsequently modified by Jscheme project members
008: * licensed under zlib licence (see license.txt)
009: */
010:
011: public class BacktraceException extends RuntimeException {
012: public static boolean printJavaTrace = false;
013: private Throwable exception;
014: private Object[] args;
015: private LexicalEnvironment lexenv;
016:
017: public BacktraceException(Throwable e, Object[] args) {
018: this (e, args, jsint.LexicalEnvironment.NULLENV);
019: }
020:
021: public BacktraceException(Throwable e, Object[] args,
022: LexicalEnvironment lexenv) {
023: // KRA 25DEC01: super suggestion by Adrian Boyko <adrianboyko@hotmail.com>
024: super (e.getMessage());
025: this .exception = e;
026: this .args = args;
027: this .lexenv = lexenv;
028: }
029:
030: /** Clever performance trick i found in
031: http://docs.msdnaa.net/ark_new/Webfiles/WhitePapers/Babel01/bab12.pdf
032: **/
033: public Throwable fillInStackTrace() {
034: return this ;
035: }
036:
037: public Throwable getBaseException() {
038: Throwable t = this .exception;
039: while (t instanceof BacktraceException)
040: t = ((BacktraceException) t).exception;
041: return t;
042: }
043:
044: public void printStackTrace(java.io.PrintStream s) {
045: this .printStackTrace(new java.io.PrintWriter(s));
046: }
047:
048: public void printStackTrace() {
049: this .printStackTrace(Scheme.currentEvaluator().getError());
050: }
051:
052: private static final Symbol backtraceBody = Symbol
053: .intern("backtraceBody");
054:
055: /** Try once to load code for a nicer backtrace. If you fail use
056: the older one. **/
057: private static boolean triedOnce = false;
058:
059: public static boolean checkBacktrace() {
060: try {
061: // if (jscheme.JS.isDefined("backtraceBody")) return true;
062: if (Scheme.currentEvaluator().getInteractionEnvironment()
063: .isDefined(backtraceBody))
064: return true;
065: if (triedOnce)
066: return false;
067: triedOnce = true;
068: Scheme.load("elf/basic.scm");
069: return true;
070: } catch (Throwable t) {
071: return false;
072: }
073: }
074:
075: public void printStackTrace(java.io.PrintWriter s) {
076: try {
077: // if (checkBacktrace())
078: // jscheme.JS.call("backtraceBody", lexenv, args);
079: // else showargs(args, s);
080: if (checkBacktrace()) {
081: // was: jscheme.JS.call("backtraceBody", lexenv, args);
082: Object bbProc = Scheme.currentEvaluator()
083: .getInteractionEnvironment().getValue(
084: backtraceBody);
085: U.toProc(bbProc).apply(
086: jscheme.JScheme.list(lexenv, args));
087: } else {
088: s.print("showargs: ");
089: showargs(args, s); // args is "analyzed form": may look strange
090: }
091: s.println();
092: lexenv.show(s);
093: s.println("\n ====================================");
094: if (printJavaTrace
095: || (this .exception instanceof BacktraceException))
096: this .exception.printStackTrace(s);
097: else
098: s.println(this .exception);
099: s.flush();
100: } catch (Throwable e) {
101: s.println("Error in BacktraceException.printStackTrace: ");
102: try {
103: ultimateException(e).printStackTrace(s);
104: } catch (Throwable e2) {
105: try {
106: s.println("Error tracing the ultimate error: "
107: + ultimateException(e));
108: } catch (Throwable e3) {
109: s
110: .println("Error printing ultimate error of class: "
111: + ultimateException(e).getClass());
112: }
113: }
114: }
115: }
116:
117: public void showargs(Object x, java.io.PrintWriter s) {
118: if (x == null)
119: s.println();
120: else if (x.getClass().isArray()) {
121: Object[] xv = (Object[]) x;
122: if (xv.length > 0 && Symbol.QUOTE == xv[0])
123: s.print(U.stringify(xv[1]) + " ");
124: else {
125: s.print("(");
126: for (int i = 0; i < xv.length; i++)
127: showargs(xv[i], s);
128: s.print(")");
129: }
130: } else if (x.getClass() == LocalVariable.class)
131: s.print(((LocalVariable) x).name + " ");
132: else
133: s.print(U.stringify(x) + " ");
134: }
135:
136: private static Throwable ultimateException(Throwable e) {
137: return (e instanceof BacktraceException) ? ultimateException(((BacktraceException) e).exception)
138: : e;
139: }
140:
141: }
|