00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef SBUILD_ERROR_H
00021 #define SBUILD_ERROR_H
00022
00023 #include <map>
00024 #include <stdexcept>
00025 #include <string>
00026 #include <typeinfo>
00027
00028 #include <boost/format.hpp>
00029 #include <boost/type_traits.hpp>
00030
00031 namespace sbuild
00032 {
00033
00037 class error_base : public std::runtime_error
00038 {
00039 protected:
00045 error_base(std::string const& error):
00046 runtime_error(error),
00047 reason()
00048 {
00049 }
00050
00057 error_base(std::string const& error,
00058 std::string const& reason):
00059 runtime_error(error),
00060 reason(reason)
00061 {
00062 }
00063
00064 public:
00066 virtual ~error_base () throw ()
00067 {}
00068
00074 virtual const char *
00075 why () const throw ()
00076 {
00077 return this->reason.c_str();
00078 }
00079
00085 std::string const&
00086 get_reason () const
00087 {
00088 return this->reason;
00089 }
00090
00096 void
00097 set_reason (std::string const& reason)
00098 {
00099 this->reason = reason;
00100 }
00101
00102 private:
00104 std::string reason;
00105 };
00106
00110 template <typename T>
00111 class error : public error_base
00112 {
00113 public:
00115 typedef T error_type;
00117 typedef std::map<error_type,const char *> map_type;
00118
00124 error(std::string const& error):
00125 error_base(error)
00126 {
00127 }
00128
00135 error(std::string const& error,
00136 std::string const& reason):
00137 error_base(error, reason)
00138 {
00139 }
00140
00142 virtual ~error () throw ()
00143 {}
00144
00145 private:
00147 static map_type error_strings;
00148
00155 static const char *
00156 get_error (error_type error);
00157
00158 protected:
00173 template <typename A, typename B, typename C, typename D, typename E>
00174 static std::string
00175 format_error (A const& context1,
00176 B const& context2,
00177 C const& context3,
00178 error_type error,
00179 D const& detail1,
00180 E const& detail2);
00181
00193 template <typename A, typename B, typename C, typename D, typename E>
00194 static std::string
00195 format_error (A const& context1,
00196 B const& context2,
00197 C const& context3,
00198 std::runtime_error const& error,
00199 D const& detail1,
00200 E const& detail2);
00201
00213 template <typename A, typename B, typename C, typename R, typename D, typename E>
00214 static std::string
00215 format_reason (A const& context1,
00216 B const& context2,
00217 C const& context3,
00218 R const& error,
00219 D const& detail1,
00220 E const& detail2);
00221
00228 template<typename A>
00229 static void
00230 add_detail(boost::format& fmt,
00231 A const& value);
00232
00237 template<typename A, bool b>
00238 struct add_detail_helper
00239 {
00246 add_detail_helper(boost::format& fmt,
00247 A const& value)
00248 {
00249 fmt % value;
00250 }
00251 };
00252
00257 template<typename A>
00258 struct add_detail_helper<A, true>
00259 {
00266 add_detail_helper(boost::format& fmt,
00267 A const& value)
00268 {
00269 fmt % value.what();
00270 }
00271 };
00272
00279 template<typename A>
00280 static void
00281 add_reason(std::string& reason,
00282 A const& value);
00283
00288 template<typename A, bool b>
00289 struct add_reason_helper
00290 {
00297 add_reason_helper(std::string& reason,
00298 A const& value)
00299 {
00300 }
00301 };
00302
00307 template<typename A>
00308 struct add_reason_helper<A, true>
00309 {
00316 add_reason_helper(std::string& reason,
00317 A const& value)
00318 {
00319 try
00320 {
00321 sbuild::error_base const& eb(dynamic_cast<sbuild::error_base const&>(value));
00322 if (!reason.empty())
00323 reason += '\n';
00324 reason += eb.why();
00325 }
00326 catch (std::bad_cast const& discard)
00327 {
00328 }
00329 }
00330 };
00331
00332 };
00333
00334 }
00335
00336 #include "sbuild-error.tcc"
00337
00338 #endif
00339
00340
00341
00342
00343
00344