diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libutil/error.cc | 138 | ||||
-rw-r--r-- | src/libutil/error.hh | 361 |
2 files changed, 264 insertions, 235 deletions
diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 04da075ed..8ab4a2dea 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -3,109 +3,99 @@ #include <iostream> #include <optional> -namespace nix { +namespace nix +{ std::optional<string> ErrorInfo::programName = std::nullopt; string showErrLine(ErrLine &errLine) { - if (errLine.columnRange.has_value()) - { + if (errLine.columnRange.has_value()) { return (format("(%1%:%2%)") % errLine.lineNumber % errLine.columnRange->start).str(); - } - else - { + } else { return (format("(%1%)") % errLine.lineNumber).str(); }; } -void printCodeLines(string &prefix, NixCode &nixCode) +void printCodeLines(string &prefix, NixCode &nixCode) { - if (nixCode.errLine.has_value()) - { + if (nixCode.errLine.has_value()) { // previous line of code. - if (nixCode.errLine->prevLineOfCode.has_value()) { + if (nixCode.errLine->prevLineOfCode.has_value()) { std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errLine->lineNumber - 1) - % *nixCode.errLine->prevLineOfCode - << std::endl; + % prefix + % (nixCode.errLine->lineNumber - 1) + % *nixCode.errLine->prevLineOfCode + << std::endl; } // line of code containing the error.%2$+5d% std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errLine->lineNumber) - % nixCode.errLine->errLineOfCode - << std::endl; - - // error arrows for the column range. - if (nixCode.errLine->columnRange.has_value()) - { + % prefix + % (nixCode.errLine->lineNumber) + % nixCode.errLine->errLineOfCode + << std::endl; + + // error arrows for the column range. + if (nixCode.errLine->columnRange.has_value()) { int start = nixCode.errLine->columnRange->start; std::string spaces; - for (int i = 0; i < start; ++i) - { + for (int i = 0; i < start; ++i) { spaces.append(" "); } int len = nixCode.errLine->columnRange->len; std::string arrows; - for (int i = 0; i < len; ++i) - { + for (int i = 0; i < len; ++i) { arrows.append("^"); } - std::cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << std::endl; + std::cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << std::endl; } // next line of code. - if (nixCode.errLine->nextLineOfCode.has_value()) { + if (nixCode.errLine->nextLineOfCode.has_value()) { std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errLine->lineNumber + 1) - % *nixCode.errLine->nextLineOfCode - << std::endl; + % prefix + % (nixCode.errLine->lineNumber + 1) + % *nixCode.errLine->nextLineOfCode + << std::endl; } } } -void printErrorInfo(ErrorInfo &einfo) +void printErrorInfo(ErrorInfo &einfo) { int errwidth = 80; string prefix = " "; string levelString; - switch (einfo.level) - { - case ErrLevel::elError: - { - levelString = ANSI_RED; - levelString += "error:"; - levelString += ANSI_NORMAL; - break; - } - case ErrLevel::elWarning: - { - levelString = ANSI_YELLOW; - levelString += "warning:"; - levelString += ANSI_NORMAL; - break; - } - default: - { - levelString = (format("invalid error level: %1%") % einfo.level).str(); - break; - } + switch (einfo.level) { + case ErrLevel::elError: { + levelString = ANSI_RED; + levelString += "error:"; + levelString += ANSI_NORMAL; + break; + } + case ErrLevel::elWarning: { + levelString = ANSI_YELLOW; + levelString += "warning:"; + levelString += ANSI_NORMAL; + break; + } + default: { + levelString = (format("invalid error level: %1%") % einfo.level).str(); + break; + } } int ndl = prefix.length() + levelString.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); - int dashwidth = ndl > (errwidth - 3) ? 3 : errwidth - ndl; + int dashwidth = ndl > (errwidth - 3) ? 3 : errwidth - ndl; string dashes; for (int i = 0; i < dashwidth; ++i) @@ -113,29 +103,25 @@ void printErrorInfo(ErrorInfo &einfo) // divider. std::cout << format("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL) - % prefix - % levelString - % "---" - % einfo.name - % dashes - % einfo.programName.value_or("") - << std::endl; + % prefix + % levelString + % "---" + % einfo.name + % dashes + % einfo.programName.value_or("") + << std::endl; // filename. - if (einfo.nixCode.has_value()) - { - if (einfo.nixCode->nixFile.has_value()) - { + if (einfo.nixCode.has_value()) { + if (einfo.nixCode->nixFile.has_value()) { string eline = einfo.nixCode->errLine.has_value() - ? string(" ") + showErrLine(*einfo.nixCode->errLine) - : ""; + ? string(" ") + showErrLine(*einfo.nixCode->errLine) + : ""; - std::cout << format("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL) - % prefix % *einfo.nixCode->nixFile % eline << std::endl; + std::cout << format("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL) + % prefix % *einfo.nixCode->nixFile % eline << std::endl; std::cout << prefix << std::endl; - } - else - { + } else { std::cout << format("%1%from command line argument") % prefix << std::endl; std::cout << prefix << std::endl; } @@ -146,15 +132,13 @@ void printErrorInfo(ErrorInfo &einfo) std::cout << prefix << std::endl; // lines of code. - if (einfo.nixCode.has_value()) - { + if (einfo.nixCode.has_value()) { printCodeLines(prefix, *einfo.nixCode); std::cout << prefix << std::endl; } // hint - if (einfo.hint.has_value()) - { + if (einfo.hint.has_value()) { std::cout << prefix << *einfo.hint << std::endl; std::cout << prefix << std::endl; } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 32571d97f..70884c189 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -9,41 +9,45 @@ #include <boost/format.hpp> -namespace nix { +namespace nix +{ -typedef enum { +typedef enum { elWarning, elError } ErrLevel; -class ColumnRange { - public: - unsigned int start; - unsigned int len; +class ColumnRange +{ +public: + unsigned int start; + unsigned int len; }; class ErrorInfo; -class ErrLine { - public: - int lineNumber; - std::optional<ColumnRange> columnRange; - std::optional<string> prevLineOfCode; - string errLineOfCode; - std::optional<string> nextLineOfCode; +class ErrLine +{ +public: + int lineNumber; + std::optional<ColumnRange> columnRange; + std::optional<string> prevLineOfCode; + string errLineOfCode; + std::optional<string> nextLineOfCode; }; -class NixCode { - public: - std::optional<string> nixFile; - std::optional<ErrLine> errLine; - - ErrLine& ensureErrLine() - { - if (!this->errLine.has_value()) - this->errLine = std::optional(ErrLine()); - return *this->errLine; - } +class NixCode +{ +public: + std::optional<string> nixFile; + std::optional<ErrLine> errLine; + + ErrLine& ensureErrLine() + { + if (!this->errLine.has_value()) + this->errLine = std::optional(ErrLine()); + return *this->errLine; + } }; // ------------------------------------------------- @@ -65,149 +69,180 @@ class AddNixFile; template <class T> class AddErrLine; -template <class T> +template <class T> class AddLineNumber; -template <class T> +template <class T> class AddColumnRange; -template <class T> +template <class T> class AddLOC; // The error info class itself. -class ErrorInfo { - public: - ErrLevel level; - string name; - string description; - std::optional<NixCode> nixCode; - std::optional<string> hint; - ErrorInfo& GetEI() { return *this; } - - static std::optional<string> programName; - - // give these access to the private constructor, - // when they are direct descendants (children but not grandchildren). - friend AddName<ErrorInfo>; - friend AddDescription<ErrorInfo>; - friend AddNixCode<ErrorInfo>; - friend AddNixFile<ErrorInfo>; - friend AddErrLine<ErrorInfo>; - friend AddLineNumber<ErrorInfo>; - friend AddColumnRange<ErrorInfo>; - friend AddLOC<ErrorInfo>; - - NixCode& ensureNixCode() - { - if (!this->nixCode.has_value()) - this->nixCode = std::optional(NixCode()); - return *this->nixCode; - } - protected: - // constructor is protected, so only the builder classes can create an ErrorInfo. - ErrorInfo(ErrLevel level) { this->level = level; } +class ErrorInfo +{ +public: + ErrLevel level; + string name; + string description; + std::optional<NixCode> nixCode; + std::optional<string> hint; + ErrorInfo& GetEI() + { + return *this; + } + + static std::optional<string> programName; + + // give these access to the private constructor, + // when they are direct descendants (children but not grandchildren). + friend AddName<ErrorInfo>; + friend AddDescription<ErrorInfo>; + friend AddNixCode<ErrorInfo>; + friend AddNixFile<ErrorInfo>; + friend AddErrLine<ErrorInfo>; + friend AddLineNumber<ErrorInfo>; + friend AddColumnRange<ErrorInfo>; + friend AddLOC<ErrorInfo>; + + NixCode& ensureNixCode() + { + if (!this->nixCode.has_value()) + this->nixCode = std::optional(NixCode()); + return *this->nixCode; + } +protected: + // constructor is protected, so only the builder classes can create an ErrorInfo. + ErrorInfo(ErrLevel level) + { + this->level = level; + } }; // Init as error class EIError : public ErrorInfo { - protected: - EIError() : ErrorInfo(elError) {} +protected: + EIError() : ErrorInfo(elError) {} }; // Init as warning class EIWarning : public ErrorInfo { - protected: - EIWarning() : ErrorInfo(elWarning) {} +protected: + EIWarning() : ErrorInfo(elWarning) {} }; // Builder class definitions. template <class T> class AddName : private T { - public: - T& name(const std::string &name){ - GetEI().name = name; - return *this; - } - protected: - ErrorInfo& GetEI() { return T::GetEI(); } +public: + T& name(const std::string &name) + { + GetEI().name = name; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } }; template <class T> -class AddDescription : private T +class AddDescription : private T { - public: - T& description(const std::string &description){ - GetEI().description = description; - return *this; - } - protected: - ErrorInfo& GetEI() { return T::GetEI(); } +public: + T& description(const std::string &description) + { + GetEI().description = description; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } }; -template <class T> +template <class T> class AddNixFile : private T { - public: - T& nixFile(string filename) { - GetEI().ensureNixCode().nixFile = filename; - return *this; - } - protected: - ErrorInfo& GetEI() { return T::GetEI(); } +public: + T& nixFile(string filename) + { + GetEI().ensureNixCode().nixFile = filename; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } }; -template <class T> +template <class T> class AddLineNumber : private T { - public: - T& lineNumber(int lineNumber) { - GetEI().ensureNixCode().ensureErrLine().lineNumber = lineNumber; - return *this; - } - protected: - ErrorInfo& GetEI() { return T::GetEI(); } +public: + T& lineNumber(int lineNumber) + { + GetEI().ensureNixCode().ensureErrLine().lineNumber = lineNumber; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } }; -template <class T> +template <class T> class AddColumnRange : private T { - public: - T& columnRange(unsigned int start, unsigned int len) { - GetEI().ensureNixCode().ensureErrLine().columnRange = { start, len }; - return *this; - } - protected: - ErrorInfo& GetEI() { return T::GetEI(); } +public: + T& columnRange(unsigned int start, unsigned int len) + { + GetEI().ensureNixCode().ensureErrLine().columnRange = { start, len }; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } }; -template <class T> +template <class T> class AddLOC : private T { - public: - T& linesOfCode(std::optional<string> prevloc, string loc, std::optional<string> nextloc) { - GetEI().ensureNixCode().ensureErrLine().prevLineOfCode = prevloc; - GetEI().ensureNixCode().ensureErrLine().errLineOfCode = loc; - GetEI().ensureNixCode().ensureErrLine().nextLineOfCode = nextloc; - return *this; - } - protected: - ErrorInfo& GetEI() { return T::GetEI(); } +public: + T& linesOfCode(std::optional<string> prevloc, string loc, std::optional<string> nextloc) + { + GetEI().ensureNixCode().ensureErrLine().prevLineOfCode = prevloc; + GetEI().ensureNixCode().ensureErrLine().errLineOfCode = loc; + GetEI().ensureNixCode().ensureErrLine().nextLineOfCode = nextloc; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } }; // ---------------------------------------------------------------- -// format for hints. same as boost format, except templated values +// format for hints. same as boost format, except templated values // are always in yellow. template <class T> class yellowify { public: - yellowify(T &s) : value(s) {} - T &value; + yellowify(T &s) : value(s) {} + T &value; }; template <class T> @@ -216,69 +251,79 @@ std::ostream& operator<<(std::ostream &out, const yellowify<T> &y) return out << ANSI_YELLOW << y.value << ANSI_NORMAL; } -class hintfmt +class hintfmt { - public: - hintfmt(string format) :fmt(format) { - fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); - } - template<class T> - hintfmt& operator%(const T &value) { fmt % yellowify(value); return *this; } - - template <typename U> - friend class AddHint; - private: - format fmt; +public: + hintfmt(string format) :fmt(format) + { + fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); + } + template<class T> + hintfmt& operator%(const T &value) + { + fmt % yellowify(value); + return *this; + } + + template <typename U> + friend class AddHint; +private: + format fmt; }; // the template layer for adding a hint. -template <class T> +template <class T> class AddHint : private T { - public: - T& hint(hintfmt &hfmt) { - GetEI().hint = std::optional(hfmt.fmt.str()); - return *this; - } - T& nohint() { - GetEI().hint = std::nullopt; - return *this; - } - protected: - ErrorInfo& GetEI() { return T::GetEI(); } +public: + T& hint(hintfmt &hfmt) + { + GetEI().hint = std::optional(hfmt.fmt.str()); + return *this; + } + T& nohint() + { + GetEI().hint = std::nullopt; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } }; // -------------------------------------------------------- // error types typedef AddName< - AddDescription< - AddHint< - EIError>>> ProgramError; +AddDescription< +AddHint< +EIError>>> ProgramError; typedef AddName< - AddDescription< - AddHint< - EIWarning>>> ProgramWarning; +AddDescription< +AddHint< +EIWarning>>> ProgramWarning; typedef AddName< - AddDescription< - AddNixFile< - AddLineNumber< - AddColumnRange< - AddLOC< - AddHint< - EIError>>>>>>> NixLangError; +AddDescription< +AddNixFile< +AddLineNumber< +AddColumnRange< +AddLOC< +AddHint< +EIError>>>>>>> NixLangError; typedef AddName< - AddDescription< - AddNixFile< - AddLineNumber< - AddColumnRange< - AddLOC< - AddHint< - EIWarning>>>>>>> NixLangWarning; +AddDescription< +AddNixFile< +AddLineNumber< +AddColumnRange< +AddLOC< +AddHint< +EIWarning>>>>>>> NixLangWarning; // -------------------------------------------------------- |