error.cc

Go to the documentation of this file.
00001 #include "config.h"
00002 
00003 #include <cerrno>
00004 #include <cstring>
00005 #ifdef HAVE_CSTDIO
00006 #include <cstdio>
00007 #endif
00008 #ifdef HAVE_CSTDLIB
00009 #include <cstdlib>
00010 #endif
00011 
00012 #include "asserts.h"
00013 #include "types.h"
00014 #include "error.h"
00015 
00016 #define internal_TRY_nomem(code) \
00017         try { \
00018                 code; \
00019         } \
00020         catch(...) { \
00021                 if (errno == 12) \
00022                         std::cerr << err_nomem; \
00023                 else \
00024                         std::cerr << err_unknown; \
00025         }
00026 
00027 //-----------------------------------------------------------------------------
00028 
00029 error_instance::error_instance()
00030 {
00031         clear();
00032 }
00033 
00034 error_instance::error_instance(const error_instance& a_e)
00035 {
00036         set(a_e);
00037 }
00038 
00039 error_instance::error_instance(
00040         const std::string a_what,
00041 #ifdef __GNUC__
00042         const std::string a_where,
00043 #endif
00044         const std::string a_file,
00045         const uint16 a_line
00046         )
00047 {
00048         set(
00049                 a_what,
00050 #ifdef __GNUC__
00051                 a_where,
00052 #endif
00053                 a_file,
00054                 a_line
00055                 );
00056 }
00057 
00058 void error_instance::clear(void)
00059 {
00060         internal_TRY_nomem(m_what = "");
00061 #ifdef __GNUC__
00062         internal_TRY_nomem(m_where = "");
00063 #endif
00064         internal_TRY_nomem(m_file = "");
00065         m_line = 0;
00066 }
00067 
00068 void error_instance::set(void)
00069 {
00070         clear();
00071 }
00072 
00073 void error_instance::set(
00074         const std::string a_what,
00075 #ifdef __GNUC__
00076         const std::string a_where,
00077 #endif
00078         const std::string a_file,
00079         const uint16 a_line
00080         )
00081 {
00082         clear();
00083 
00084         internal_TRY_nomem(m_what = a_what);
00085 #ifdef __GNUC__
00086         internal_TRY_nomem(m_where = a_where);
00087 #endif
00088         internal_TRY_nomem(m_file = a_file);
00089         m_line = a_line;
00090 }
00091 
00092 void error_instance::set(const error_instance& a_e)
00093 {
00094         clear();
00095 
00096         internal_TRY_nomem(m_what = a_e.what());
00097 #ifdef __GNUC__
00098         internal_TRY_nomem(m_where = a_e.where());
00099 #endif
00100         internal_TRY_nomem(m_file = a_e.file());
00101         m_line = a_e.line();
00102 }
00103 
00104 const std::string error_instance::what(void) const
00105 {
00106         return(m_what);
00107 }
00108 
00109 #ifdef __GNUC__
00110 const std::string error_instance::where(void) const
00111 {
00112         return(m_where);
00113 }
00114 #endif
00115 
00116 const std::string error_instance::file(void) const
00117 {
00118         return(m_file);
00119 }
00120 
00121 const uint16 error_instance::line(void) const
00122 {
00123         return(m_line);
00124 }
00125 
00126 error_instance& error_instance::operator=(const error_instance& a_e)
00127 {
00128         set(a_e);
00129 
00130         return(*this);
00131 }
00132 
00133 /*
00134 void 
00135 error_instance::dump(std::ostream& a_out, const std::string& a_prefix) const
00136 {
00137         a_out 
00138                 << a_prefix 
00139                 << "error_instance::what = \"" 
00140                 << m_what 
00141                 << "\"" 
00142                 << std::endl;
00143 #ifdef __GNUC__
00144         a_out 
00145                 << a_prefix 
00146                 << "              ::where = " 
00147                 << m_where 
00148                 << std::endl;
00149 #endif
00150         a_out 
00151                 << a_prefix 
00152                 << "              ::at " 
00153                 << m_file << "[" << m_line << "]" 
00154                 << std::endl;
00155 }
00156 */
00157 
00158 //-----------------------------------------------------------------------------
00159 
00160 error::error(const int a_errno)
00161 {
00162         clear();
00163         num(a_errno);
00164 }
00165 
00166 error::error(
00167         const int a_errno,
00168         const error_instance& a_e, 
00169         const bool a_internal
00170         )
00171 {
00172         clear();
00173         push_back(a_e);
00174         internal(a_internal);
00175         num(a_errno);
00176 }
00177 
00178 error::error(const error& a_e)
00179 {
00180         assign(a_e);
00181 }
00182 
00183 void error::clear(void)
00184 {
00185         m_errno = 0;
00186         m_internal = false;
00187         clear_stack();
00188 }
00189 
00190 void error::clear_stack(void)
00191 {
00192         type::clear();
00193 }
00194 
00195 void error::internal(bool a_i)
00196 {
00197         m_internal = a_i;
00198 }
00199 
00200 const bool error::internal(void) const
00201 {
00202         return(m_internal);
00203 }
00204 
00205 void error::num(int a_i)
00206 {
00207         m_errno = a_i;
00208 }
00209 
00210 int error::num(void) const
00211 {
00212         return(m_errno);
00213 }
00214 
00215 void error::push_back(const error_instance& a_e)
00216 {
00217         try {
00218                 type::push_back(a_e);
00219         }
00220         catch(...) {
00221                 std::cerr << "*** ERROR: ";
00222                 if (errno != 0) {
00223                         std::cerr 
00224                                 << "[" << errno << "]: " 
00225                                 << get_error_str(errno) 
00226                                 << std::endl;
00227                         std::cerr << "           ";
00228                         errno = 0;
00229                 }
00230                 std::cerr << "error::push_back() failed" << std::endl;
00231         }
00232 }
00233 
00234 void error::push_back(const error& a_e)
00235 {
00236         error::const_iterator ei;
00237         
00238         for (ei = a_e.begin(); ei != a_e.end(); ei++) {
00239                 push_back(*ei);
00240         }
00241 }
00242 
00243 void error::push_back(const std::string& a_str)
00244 {
00245         error_instance ei;
00246 
00247         internal_TRY_nomem(ei = ERROR_INSTANCE(a_str));
00248         push_back(ei);
00249 }
00250 
00251 void error::assign(const error& a_e)
00252 {
00253         const_iterator eii;
00254 
00255         clear();
00256         m_errno = a_e.num();
00257         m_internal = a_e.internal();
00258         for (eii = a_e.begin(); eii != a_e.end(); eii++) {
00259                 push_back(*eii);
00260         }
00261 }
00262 
00263 error& error::operator=(const error& a_e)
00264 {
00265         assign(a_e);
00266 
00267         return(*this);
00268 }
00269 
00270 std::ostream&
00271         error::write(std::ostream& a_out, const std::string a_prefix) const
00272 {
00273         const_iterator eii;
00274 
00275         if (a_prefix.size() != 0)
00276                 a_out << a_prefix << " ";
00277         a_out << "*** ";
00278         if (m_internal)
00279                 a_out << "INTERNAL ";
00280         a_out << "ERROR";
00281 
00282         if (m_errno != 0)
00283                 a_out << " [" << m_errno << "]: " << strerror(m_errno);
00284         a_out << std::endl;
00285 
00286         for (eii = begin(); eii != end(); ++eii) {
00287                 if (a_prefix.size() != 0)
00288                         a_out << a_prefix << " ";
00289                 if (eii->what().size() != 0)
00290                         a_out << "    " << eii->what() << std::endl;
00291                 if (m_internal) {
00292                         a_out << "      ";
00293 #ifdef __GNUC__
00294                         a_out << "in " << eii->where() << " ";
00295 #endif
00296                         a_out << "at " << eii->file() << "[" << eii->line() << "]";
00297                         a_out << std::endl;
00298                 }
00299         }
00300 
00301         return(a_out);
00302 }
00303 
00304 const std::string error::str(const std::string a_prefix) const
00305 {
00306         static const size_t buffer_len = 32;
00307         char buffer[buffer_len] = { 0 };
00308         std::string es;
00309         const_iterator eii;
00310 
00311         try {
00312                 es.erase();
00313                 if (a_prefix.size() != 0) {
00314                         es += a_prefix;
00315                         es += " ";
00316                 }
00317                 es += "*** ";
00318                 if (m_internal)
00319                         es += "INTERNAL ";
00320                 es += "ERROR";
00321 
00322                 snprintf(buffer, buffer_len, "%d", m_errno);
00323                 if (m_errno != 0) {
00324                         es += " [";
00325                         es += buffer;
00326                         es += "]: ";
00327                         es += strerror(m_errno);
00328                 }
00329                 es += "\n";
00330 
00331                 for (eii = begin(); eii != end(); ++eii) {
00332                         if (a_prefix.size() != 0)
00333                                 es += a_prefix + " ";
00334                         if (eii->what().size() != 0) {
00335                                 es += "    ";
00336                                 es += eii->what();
00337                                 es += "\n";
00338                         }
00339                         snprintf(buffer, buffer_len, "%u", eii->line());
00340                         if (m_internal) {
00341                                 es += "      ";
00342 #ifdef __GNUC__
00343                                 es += "in ";
00344                                 es += eii->where();
00345                                 es += " ";
00346 #endif
00347                                 es += "at ";
00348                                 es += eii->file();
00349                                 es += "[";
00350                                 es += buffer;
00351                                 es += "]";
00352                                 es += "\n";
00353                         }
00354                 }
00355         }
00356         catch(...) {
00357                 if (errno == 12)
00358                         std::cerr << err_nomem;
00359                 else
00360                         std::cerr << err_unknown;
00361         }
00362 
00363         return(es);
00364 }
00365 
00366 /*
00367 std::ostream& error::dump(std::ostream& a_out) const
00368 {
00369         const_iterator eii;
00370 
00371         a_out << "ERROR: errno = " << m_errno;
00372         if (m_errno != 0) {
00373                 a_out << " \"" << strerror(m_errno) << "\"";
00374         }
00375         a_out << std::endl;
00376         for (eii = begin(); eii != end(); ++eii) {
00377                 eii->dump(a_out, "       ");
00378         }
00379 
00380         return(a_out);
00381 }
00382 */
00383 
00384 std::ostream& operator<<(std::ostream& a_out, const error& a_e)
00385 {
00386         return(a_e.write(a_out));
00387 }
00388 
00389 const char * get_error_str(const int a_err)
00390 {
00391         return(strerror(a_err));
00392 }
00393 
00394 //-----------------------------------------------------------------------------
00395 

Generated on Thu Jun 5 11:12:56 2008 for rvm by  doxygen 1.5.1