
/**********************************************************//**
 **
 ** @file base/exception_c.h
 **
 ** Copyright (C) 2009  Xpace, LLC.  All rights reserved
 **
 ** www.xpace.net
 **
 **************************************************************/

#ifndef XPACE_EXCEPTION_C_H
#define XPACE_EXCEPTION_C_H

#include "base/types_c.h"

#ifdef __cplusplus
  #include "base/exception.h"
  extern "C"
  {
  struct Xpace_Error
  {
    Xpace::AnyException* ex;
  };

  Xpace_Error XPACE_ABI Xpace_Error_Create
    (const Xpace::Exception& ex);
  Xpace_Error XPACE_ABI Xpace_Error_Create_Std
    (const std::exception& ex = std::bad_alloc());

  extern Xpace_Error Xpace_Error_None;

#else
  typedef struct
  {
    void* v;
  }
  Xpace_Error;
#endif

XPACE_EXPORT Xpace_Error XPACE_ABI Xpace_Error_Copy
  (Xpace_Error);

XPACE_EXPORT void XPACE_ABI Xpace_Error_Destroy
  (Xpace_Error);

/// Get to the error that cause this one (if any)
/// @return the error we there is such an error
XPACE_EXPORT Xpace_Error XPACE_ABI  Xpace_Error_Why
  (Xpace_Error);

/// @return English template into which params will be inserted
XPACE_EXPORT Xpace_String XPACE_ABI Xpace_Error_getTemplate
  (Xpace_Error);

/// Construct an error message
/// @param templ the template into which params will be inserted
///   (I.e., a translation of getTemplate() for this exception)
///   if = Xpace_String(), use English template
/// @return the translated template with params insterted
XPACE_EXPORT Xpace_String XPACE_ABI Xpace_Error_getMessage
  (Xpace_Error, 
   const Xpace_String templ);

/// @return an English error message with params inserted
XPACE_EXPORT char* XPACE_ABI Xpace_Error_What
  (const Xpace_Error);

#ifdef __cplusplus
  #define CALL_CATCH(x)  \
    try                                     \
    {                                       \
      x;                                    \
    }                                       \
    catch (Xpace::Exception& ex)            \
    {                                       \
      return Xpace_Error_Create(ex);        \
    }                                       \
    catch (std::exception& ex)              \
    {                                       \
      return Xpace_Error_Create_Std(ex);    \
    }                                       \
    return Xpace_Error_None;
  }
#endif

#endif
