1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15 
16 #ifndef __H5EXCEPTION_HXX__
17 #define __H5EXCEPTION_HXX__
18 
19 extern "C"
20 {
21 #include "localization.h"
22 #include "backtrace_print.h"
23 }
24 
25 #include "HDF5Objects.h"
26 
27 #include <cstdlib>
28 #include <exception>
29 #include <sstream>
30 #include <string>
31 #include <cstdio>
32 #include <stdarg.h>
33 
34 #define BUFFER_SIZE 1024
35 
36 namespace org_modules_hdf5
37 {
38 class H5Exception : public std::exception
39 {
40     std::string message;
41     std::string file;
42     int line;
43 
44 public :
45 
H5Exception(const int _line,const char * _file,std::string _message,...)46     H5Exception(const int _line, const char * _file, std::string _message, ...) : message(""), file(_file), line(_line)
47     {
48         char str[BUFFER_SIZE];
49         va_list args;
50 
51         va_start(args, _message);
52         vsnprintf(str, BUFFER_SIZE, _message.c_str(), args);
53         va_end(args);
54 
55         message = getDescription(std::string(str));
56     }
57 
H5Exception(const int _line,const char * _file,const char * _message,...)58     H5Exception(const int _line, const char * _file, const char * _message, ...) : message(""), file(_file), line(_line)
59     {
60         char str[BUFFER_SIZE];
61         va_list args;
62 
63         va_start(args, _message);
64         vsnprintf(str, BUFFER_SIZE, _message, args);
65         va_end(args);
66 
67         message = getDescription(std::string(str));
68     }
69 
~H5Exception()70     virtual ~H5Exception() throw() { }
71 
what() const72     virtual const char * what() const throw()
73     {
74         return message.c_str();
75     }
76 
77 private:
78 
getHDF5ErrorMsg()79     static std::string getHDF5ErrorMsg()
80     {
81         hid_t stid = H5Eget_current_stack();
82         if (stid < 0)
83         {
84             return std::string(_("Cannot get the current stack of errors."));
85         }
86 
87         ssize_t stackSize = H5Eget_num(stid);
88         std::string ret;
89 
90         if (stackSize)
91         {
92             herr_t err = H5Ewalk2(stid, H5E_WALK_UPWARD, getStackErrorMsg, &ret);
93             H5Eclear2(stid);
94         }
95 
96         return ret;
97     }
98 
getStackErrorMsg(unsigned int n,const H5E_error2_t * eptr,void * client_data)99     static herr_t getStackErrorMsg(unsigned int n, const H5E_error2_t * eptr, void * client_data)
100     {
101         std::string * str = (std::string *)client_data;
102         str->append(eptr->desc);
103 
104         return -1;
105     }
106 
getDescription(std::string m) const107     inline std::string getDescription(std::string m) const
108     {
109         std::ostringstream os;
110         std::string err = getHDF5ErrorMsg();
111         if (!err.empty())
112         {
113             os << m << std::endl
114                << _("HDF5 description") << ": " << err << "." << std::flush;
115 
116             m = os.str();
117             os.str("");
118         }
119 
120 #if defined(__HDF5OBJECTS_DEBUG__)
121 
122         if (line == -1)
123         {
124             return m;
125         }
126 
127         const char * bt = backtrace_print(0, 1);
128 
129         os << m << std::endl
130            << "DEBUG Information:" << std::endl
131            << gettext("Exception thrown in file") << " " << file << " " << gettext("at line") << " " << line << std::endl
132            << bt << std::flush;
133 
134         free(const_cast<char *>(bt));
135 
136         return os.str();
137 
138 #else
139 
140         return m;
141 
142 #endif
143     }
144 };
145 }
146 
147 #endif // __H5EXCEPTION_HXX__
148