diff options
author | Ben Burdette <bburdette@gmail.com> | 2020-04-21 13:25:41 -0600 |
---|---|---|
committer | Ben Burdette <bburdette@gmail.com> | 2020-04-21 13:25:41 -0600 |
commit | d3052197feababc312fd874e08ae48050d985eb3 (patch) | |
tree | d82b94bb3478f59e60b4df5dcd5dddc554697771 /src/libutil | |
parent | 15e9564fd1e11b3797f0188a494aa66d4622dfb0 (diff) |
add ErrorInfo to BaseError
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/error.cc | 2 | ||||
-rw-r--r-- | src/libutil/error.hh | 122 | ||||
-rw-r--r-- | src/libutil/fmt.hh | 127 | ||||
-rw-r--r-- | src/libutil/logging.hh | 1 | ||||
-rw-r--r-- | src/libutil/types.hh | 125 | ||||
-rw-r--r-- | src/libutil/util.hh | 1 |
6 files changed, 192 insertions, 186 deletions
diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 0e07c0d98..41595b0df 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -1,4 +1,4 @@ -#include "error.hh" +#include "types.hh" #include <iostream> #include <optional> diff --git a/src/libutil/error.hh b/src/libutil/error.hh deleted file mode 100644 index 63778ebda..000000000 --- a/src/libutil/error.hh +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef error_hh -#define error_hh - -#include "ansicolor.hh" -#include <string> -#include <optional> -#include <iostream> -#include "types.hh" - -namespace nix -{ - -typedef enum { - lvlError = 0, - lvlWarn, - lvlInfo, - lvlTalkative, - lvlChatty, - lvlDebug, - lvlVomit -} Verbosity; - -struct ErrPos -{ - int line; - int column; - string file; - - template <class P> - ErrPos& operator=(const P &pos) - { - line = pos.line; - column = pos.column; - file = pos.file; - return *this; - } - - template <class P> - ErrPos(const P &p) - { - *this = p; - } -}; - -struct NixCode -{ - ErrPos errPos; - std::optional<string> prevLineOfCode; - string errLineOfCode; - std::optional<string> nextLineOfCode; -}; - -// ---------------------------------------------------------------- -// format function for hints. same as fmt, except templated values -// are always in yellow. - -template <class T> -struct yellowify -{ - yellowify(T &s) : value(s) {} - T &value; -}; - -template <class T> -std::ostream& operator<<(std::ostream &out, const yellowify<T> &y) -{ - return out << ANSI_YELLOW << y.value << ANSI_NORMAL; -} - -class hintformat -{ -public: - hintformat(string format) :fmt(format) - { - fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); - } - template<class T> - hintformat& operator%(const T &value) - { - fmt % yellowify(value); - return *this; - } - - std::string str() const - { - return fmt.str(); - } - - template <typename U> - friend class AddHint; -private: - format fmt; -}; - -std::ostream& operator<<(std::ostream &os, const hintformat &hf); - -template<typename... Args> -inline hintformat hintfmt(const std::string & fs, const Args & ... args) -{ - hintformat f(fs); - formatHelper(f, args...); - return f; -} - -// ------------------------------------------------- -// ErrorInfo. -struct ErrorInfo -{ - Verbosity level; - string name; - string description; - std::optional<hintformat> hint; - std::optional<NixCode> nixCode; - - static std::optional<string> programName; -}; - -std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); - -} - -#endif diff --git a/src/libutil/fmt.hh b/src/libutil/fmt.hh new file mode 100644 index 000000000..08edffee0 --- /dev/null +++ b/src/libutil/fmt.hh @@ -0,0 +1,127 @@ +#pragma once + +#include <boost/format.hpp> +#include <string> +#include "ansicolor.hh" + + +namespace nix { + + +/* Inherit some names from other namespaces for convenience. */ +using std::string; +using boost::format; + + +/* A variadic template that does nothing. Useful to call a function + for all variadic arguments but ignoring the result. */ +struct nop { template<typename... T> nop(T...) {} }; + + +struct FormatOrString +{ + string s; + FormatOrString(const string & s) : s(s) { }; + template<class F> + FormatOrString(const F & f) : s(f.str()) { }; + FormatOrString(const char * s) : s(s) { }; +}; + + +/* A helper for formatting strings. ‘fmt(format, a_0, ..., a_n)’ is + equivalent to ‘boost::format(format) % a_0 % ... % + ... a_n’. However, ‘fmt(s)’ is equivalent to ‘s’ (so no %-expansion + takes place). */ + +template<class F> +inline void formatHelper(F & f) +{ +} + +template<class F, typename T, typename... Args> +inline void formatHelper(F & f, const T & x, const Args & ... args) +{ + formatHelper(f % x, args...); +} + +inline std::string fmt(const std::string & s) +{ + return s; +} + +inline std::string fmt(const char * s) +{ + return s; +} + +inline std::string fmt(const FormatOrString & fs) +{ + return fs.s; +} + +template<typename... Args> +inline std::string fmt(const std::string & fs, const Args & ... args) +{ + boost::format f(fs); + f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); + formatHelper(f, args...); + return f.str(); +} + +// ----------------------------------------------------------------------------- +// format function for hints in errors. same as fmt, except templated values +// are always in yellow. + +template <class T> +struct yellowify +{ + yellowify(T &s) : value(s) {} + T &value; +}; + +template <class T> +std::ostream& operator<<(std::ostream &out, const yellowify<T> &y) +{ + return out << ANSI_YELLOW << y.value << ANSI_NORMAL; +} + +class hintformat +{ +public: + hintformat(const string &format) :fmt(format) + { + fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); + } + template<class T> + hintformat& operator%(const T &value) + { + fmt % yellowify(value); + return *this; + } + hintformat(const hintformat &hf) + : fmt(hf.fmt) + {} + + + std::string str() const + { + return fmt.str(); + } + + template <typename U> + friend class AddHint; +private: + format fmt; +}; + +std::ostream& operator<<(std::ostream &os, const hintformat &hf); + +template<typename... Args> +inline hintformat hintfmt(const std::string & fs, const Args & ... args) +{ + hintformat f(fs); + formatHelper(f, args...); + return f; +} + +} diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index ba6f39ac9..8269e2e1a 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -1,7 +1,6 @@ #pragma once #include "types.hh" -#include "error.hh" namespace nix { diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 981af528b..633c6bdf7 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -3,13 +3,13 @@ #include "ref.hh" -#include <string> #include <list> #include <set> #include <memory> #include <map> +#include <optional> -#include <boost/format.hpp> +#include "fmt.hh" /* Before 4.7, gcc's std::exception uses empty throw() specifiers for * its (virtual) destructor and what() in c++11 mode, in violation of spec @@ -20,73 +20,66 @@ #endif #endif - namespace nix { - -/* Inherit some names from other namespaces for convenience. */ -using std::string; using std::list; using std::set; using std::vector; -using boost::format; - - -/* A variadic template that does nothing. Useful to call a function - for all variadic arguments but ignoring the result. */ -struct nop { template<typename... T> nop(T...) {} }; - -struct FormatOrString +typedef enum { + lvlError = 0, + lvlWarn, + lvlInfo, + lvlTalkative, + lvlChatty, + lvlDebug, + lvlVomit +} Verbosity; + +struct ErrPos { - string s; - FormatOrString(const string & s) : s(s) { }; - template<class F> - FormatOrString(const F & f) : s(f.str()) { }; - FormatOrString(const char * s) : s(s) { }; -}; - - -/* A helper for formatting strings. ‘fmt(format, a_0, ..., a_n)’ is - equivalent to ‘boost::format(format) % a_0 % ... % - ... a_n’. However, ‘fmt(s)’ is equivalent to ‘s’ (so no %-expansion - takes place). */ + int line; + int column; + string file; -template<class F> -inline void formatHelper(F & f) -{ -} - -template<class F, typename T, typename... Args> -inline void formatHelper(F & f, const T & x, const Args & ... args) -{ - formatHelper(f % x, args...); -} + template <class P> + ErrPos& operator=(const P &pos) + { + line = pos.line; + column = pos.column; + file = pos.file; + return *this; + } -inline std::string fmt(const std::string & s) -{ - return s; -} + template <class P> + ErrPos(const P &p) + { + *this = p; + } +}; -inline std::string fmt(const char * s) +struct NixCode { - return s; -} + ErrPos errPos; + std::optional<string> prevLineOfCode; + string errLineOfCode; + std::optional<string> nextLineOfCode; +}; -inline std::string fmt(const FormatOrString & fs) +// ------------------------------------------------- +// ErrorInfo. +struct ErrorInfo { - return fs.s; -} + Verbosity level; + string name; + string description; + std::optional<hintformat> hint; + std::optional<NixCode> nixCode; -template<typename... Args> -inline std::string fmt(const std::string & fs, const Args & ... args) -{ - boost::format f(fs); - f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); - formatHelper(f, args...); - return f.str(); -} + static std::optional<string> programName; +}; +std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); /* BaseError should generally not be caught, as it has Interrupted as a subclass. Catch Error instead. */ @@ -94,33 +87,42 @@ class BaseError : public std::exception { protected: string prefix_; // used for location traces etc. - string err; + ErrorInfo err; public: unsigned int status = 1; // exit status template<typename... Args> BaseError(unsigned int status, const Args & ... args) - : err(fmt(args...)) + : err(hintfmt(args...)) , status(status) { } template<typename... Args> BaseError(const Args & ... args) - : err(fmt(args...)) + : err { .level = lvlError, + .hint = hintfmt(args...) + } + { + } + + BaseError(ErrorInfo e) + : err(e) { } #ifdef EXCEPTION_NEEDS_THROW_SPEC ~BaseError() throw () { }; - const char * what() const throw () { return err.c_str(); } + const char * what() const throw () { return err.description.c_str(); } #else - const char * what() const noexcept { return err.c_str(); } + const char * what() const noexcept { return err.description.c_str(); } #endif - const string & msg() const { return err; } + const string & msg() const { return err.description; } const string & prefix() const { return prefix_; } BaseError & addPrefix(const FormatOrString & fs); + + const ErrorInfo & info() const { return err; } }; #define MakeError(newClass, superClass) \ @@ -139,7 +141,8 @@ public: template<typename... Args> SysError(const Args & ... args) - : Error(addErrno(fmt(args...))) + : Error(args...) // TODO addErrNo for hintfmt + // : Error(addErrno(hintfmt(args...))) { } private: diff --git a/src/libutil/util.hh b/src/libutil/util.hh index fb9a7ed38..636f3ba6c 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -3,7 +3,6 @@ #include "types.hh" #include "logging.hh" #include "ansicolor.hh" -#include "error.hh" #include <sys/types.h> #include <sys/stat.h> |