rvm  1.11
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
error.cc
Go to the documentation of this file.
1 #include "config.h"
2 
3 #include <cerrno>
4 #include <cstring>
5 #ifdef HAVE_CSTDIO
6 #include <cstdio>
7 #endif
8 #ifdef HAVE_CSTDLIB
9 #include <cstdlib>
10 #endif
11 
12 #include "asserts.h"
13 #include "types.h"
14 #include "error.h"
15 
16 #define internal_TRY_nomem(code) \
17  try { \
18  code; \
19  } \
20  catch(...) { \
21  if (errno == 12) \
22  std::cerr << err_nomem; \
23  else \
24  std::cerr << err_unknown; \
25  }
26 
27 //-----------------------------------------------------------------------------
28 
30 {
31  clear();
32 }
33 
35 {
36  set(a_e);
37 }
38 
40  const std::string a_what,
41 #ifdef __GNUC__
42  const std::string a_where,
43 #endif
44  const std::string a_file,
45  const uint16 a_line
46  )
47 {
48  set(
49  a_what,
50 #ifdef __GNUC__
51  a_where,
52 #endif
53  a_file,
54  a_line
55  );
56 }
57 
59 {
61 #ifdef __GNUC__
62  internal_TRY_nomem(m_where = "");
63 #endif
65  m_line = 0;
66 }
67 
69 {
70  clear();
71 }
72 
74  const std::string a_what,
75 #ifdef __GNUC__
76  const std::string a_where,
77 #endif
78  const std::string a_file,
79  const uint16 a_line
80  )
81 {
82  clear();
83 
84  internal_TRY_nomem(m_what = a_what);
85 #ifdef __GNUC__
86  internal_TRY_nomem(m_where = a_where);
87 #endif
88  internal_TRY_nomem(m_file = a_file);
89  m_line = a_line;
90 }
91 
93 {
94  clear();
95 
97 #ifdef __GNUC__
98  internal_TRY_nomem(m_where = a_e.where());
99 #endif
100  internal_TRY_nomem(m_file = a_e.file());
101  m_line = a_e.line();
102 }
103 
104 const std::string error_instance::what(void) const
105 {
106  return(m_what);
107 }
108 
109 #ifdef __GNUC__
110 const std::string error_instance::where(void) const
111 {
112  return(m_where);
113 }
114 #endif
115 
116 const std::string error_instance::file(void) const
117 {
118  return(m_file);
119 }
120 
121 const uint16 error_instance::line(void) const
122 {
123  return(m_line);
124 }
125 
127 {
128  set(a_e);
129 
130  return(*this);
131 }
132 
133 /*
134 void
135 error_instance::dump(std::ostream& a_out, const std::string& a_prefix) const
136 {
137  a_out
138  << a_prefix
139  << "error_instance::what = \""
140  << m_what
141  << "\""
142  << std::endl;
143 #ifdef __GNUC__
144  a_out
145  << a_prefix
146  << " ::where = "
147  << m_where
148  << std::endl;
149 #endif
150  a_out
151  << a_prefix
152  << " ::at "
153  << m_file << "[" << m_line << "]"
154  << std::endl;
155 }
156 */
157 
158 //-----------------------------------------------------------------------------
159 
160 error::error(const int a_errno)
161 {
162  clear();
163  num(a_errno);
164 }
165 
167  const int a_errno,
168  const error_instance& a_e,
169  const bool a_internal
170  )
171 {
172  clear();
173  push_back(a_e);
174  internal(a_internal);
175  num(a_errno);
176 }
177 
178 error::error(const error& a_e)
179 {
180  assign(a_e);
181 }
182 
183 void error::clear(void)
184 {
185  m_errno = 0;
186  m_internal = false;
187  clear_stack();
188 }
189 
191 {
192  type::clear();
193 }
194 
195 void error::internal(bool a_i)
196 {
197  m_internal = a_i;
198 }
199 
200 const bool error::internal(void) const
201 {
202  return(m_internal);
203 }
204 
205 void error::num(int a_i)
206 {
207  m_errno = a_i;
208 }
209 
210 int error::num(void) const
211 {
212  return(m_errno);
213 }
214 
216 {
217  try {
218  type::push_back(a_e);
219  }
220  catch(...) {
221  std::cerr << "*** ERROR: ";
222  if (errno != 0) {
223  std::cerr
224  << "[" << errno << "]: "
225  << get_error_str(errno)
226  << std::endl;
227  std::cerr << " ";
228  errno = 0;
229  }
230  std::cerr << "error::push_back() failed" << std::endl;
231  }
232 }
233 
234 void error::push_back(const error& a_e)
235 {
236  error::const_iterator ei;
237 
238  for (ei = a_e.begin(); ei != a_e.end(); ei++) {
239  push_back(*ei);
240  }
241 }
242 
243 void error::push_back(const std::string& a_str)
244 {
245  error_instance ei;
246 
247  internal_TRY_nomem(ei = ERROR_INSTANCE(a_str));
248  push_back(ei);
249 }
250 
251 void error::assign(const error& a_e)
252 {
253  const_iterator eii;
254 
255  clear();
256  m_errno = a_e.num();
257  m_internal = a_e.internal();
258  for (eii = a_e.begin(); eii != a_e.end(); eii++) {
259  push_back(*eii);
260  }
261 }
262 
264 {
265  assign(a_e);
266 
267  return(*this);
268 }
269 
270 std::ostream&
271  error::write(std::ostream& a_out, const std::string a_prefix) const
272 {
273  const_iterator eii;
274 
275  if (a_prefix.size() != 0)
276  a_out << a_prefix << " ";
277  a_out << "*** ";
278  if (m_internal)
279  a_out << "INTERNAL ";
280  a_out << "ERROR";
281 
282  if (m_errno != 0)
283  a_out << " [" << m_errno << "]: " << strerror(m_errno);
284  a_out << std::endl;
285 
286  for (eii = begin(); eii != end(); ++eii) {
287  if (a_prefix.size() != 0)
288  a_out << a_prefix << " ";
289  if (eii->what().size() != 0)
290  a_out << " " << eii->what() << std::endl;
291  if (m_internal) {
292  a_out << " ";
293 #ifdef __GNUC__
294  a_out << "in " << eii->where() << " ";
295 #endif
296  a_out << "at " << eii->file() << "[" << eii->line() << "]";
297  a_out << std::endl;
298  }
299  }
300 
301  return(a_out);
302 }
303 
304 const std::string error::str(const std::string a_prefix) const
305 {
306  static const size_t buffer_len = 32;
307  char buffer[buffer_len] = { 0 };
308  std::string es;
309  const_iterator eii;
310 
311  try {
312  es.erase();
313  if (a_prefix.size() != 0) {
314  es += a_prefix;
315  es += " ";
316  }
317  es += "*** ";
318  if (m_internal)
319  es += "INTERNAL ";
320  es += "ERROR";
321 
322  snprintf(buffer, buffer_len, "%d", m_errno);
323  if (m_errno != 0) {
324  es += " [";
325  es += buffer;
326  es += "]: ";
327  es += strerror(m_errno);
328  }
329  es += "\n";
330 
331  for (eii = begin(); eii != end(); ++eii) {
332  if (a_prefix.size() != 0)
333  es += a_prefix + " ";
334  if (eii->what().size() != 0) {
335  es += " ";
336  es += eii->what();
337  es += "\n";
338  }
339  snprintf(buffer, buffer_len, "%u", eii->line());
340  if (m_internal) {
341  es += " ";
342 #ifdef __GNUC__
343  es += "in ";
344  es += eii->where();
345  es += " ";
346 #endif
347  es += "at ";
348  es += eii->file();
349  es += "[";
350  es += buffer;
351  es += "]";
352  es += "\n";
353  }
354  }
355  }
356  catch(...) {
357  if (errno == 12)
358  std::cerr << err_nomem;
359  else
360  std::cerr << err_unknown;
361  }
362 
363  return(es);
364 }
365 
366 /*
367 std::ostream& error::dump(std::ostream& a_out) const
368 {
369  const_iterator eii;
370 
371  a_out << "ERROR: errno = " << m_errno;
372  if (m_errno != 0) {
373  a_out << " \"" << strerror(m_errno) << "\"";
374  }
375  a_out << std::endl;
376  for (eii = begin(); eii != end(); ++eii) {
377  eii->dump(a_out, " ");
378  }
379 
380  return(a_out);
381 }
382 */
383 
384 std::ostream& operator<<(std::ostream& a_out, const error& a_e)
385 {
386  return(a_e.write(a_out));
387 }
388 
389 const char * get_error_str(const int a_err)
390 {
391  return(strerror(a_err));
392 }
393 
394 //-----------------------------------------------------------------------------
395 
void assign(const error &a_e)
Definition: error.cc:251
error_instance()
Definition: error.cc:29
Basic types definitions and templates.
std::string m_file
Definition: error.h:59
int num(void) const
Definition: error.cc:210
const bool internal(void) const
Definition: error.cc:200
#define err_nomem
Definition: error.h:116
std::ostream & write(std::ostream &a_out, const std::string a_prefix="") const
Definition: error.cc:271
error_instance & operator=(const error_instance &a_e)
Definition: error.cc:126
const char * get_error_str(const int a_err)
Definition: error.cc:389
Instance of a single error containing a descriptive error message and the location in the file that t...
Definition: error.h:17
std::string m_what
Definition: error.h:55
void push_back(const error_instance &a_e)
Definition: error.cc:215
void clear(void)
Definition: error.cc:183
void num(int a_i)
Definition: error.cc:205
const uint16 line(void) const
Definition: error.cc:121
#define internal_TRY_nomem(code)
Definition: error.cc:16
const std::string what(void) const
Definition: error.cc:104
const std::string file(void) const
Definition: error.cc:116
std::ostream & operator<<(std::ostream &a_out, const error &a_e)
Definition: error.cc:384
#define err_unknown
Definition: error.h:114
void internal(bool a_i)
Definition: error.cc:195
An error class.
Definition: error.h:72
void clear(void)
Definition: error.cc:58
uint16 m_line
Definition: error.h:60
bool m_internal
Definition: error.h:107
int m_errno
Definition: error.h:106
error & operator=(const error &a_e)
Definition: error.cc:263
void set(void)
Definition: error.cc:68
#define ERROR_INSTANCE(s)
Definition: error.h:67
error(const int a_errno)
Definition: error.cc:160
void clear_stack(void)
Definition: error.cc:190
const std::string str(const std::string a_prefix="") const
Definition: error.cc:304