/* Generated automatically by jlpp - do not edit. */ #include static jakelib::lang::String* jakelib2_strings[] = {null, null, null, null, null, null, null, null}; // ": " static jchar chars_jakelib2_str_0[] = {58,32}; // " <>" static jchar chars_jakelib2_str_1[] = {32,32,32,32,32,32,32,32,60,60,78,111,32,115,116,97,99,107,116,114,97,99,101,32,97,118,97,105,108,97,98,108,101,62,62}; // " at " static jchar chars_jakelib2_str_2[] = {32,32,32,32,32,32,32,32,97,116,32}; // "<>" static jchar chars_jakelib2_str_3[] = {60,60,85,110,107,110,111,119,110,62,62}; // " ..." static jchar chars_jakelib2_str_4[] = {32,32,32,46,46,46}; // " more" static jchar chars_jakelib2_str_5[] = {32,109,111,114,101}; // "Element " static jchar chars_jakelib2_str_6[] = {69,108,101,109,101,110,116,32}; // " null" static jchar chars_jakelib2_str_7[] = {32,110,117,108,108}; #line 1 "lang/Throwable.jlc" // -*- c++ -*- /* * Jakelib2 - General purpose C++ library * Copyright (C) 2001 Florian Wolff (florian@donuz.de) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: Throwable.jlc,v 1.15 2003/09/27 08:10:28 florian Exp $ */ #include "jakelib2.h" #include "jakelib2/lang/System.h" #include "jakelib2/lang/Throwable.h" #include "jakelib2/lang/Thread.h" #include "jakelib2/lang/StackTrace.h" #include using namespace jakelib::lang; using namespace jakelib::io; JAKELIB_IMPLEMENT_CLASS("jakelib.lang.Throwable", Throwable, Object) /*****************************************************************************\ * Throwable | *****************************************************************************/ Throwable::Throwable() { cause = this; message = String::emptyString; fillInStackTrace(); } Throwable::Throwable(String* msg) { cause = this; initMsg(msg); fillInStackTrace(); } Throwable::Throwable(String *msg, Throwable *cause) { initMsg(msg); initCause(cause); fillInStackTrace(); } Throwable::Throwable(Throwable* cause) { initMsg((cause == null) ? null : cause->toString()); initCause(cause); fillInStackTrace(); } /*****************************************************************************\ * getMessage | *****************************************************************************/ String* Throwable::getMessage() { return message; } /*****************************************************************************\ * toString | *****************************************************************************/ String* Throwable::toString() { return getClass()->getName() ->plus( JAKELIB_ONDEMAND(jakelib2_strings[0], new jakelib::lang::String(chars_jakelib2_str_0, 0, 2)) )->plus( message); } /*****************************************************************************\ * toString | *****************************************************************************/ void Throwable::initMsg(String *msg) { if (msg == null) message = String::emptyString; else message = msg; } /*****************************************************************************\ * printStackTrace | *****************************************************************************/ void Throwable::printStackTrace() { printStackTrace(jakelib::lang::System::err); } /*+++AlFa 01/24/2003 this is original Classpath inplementation we don't have PrintStream, so it's implemented using PrintWriter void Throwable::printStackTrace(PrintStream* s) { s->print(stackTraceString()); }*/ void Throwable::printStackTrace(PrintWriter* pw) { pw->print(stackTraceString()); } /*****************************************************************************\ * initCause | *****************************************************************************/ Throwable* Throwable::initCause(Throwable *cause) { if (cause == this) throw new IllegalArgumentException(); if (this->cause != this) throw new IllegalStateException(); this->cause = cause; return this; } /*****************************************************************************\ * toString | *****************************************************************************/ Throwable* Throwable::getCause() { return (cause == this) ? null : cause; } /*****************************************************************************\ * stackTraceString | *****************************************************************************/ String* Throwable::stackTraceString() { StringBuffer sb; // Main stacktrace StackTraceElements* stack = getStackTrace(); stackTraceStringBuffer(&sb, toString(), stack, 0); // The cause(s) Throwable* cause = getCause(); // while (cause != null) { // // Cause start first line // sb.append(`"Caused by: "`); // // Cause stacktrace // StackTraceElements* parentStack = stack; // stack = cause->getStackTrace(); // if (parentStack == null || parentStack->length() == 0) // stackTraceStringBuffer(&sb, cause->toString(), stack, 0); // else { // int equal = 0; // Count how many of the last stack frames are equal // int frame = stack->length()-1; // int parentFrame = parentStack->length()-1; // while (frame > 0 && parentFrame > 0) { // if ((*stack)[frame]->equals((*parentStack)[parentFrame])) { // equal++; // frame--; // parentFrame--; // } // else // break; // } // stackTraceStringBuffer(&sb, cause->toString(), stack, equal); // } // cause = cause->getCause(); // } return sb.toString(); } /*****************************************************************************\ * stackTraceStringBuffer | *****************************************************************************/ void Throwable::stackTraceStringBuffer(StringBuffer* sb, String* name, StackTraceElements* stack, int equal) { String* nl = System::eol; // (finish) first line sb->append(name); sb->append(System::eol); // The stacktrace if (stack == null || stack->length() == 0) { sb->append(JAKELIB_ONDEMAND(jakelib2_strings[1], new jakelib::lang::String(chars_jakelib2_str_1, 0, 35))); sb->append(nl); } else { StackTraceElements& st = *stack;//just a handy reference to use nice array operators for (int i = 0; i < (st.length() - equal); i++) { sb->append(JAKELIB_ONDEMAND(jakelib2_strings[2], new jakelib::lang::String(chars_jakelib2_str_2, 0, 11))); sb->append(st.get(i) == null ? JAKELIB_ONDEMAND(jakelib2_strings[3], new jakelib::lang::String(chars_jakelib2_str_3, 0, 11)) : st.get(i)->toString()); sb->append(nl); } if (equal > 0) { sb->append(JAKELIB_ONDEMAND(jakelib2_strings[4], new jakelib::lang::String(chars_jakelib2_str_4, 0, 6))); sb->append(equal); sb->append(JAKELIB_ONDEMAND(jakelib2_strings[5], new jakelib::lang::String(chars_jakelib2_str_5, 0, 5))); sb->append(nl); } } } /*****************************************************************************\ * fillInStackTrace | *****************************************************************************/ Throwable* Throwable::fillInStackTrace() { #ifdef JAKELIB_STACKTRACE StackTrace *st = Thread::currentThread()->getStackTrace(); int size = st->getElemCount(); stackTrace = new StackTraceElements(size); //System::out->println(`"Throwable::fillInStackTrace: elemCount="`..size); for (int idx = 0; idx < size; idx++) { TmpStackTraceElement *tmp = st->get(idx); String *methodName = null; String *className = null; int len = (tmp->methodName != 0) ? (int)strlen(tmp->methodName) : -1; int startX = 0; int endX = len; #if defined(POSIX) || defined(MSVC) for (int x = 0; x < len; x++) { if (tmp->methodName[x] == ' ') startX = x + 1; else if (tmp->methodName[x] == ':') { for (; x < len; x++) { if (tmp->methodName[x] == '(' || tmp->methodName[x] == ' ') { endX = x; break; } } break; } else if (tmp->methodName[x] == '(') { endX = x; } } methodName = new String(tmp->methodName, startX, endX - startX); className = null; #endif StackTraceElement *elem = new StackTraceElement(className, methodName, new String(tmp->fileName), tmp->lineNumber); stackTrace->set(size - idx - 1, elem); } #else stackTrace = new StackTraceElements(0); #endif return this; } /*****************************************************************************\ * getStackTrace | *****************************************************************************/ StackTraceElements* Throwable::getStackTrace() { return stackTrace; } /*****************************************************************************\ * setStackTrace | *****************************************************************************/ void Throwable::setStackTrace(StackTraceElements* stackTrace) { jint i = stackTrace->length(); StackTraceElements& st = *(new StackTraceElements(i)); st = *stackTrace; while (--i >= 0) { if (st.get(i) == null) throw new NullPointerException(JAKELIB_ONDEMAND(jakelib2_strings[6], new jakelib::lang::String(chars_jakelib2_str_6, 0, 8)) ->plus( i )->plus( JAKELIB_ONDEMAND(jakelib2_strings[7], new jakelib::lang::String(chars_jakelib2_str_7, 0, 5)))); } this->stackTrace = &st; }