contrib/mul/mbl/mbl_exception.cxx
Go to the documentation of this file.
00001 // This is mul/mbl/mbl_exception.cxx
00002 #include "mbl_exception.h"
00003 //:
00004 // \file
00005 // \brief Exceptions thrown by mbl, and a mechanism for turning them off.
00006 // \author Ian Scott.
00007 
00008 #include <vcl_cerrno.h>
00009 #include <vcl_cstring.h>
00010 
00011 #if 0 // should be #ifdef VCL_VC, but it doesn't work yet - I can't get it to link
00012 #pragma comment(lib, "user32")
00013 #pragma comment (lib, "dbghelp")
00014 #include <vxl_config.h>
00015 #define AFX_STACK_DUMP_TARGET_CLIPBOARD 0x0002
00016 #define CF_OEMTEXT          7
00017 #define AFXAPI __stdcall
00018 #define WINAPI __stdcall
00019 typedef vxl_uint_32 DWORD;
00020 typedef void * HANDLE;
00021 typedef unsigned int UINT;
00022 #if (!defined(_USER32_) && (defined(_M_IX86) || defined(_M_IA64) || defined(_M_AMD64)))
00023 #define WINUSERAPI __declspec(dllimport)
00024 #else
00025 #define WINUSERAPI
00026 #endif
00027 #if (!defined(_KERNEL32_) && (defined(_M_IX86) || defined(_M_IA64) || defined(_M_AMD64)))
00028 #define WINBASEAPI __declspec(dllimport)
00029 #else
00030 #define WINBASEAPI
00031 #endif
00032 
00033 void AFXAPI AfxDumpStack(DWORD);
00034 WINUSERAPI bool WINAPI OpenClipboard(HANDLE hWndNewOwner);
00035 WINUSERAPI bool WINAPI CloseClipboard(void);
00036 WINUSERAPI HANDLE WINAPI GetClipboardData(UINT uFormat);
00037 WINBASEAPI void * WINAPI GlobalLock(HANDLE hMem);
00038 static vcl_string LotsOfInfo()
00039 {
00040   vcl_string text;
00041   text = "Stack: ";
00042   ::AfxDumpStack(AFX_STACK_DUMP_TARGET_CLIPBOARD);
00043   if ( !::OpenClipboard(0) )
00044     text += "Failed to open clipboard to retrieve stack trace.\n";
00045   HANDLE hglb = ::GetClipboardData(CF_OEMTEXT);
00046   if (hglb == NULL)
00047     text += "Failed to retrieve stack trace from clipboard.\n";
00048   const char* str = static_cast<const char *>(::GlobalLock(hglb));
00049   if (str == NULL)
00050     text += "Failed to convert stack trace from clipboard.\n";
00051   else
00052     text += str;
00053   ::CloseClipboard();
00054   return text;
00055 }
00056 
00057 #else // 0, should be VCL_VC
00058 
00059 static vcl_string LotsOfInfo()
00060 {
00061   return "";
00062 }
00063 
00064 #endif // 0, should be VCL_VC
00065 
00066 #if !VCL_HAS_EXCEPTIONS
00067 
00068 mbl_exception_abort::mbl_exception_abort(const vcl_string& comment):
00069   msg_(comment + LotsOfInfo()) {}
00070 
00071 #else
00072 
00073 mbl_exception_abort::mbl_exception_abort(const vcl_string& comment):
00074   vcl_logic_error(comment + LotsOfInfo()) {}
00075 
00076 #endif
00077 
00078 mbl_exception_os_error::mbl_exception_os_error(int errnum, const vcl_string &file_name,
00079                                                const vcl_string &comment/*=""*/):
00080 #if !VCL_HAS_EXCEPTIONS
00081   msg_(file_name + " " + vcl_strerror(errnum) + "\n" + comment),
00082     errno(errnum), error_message(vcl_strerror(errnum)), filename(file_name),
00083     additional_comment(comment) {}
00084 #else
00085   vcl_runtime_error(vcl_string("\"") + file_name + "\" " + vcl_strerror(errnum) + "\n" + comment),
00086     err_no(errnum), error_message(vcl_strerror(errnum)), filename(file_name),
00087     additional_comment(comment) {}
00088 #endif
00089 
00090 void mbl_exception_throw_os_error(const vcl_string& filename,
00091                                   const vcl_string& additional_comment /*=""*/)
00092 {
00093   switch (errno)
00094   {
00095   case ENOENT:
00096     mbl_exception_warning(mbl_exception_os_no_such_file_or_directory(ENOENT, filename, additional_comment));
00097     break;
00098   case EACCES:
00099     mbl_exception_warning(mbl_exception_os_permission_denied(EACCES, filename, additional_comment));
00100     break;
00101   case EEXIST:
00102     mbl_exception_warning(mbl_exception_os_file_exists(EEXIST, filename, additional_comment));
00103     break;
00104   case ENOTDIR:
00105     mbl_exception_warning(mbl_exception_os_not_a_directory(ENOTDIR, filename, additional_comment));
00106     break;
00107   case EISDIR:
00108     mbl_exception_warning(mbl_exception_os_is_a_directory(EISDIR, filename, additional_comment));
00109     break;
00110   case ENOSPC:
00111     mbl_exception_warning(mbl_exception_os_no_space_left_on_device(ENOSPC, filename, additional_comment));
00112     break;
00113   case EINVAL:
00114     mbl_exception_warning(mbl_exception_os_invalid_value(EINVAL, filename, additional_comment));
00115     break;
00116   default:
00117     mbl_exception_warning(mbl_exception_os_error(errno, filename, additional_comment));
00118     break;
00119   }
00120 }
00121