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:
00173 template <typename A, typename B, typename C,
00174 typename D, typename E, typename F>
00175 static std::string
00176 format_error (A const& context1,
00177 B const& context2,
00178 C const& context3,
00179 error_type error,
00180 D const& detail1,
00181 E const& detail2,
00182 F const& detail3);
00183
00196 template <typename A, typename B, typename C,
00197 typename D, typename E, typename F>
00198 static std::string
00199 format_error (A const& context1,
00200 B const& context2,
00201 C const& context3,
00202 std::runtime_error const& error,
00203 D const& detail1,
00204 E const& detail2,
00205 F const& detail3);
00206
00219 template <typename A, typename B, typename C,
00220 typename R, typename D, typename E, typename F>
00221 static std::string
00222 format_reason (A const& context1,
00223 B const& context2,
00224 C const& context3,
00225 R const& error,
00226 D const& detail1,
00227 E const& detail2,
00228 F const& detail3);
00229
00236 template<typename A>
00237 static void
00238 add_detail(boost::format& fmt,
00239 A const& value);
00240
00245 template<typename A, bool b>
00246 struct add_detail_helper
00247 {
00254 add_detail_helper(boost::format& fmt,
00255 A const& value)
00256 {
00257 fmt % value;
00258 }
00259 };
00260
00265 template<typename A>
00266 struct add_detail_helper<A, true>
00267 {
00274 add_detail_helper(boost::format& fmt,
00275 A const& value)
00276 {
00277 fmt % value.what();
00278 }
00279 };
00280
00287 template<typename A>
00288 static void
00289 add_reason(std::string& reason,
00290 A const& value);
00291
00296 template<typename A, bool b>
00297 struct add_reason_helper
00298 {
00305 add_reason_helper(std::string& reason,
00306 A const& value)
00307 {
00308 }
00309 };
00310
00315 template<typename A>
00316 struct add_reason_helper<A, true>
00317 {
00324 add_reason_helper(std::string& reason,
00325 A const& value)
00326 {
00327 try
00328 {
00329 sbuild::error_base const& eb(dynamic_cast<sbuild::error_base const&>(value));
00330 if (!reason.empty())
00331 reason += '\n';
00332 reason += eb.why();
00333 }
00334 catch (std::bad_cast const& discard)
00335 {
00336 }
00337 }
00338 };
00339
00340 };
00341
00342 }
00343
00344 #include "sbuild-error.tcc"
00345
00346 #endif
00347
00348
00349
00350
00351
00352