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