/* ====================================================================
 * Copyright (c) 2003-2006, Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

// sc
#include "config.h"
#include "StdException.h"
#include "util/Error.h"
#include "util/ErrorCodes.h"


///////////////////////////////////////////////////////////////////////

static sc::String sExceptions[] =
{
  sc::String("exception_access_violation"),
  sc::String("exception_datatype_misalignment"),
  sc::String("exception_breakpoint"),
  sc::String("exception_single_step"),
  sc::String("exception_array_bounds_exceeded"),
  sc::String("exception_flt_denormal_operand"),
  sc::String("exception_flt_divide_by_zero"),
  sc::String("exception_flt_inexact_result"),
  sc::String("exception_flt_invalid_operation"),
  sc::String("exception_flt_overflow"),
  sc::String("exception_flt_stack_check"),
  sc::String("exception_flt_underflow"),
  sc::String("exception_int_divide_by_zero"),
  sc::String("exception_int_overflow"),
  sc::String("exception_priv_instruction"),
  sc::String("exception_in_page_error"),
  sc::String("exception_illegal_instruction"),
  sc::String("exception_noncontinuable_exception"),
  sc::String("exception_stack_overflow"),
  sc::String("exception_invalid_disposition"),
  sc::String("exception_guard_page"),
  sc::String("exception_invalid_handle"),
  sc::String("exception_unknown")
};

static const sc::String& strException(  unsigned int e )
{
  switch( e )
  {
    case EXCEPTION_ACCESS_VIOLATION:         return sExceptions[0];
    case EXCEPTION_DATATYPE_MISALIGNMENT:    return sExceptions[1];
    case EXCEPTION_BREAKPOINT:               return sExceptions[2];
    case EXCEPTION_SINGLE_STEP:              return sExceptions[3];
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:    return sExceptions[4];
    case EXCEPTION_FLT_DENORMAL_OPERAND:     return sExceptions[5];
    case EXCEPTION_FLT_DIVIDE_BY_ZERO:       return sExceptions[6];
    case EXCEPTION_FLT_INEXACT_RESULT:       return sExceptions[7];
    case EXCEPTION_FLT_INVALID_OPERATION:    return sExceptions[8];
    case EXCEPTION_FLT_OVERFLOW:             return sExceptions[9];
    case EXCEPTION_FLT_STACK_CHECK:          return sExceptions[10];
    case EXCEPTION_FLT_UNDERFLOW:            return sExceptions[11];
    case EXCEPTION_INT_DIVIDE_BY_ZERO:       return sExceptions[12];
    case EXCEPTION_INT_OVERFLOW:             return sExceptions[13];
    case EXCEPTION_PRIV_INSTRUCTION:         return sExceptions[14];
    case EXCEPTION_IN_PAGE_ERROR:            return sExceptions[15];
    case EXCEPTION_ILLEGAL_INSTRUCTION:      return sExceptions[16];
    case EXCEPTION_NONCONTINUABLE_EXCEPTION: return sExceptions[17];
    case EXCEPTION_STACK_OVERFLOW:           return sExceptions[18];
    case EXCEPTION_INVALID_DISPOSITION:      return sExceptions[19];
    case EXCEPTION_GUARD_PAGE:               return sExceptions[20];
    case EXCEPTION_INVALID_HANDLE:           return sExceptions[21];
    default: return sExceptions[22];
  }
}

///////////////////////////////////////////////////////////////////////


StdException::StdException( unsigned int error, const Stackframes& stack, const sc::String& dump )
{
  _error = createError( error, strException(error), createError(sc::ErrDump,dump) );
  _stack = stack;
}

StdException::~StdException()
{
  // we get out of scope before the error is handled, so it is a bad
  // idea to delete it.

  //delete _error;
}

const sc::Error* StdException::getError() const
{
  return _error;
}

const Stackframes& StdException::getStack() const
{
  return _stack;
}
