1 // Copyright (C)2004 Landmark Graphics Corporation
2 // Copyright (C)2005 Sun Microsystems, Inc.
3 // Copyright (C)2014, 2019-2020 D. R. Commander
4 //
5 // This library is free software and may be redistributed and/or modified under
6 // the terms of the wxWindows Library License, Version 3.1 or (at your option)
7 // any later version.  The full license is in the LICENSE.txt file included
8 // with this distribution.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // wxWindows Library License for more details.
14 
15 #ifndef __ERROR_H__
16 #define __ERROR_H__
17 
18 #ifdef _WIN32
19 #include <windows.h>
20 #endif
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <exception>
26 #include <typeinfo>
27 
28 
29 #define GET_METHOD(e) \
30 	(dynamic_cast <const vglutil::Error *>(&e) ? \
31 		((vglutil::Error &)e).getMethod() : "C++")
32 
33 
34 namespace vglutil
35 {
36 	class Error : public std::exception
37 	{
38 		public:
39 
Error(const char * method_,char * message_)40 			Error(const char *method_, char *message_)
41 			{
42 				init(method_, message_, -1);
43 			}
44 
Error(const char * method_,const char * message_)45 			Error(const char *method_, const char *message_)
46 			{
47 				init(method_, (char *)message_, -1);
48 			}
49 
Error(const char * method_,char * message_,int line)50 			Error(const char *method_, char *message_, int line)
51 			{
52 				init(method_, message_, line);
53 			}
54 
Error(const char * method_,const char * message_,int line)55 			Error(const char *method_, const char *message_, int line)
56 			{
57 				init(method_, (char *)message_, line);
58 			}
59 
init(const char * method_,char * message_,int line)60 			void init(const char *method_, char *message_, int line)
61 			{
62 				message[0] = 0;
63 				if(line >= 1) sprintf(message, "%d: ", line);
64 				if(!method_) method_ = "(Unknown error location)";
65 				method = method_;
66 				if(message_)
67 					strncpy(&message[strlen(message)], message_, MLEN - strlen(message));
68 			}
69 
Error(void)70 			Error(void) : method(NULL) { message[0] = 0; }
71 
72 			operator bool() { return method != NULL && message[0] != 0; }
73 			Error &operator= (const std::exception &e)
74 			{
75 				method = GET_METHOD(e);
76 				strncpy(message, e.what(), MLEN);
77 				return *this;
78 			}
79 
getMethod(void)80 			const char *getMethod(void) { return method; }
what(void)81 			virtual const char *what(void) const throw() { return message; }
82 
83 		protected:
84 
85 			static const int MLEN = 256;
86 			const char *method;  char message[MLEN + 1];
87 	};
88 }
89 
90 
91 #if defined(sgi)
92 #define __FUNCTION__  __FILE__
93 #endif
94 #define THROW(m)  throw(vglutil::Error(__FUNCTION__, m, __LINE__))
95 #define ERRIFNOT(f)  { if(!(f)) THROW("Unexpected NULL condition"); }
96 
97 
98 #ifdef _WIN32
99 
100 namespace vglutil
101 {
102 	class W32Error : public Error
103 	{
104 		public:
105 
W32Error(const char * method)106 			W32Error(const char *method) : Error(method, (char *)NULL)
107 			{
108 				if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
109 					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), message, MLEN, NULL))
110 					strncpy(message, "Error in FormatMessage()", MLEN);
111 			}
112 
W32Error(const char * method,int line)113 			W32Error(const char *method, int line) :
114 				Error(method, (char *)NULL, line)
115 			{
116 				if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
117 					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &message[strlen(message)],
118 					MLEN - (DWORD)strlen(message), NULL))
119 					strncpy(message, "Error in FormatMessage()", MLEN);
120 			}
121 	};
122 }
123 
124 #define THROW_W32()  throw(vglutil::W32Error(__FUNCTION__, __LINE__))
125 #define TRY_W32(f)  { if(!(f)) THROW_W32(); }
126 
127 #endif  // _WIN32
128 
129 
130 namespace vglutil
131 {
132 	class UnixError : public Error
133 	{
134 		public:
135 
UnixError(const char * method_)136 			UnixError(const char *method_) : Error(method_, strerror(errno)) {}
UnixError(const char * method_,int line)137 			UnixError(const char *method_, int line) :
138 				Error(method_, strerror(errno), line) {}
139 	};
140 }
141 
142 #define THROW_UNIX()  throw(vglutil::UnixError(__FUNCTION__, __LINE__))
143 #define TRY_UNIX(f)  { if((f) == -1) THROW_UNIX(); }
144 
145 
146 #define TRY_FBX(f) \
147 { \
148 	if((f) == -1) \
149 		throw(vglutil::Error("FBX", fbx_geterrmsg(), fbx_geterrline())); \
150 }
151 #define TRY_FBXV(f) \
152 { \
153 	if((f) == -1) \
154 		throw(vglutil::Error("FBXV", fbxv_geterrmsg(), fbxv_geterrline())); \
155 }
156 #define TRY_TJ(f) \
157 { \
158 	if((f) == -1) \
159 		throw(vglutil::Error(__FUNCTION__, tjGetErrorStr(), __LINE__)); \
160 }
161 
162 #endif  // __ERROR_H__
163