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:
00114 typedef T error_type;
00115 typedef std::map<error_type,const char *> map_type;
00116
00122 error(std::string const& error):
00123 error_base(error)
00124 {
00125 }
00126
00133 error(std::string const& error,
00134 std::string const& reason):
00135 error_base(error, reason)
00136 {
00137 }
00138
00140 virtual ~error () throw ()
00141 {}
00142
00143 private:
00145 static map_type error_strings;
00146
00153 static const char *
00154 get_error (error_type error);
00155
00156 protected:
00168 template <typename A, typename B, typename C, typename D, typename E>
00169 static std::string
00170 format_error (A const& context1,
00171 B const& context2,
00172 C const& context3,
00173 error_type error,
00174 D const& detail1,
00175 E const& detail2);
00176
00188 template <typename A, typename B, typename C, typename D, typename E>
00189 static std::string
00190 format_error (A const& context1,
00191 B const& context2,
00192 C const& context3,
00193 std::runtime_error const& error,
00194 D const& detail1,
00195 E const& detail2);
00196
00208 template <typename A, typename B, typename C, typename R, typename D, typename E>
00209 static std::string
00210 format_reason (A const& context1,
00211 B const& context2,
00212 C const& context3,
00213 R const& error,
00214 D const& detail1,
00215 E const& detail2);
00216
00223 template<typename A>
00224 static void
00225 add_detail(boost::format& fmt,
00226 A const& value);
00227
00232 template<typename A, bool b>
00233 struct add_detail_helper
00234 {
00235 add_detail_helper(boost::format& fmt,
00236 A const& value)
00237 {
00238 fmt % value;
00239 }
00240 };
00241
00246 template<typename A>
00247 struct add_detail_helper<A, true>
00248 {
00249 add_detail_helper(boost::format& fmt,
00250 A const& value)
00251 {
00252 fmt % value.what();
00253 }
00254 };
00255
00262 template<typename A>
00263 static void
00264 add_reason(std::string& reason,
00265 A const& value);
00266
00271 template<typename A, bool b>
00272 struct add_reason_helper
00273 {
00274 add_reason_helper(std::string& reason,
00275 A const& value)
00276 {
00277 }
00278 };
00279
00284 template<typename A>
00285 struct add_reason_helper<A, true>
00286 {
00287 add_reason_helper(std::string& reason,
00288 A const& value)
00289 {
00290 try
00291 {
00292 sbuild::error_base const& eb(dynamic_cast<sbuild::error_base const&>(value));
00293 if (!reason.empty())
00294 reason += '\n';
00295 reason += eb.why();
00296 }
00297 catch (std::bad_cast const& discard)
00298 {
00299 }
00300 }
00301 };
00302
00303 };
00304
00305 }
00306
00307 #include "sbuild-error.tcc"
00308
00309 #endif
00310
00311
00312
00313
00314
00315