From ec449c845056dad43eeec4d6ff983002f038cf69 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 6 Apr 2020 19:43:22 -0600 Subject: [PATCH 1/8] constructor style basically working --- src/error-demo/error-demo.cc | 71 +++++---- src/libutil/error.cc | 42 ++++- src/libutil/error.hh | 289 +++++++++++++++++------------------ 3 files changed, 222 insertions(+), 180 deletions(-) diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 8fb20d38c..fdb574b25 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -22,21 +22,25 @@ int main() // created. // ProgramError takes name, description, and an optional hint. - printErrorInfo( ProgramError() - .name("name") - .description("error description") - .nohint() - ); + printErrorInfo( + ErrorInfo::ProgramError("name", + "error description", + std::nullopt)); // ProgramWarning takes name, description, and an optional hint. // The hint is in the form of a hintfmt class, which wraps boost::format(), // and makes all the substituted text yellow. - printErrorInfo( ProgramWarning() - .name("warning name") - .description("warning description") - // the templated value, 'warning', is automatically colored yellow. - .hint(hintfmt("there was a %1%", "warning")) - ); + printErrorInfo( + ErrorInfo::ProgramWarning("name", + "warning description", + std::optional(hintfmt("there was a %1%", "warning")))); + + // printErrorInfo( ProgramWarning() + // .name("warning name") + // .description("warning description") + // // the templated value, 'warning', is automatically colored yellow. + // .hint(hintfmt("there was a %1%", "warning")) + // ); /* // some invalid errors: @@ -63,25 +67,34 @@ int main() SymbolTable testTable; auto problem_symbol = testTable.create("problem"); - printErrorInfo(NixLangWarning() - .name("warning name") - .description("warning description") - .pos(Pos(problem_symbol, 40, 13)) - .linesOfCode(std::nullopt, - "this is the problem line of code", - std::nullopt) - .hint(hintfmt("this hint has %1% templated %2%!!", "yellow" , "values"))); + printErrorInfo(ErrorInfo::NixLangWarning( + "warning name", + "warning description", + Pos(problem_symbol, 40, 13), + std::nullopt, + "this is the problem line of code", + std::nullopt, + hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); + + // // NixLangError is just the same as NixLangWarning, except for the Error + // // flag. + // printErrorInfo(NixLangError() + // .name("error name") + // .description("error description") + // .pos(Pos(problem_symbol, 40, 13)) + // .linesOfCode(std::optional("previous line of code"), + // "this is the problem line of code", + // std::optional("next line of code")) + // .hint(hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); + printErrorInfo(ErrorInfo::NixLangError( + "error name", + "error description", + Pos(problem_symbol, 40, 13), + std::optional("previous line of code"), + "this is the problem line of code", + std::optional("next line of code"), + hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); - // NixLangError is just the same as NixLangWarning, except for the Error - // flag. - printErrorInfo(NixLangError() - .name("error name") - .description("error description") - .pos(Pos(problem_symbol, 40, 13)) - .linesOfCode(std::optional("previous line of code"), - "this is the problem line of code", - std::optional("next line of code")) - .hint(hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); return 0; } diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 8ab4a2dea..41fabbbcf 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -8,7 +8,43 @@ namespace nix std::optional ErrorInfo::programName = std::nullopt; -string showErrLine(ErrLine &errLine) +ErrorInfo ErrorInfo::ProgramError(const string &name, + const string &description, + const std::optional &hf) +{ + return ProgramEI(elError, name, description, hf); +} + +ErrorInfo ErrorInfo::ProgramWarning(const string &name, + const string &description, + const std::optional &hf) +{ + return ProgramEI(elWarning, name, description, hf); +} + + + +ErrorInfo ErrorInfo::ProgramEI(ErrLevel level, + const string &name, + const string &description, + const std::optional &hf) +{ + ErrorInfo ei(elError); + ei.name = name; + ei.description = description; + if (hf.has_value()) + ei.hint = std::optional(hf->str()); + else + ei.hint = std::nullopt; + return ei; +} + + + + + + +string showErrLine(const ErrLine &errLine) { if (errLine.columnRange.has_value()) { return (format("(%1%:%2%)") % errLine.lineNumber % errLine.columnRange->start).str(); @@ -17,7 +53,7 @@ string showErrLine(ErrLine &errLine) }; } -void printCodeLines(string &prefix, NixCode &nixCode) +void printCodeLines(const string &prefix, const NixCode &nixCode) { if (nixCode.errLine.has_value()) { @@ -69,7 +105,7 @@ void printCodeLines(string &prefix, NixCode &nixCode) } -void printErrorInfo(ErrorInfo &einfo) +void printErrorInfo(const ErrorInfo &einfo) { int errwidth = 80; string prefix = " "; diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 57a9944be..a73b6639e 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -41,153 +41,8 @@ class NixCode public: std::optional nixFile; std::optional errLine; - - ErrLine& ensureErrLine() - { - if (!this->errLine.has_value()) - this->errLine = std::optional(ErrLine()); - return *this->errLine; - } }; -// ------------------------------------------------- -// ErrorInfo. - -// Forward friend class declarations. "builder classes" -template -class AddName; - -template -class AddDescription; - -template -class AddPos; - -template -class AddLOC; - -// The error info class itself. -class ErrorInfo -{ -public: - ErrLevel level; - string name; - string description; - std::optional nixCode; - std::optional hint; - ErrorInfo& GetEI() - { - return *this; - } - - static std::optional programName; - - // give these access to the private constructor, - // when they are direct descendants (children but not grandchildren). - friend AddName; - friend AddDescription; - friend AddPos; - friend AddLOC; - - 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) {} -}; - -// Init as warning -class EIWarning : public ErrorInfo -{ -protected: - EIWarning() : ErrorInfo(elWarning) {} -}; - -// Builder class definitions. -template -class AddName : private T -{ -public: - T& name(const std::string &name) - { - GetEI().name = name; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; - -template -class AddDescription : private T -{ -public: - T& description(const std::string &description) - { - GetEI().description = description; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; - -template -class AddPos : private T -{ -public: - template - T& pos(const P &aPos) - { - GetEI().ensureNixCode().nixFile = aPos.file; - GetEI().ensureNixCode().ensureErrLine().lineNumber = aPos.line; - GetEI().ensureNixCode().ensureErrLine().columnRange = { .start = aPos.column, .len = 1 }; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; - -template -class AddLOC : private T -{ -public: - T& linesOfCode(std::optional prevloc, string loc, std::optional 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 fmt, except templated values // are always in yellow. @@ -229,7 +84,6 @@ public: friend class AddHint; private: format fmt; - }; template @@ -240,6 +94,143 @@ inline hintformat hintfmt(const std::string & fs, const Args & ... args) return f; } +// ------------------------------------------------- +// ErrorInfo. +class ErrorInfo +{ +public: + ErrLevel level; + string name; + string description; + std::optional nixCode; + std::optional hint; + + static std::optional programName; + + static ErrorInfo ProgramError(const string &name, + const string &description, + const std::optional &hf); + + + static ErrorInfo ProgramWarning(const string &name, + const string &description, + const std::optional &hf); + + + template + static ErrorInfo NixLangError(const string &name, + const string &description, + const P &pos, + std::optional prevloc, + string loc, + std::optional nextloc, + const std::optional &hf) + { + return NixLangEI(elError, name, description, pos, prevloc, loc, nextloc, hf); + } + + + template + static ErrorInfo NixLangWarning(const string &name, + const string &description, + const P &pos, + std::optional prevloc, + string loc, + std::optional nextloc, + const std::optional &hf) + { + return NixLangEI(elWarning, name, description, pos, prevloc, loc, nextloc, hf); + } + + + +private: + template + static ErrorInfo NixLangEI(ErrLevel level, + const string &name, + const string &description, + const P &pos, + std::optional prevloc, + string loc, + std::optional nextloc, + const std::optional &hf) + { + ErrorInfo ei(level); + ei.name = name; + ei.description = description; + if (hf.has_value()) + ei.hint = std::optional(hf->str()); + else + ei.hint = std::nullopt; + + ErrLine errline; + errline.lineNumber = pos.line; + errline.columnRange = { .start = pos.column, .len = 1 }; + errline.prevLineOfCode = prevloc; + errline.errLineOfCode = loc; + errline.nextLineOfCode = nextloc; + NixCode nixcode; + nixcode.nixFile = pos.file; + nixcode.errLine = std::optional(errline); + ei.nixCode = std::optional(nixcode); + + return ei; + } + + static ErrorInfo ProgramEI(ErrLevel level, + const string &name, + const string &description, + const std::optional &hf); + + + + // constructor is protected, so only the builder classes can create an ErrorInfo. + ErrorInfo(ErrLevel level) + { + this->level = level; + } +}; + +/* +template +class AddPos : private T +{ +public: + template + T& pos(const P &aPos) + { + GetEI().ensureNixCode().nixFile = aPos.file; + GetEI().ensureNixCode().ensureErrLine().lineNumber = aPos.line; + GetEI().ensureNixCode().ensureErrLine().columnRange = { .start = aPos.column, .len = 1 }; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } +}; + +template +class AddLOC : private T +{ +public: + T& linesOfCode(std::optional prevloc, string loc, std::optional nextloc) + { + GetEI().ensureNixCode().ensureErrLine().prevLineOfCode = prevloc; + GetEI().ensureNixCode().ensureErrLine().errLineOfCode = loc; + GetEI().ensureNixCode().ensureErrLine().nextLineOfCode = nextloc; + return *this; + } +protected: + ErrorInfo& GetEI() + { + return T::GetEI(); + } +}; +*/ + +/* // the template layer for adding a hint. template class AddHint : private T @@ -261,11 +252,12 @@ protected: return T::GetEI(); } }; +*/ // -------------------------------------------------------- // error types -typedef AddName< +/*typedef AddName< AddDescription< AddHint< EIError>>> ProgramError; @@ -290,11 +282,12 @@ typedef AddName< EIWarning>>>>> NixLangWarning; +*/ // -------------------------------------------------------- // error printing // just to cout for now. -void printErrorInfo(ErrorInfo &einfo); +void printErrorInfo(const ErrorInfo &einfo); } From 55c96b64e4de2b7e3443124bb0aa17ecc9188940 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 6 Apr 2020 20:14:48 -0600 Subject: [PATCH 2/8] comment cleanup --- src/error-demo/error-demo.cc | 84 +++++++++----------------------- src/libutil/error.hh | 92 ------------------------------------ 2 files changed, 23 insertions(+), 153 deletions(-) diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index fdb574b25..ef8b56308 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -11,15 +11,10 @@ int main() // In each program where errors occur, this has to be set. ErrorInfo::programName = std::optional("error-demo"); - // There are currently four error types: + // There are currently four constructor functions: // // ProgramError, ProgramWarning, NixLangError, NixLangWarning. // - // Each error type is created with a specific sequence of builder functions. - // Unlike with a constructor, each parameter is clearly named. - // If the sequence of function calls isn't followed, then there's a type - // error. This should make for a consistent look in the code when errors are - // created. // ProgramError takes name, description, and an optional hint. printErrorInfo( @@ -33,68 +28,35 @@ int main() printErrorInfo( ErrorInfo::ProgramWarning("name", "warning description", - std::optional(hintfmt("there was a %1%", "warning")))); - - // printErrorInfo( ProgramWarning() - // .name("warning name") - // .description("warning description") - // // the templated value, 'warning', is automatically colored yellow. - // .hint(hintfmt("there was a %1%", "warning")) - // ); - - /* - // some invalid errors: - - // type error: no hint function. - ProgramError() - .name("name") - .description("error description"); - - // type error: description before name. - ProgramError() - .description("error description") - .name("name") - .nohint(); - - // type error: hint function with regular boost format, not special - hintfmt. ProgramError() .description("error description") .name("name") - .hint(format("there was a %1%") % "warning"); - */ + std::optional( + hintfmt("there was a %1%", "warning")))); // NixLangWarning adds nix file, line number, column range, and the lines of // code where a warning occurred. - SymbolTable testTable; auto problem_symbol = testTable.create("problem"); - printErrorInfo(ErrorInfo::NixLangWarning( - "warning name", - "warning description", - Pos(problem_symbol, 40, 13), - std::nullopt, - "this is the problem line of code", - std::nullopt, - hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); - - // // NixLangError is just the same as NixLangWarning, except for the Error - // // flag. - // printErrorInfo(NixLangError() - // .name("error name") - // .description("error description") - // .pos(Pos(problem_symbol, 40, 13)) - // .linesOfCode(std::optional("previous line of code"), - // "this is the problem line of code", - // std::optional("next line of code")) - // .hint(hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); - printErrorInfo(ErrorInfo::NixLangError( - "error name", - "error description", - Pos(problem_symbol, 40, 13), - std::optional("previous line of code"), - "this is the problem line of code", - std::optional("next line of code"), - hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); + printErrorInfo( + ErrorInfo::NixLangWarning( + "warning name", + "warning description", + Pos(problem_symbol, 40, 13), + std::nullopt, + "this is the problem line of code", + std::nullopt, + hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); + // NixLangError is just the same as NixLangWarning, except for the Error + // flag. + printErrorInfo( + ErrorInfo::NixLangError( + "error name", + "error description", + Pos(problem_symbol, 40, 13), + std::optional("previous line of code"), + "this is the problem line of code", + std::optional("next line of code"), + hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); return 0; } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index a73b6639e..a8a1afbca 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -191,98 +191,6 @@ private: } }; -/* -template -class AddPos : private T -{ -public: - template - T& pos(const P &aPos) - { - GetEI().ensureNixCode().nixFile = aPos.file; - GetEI().ensureNixCode().ensureErrLine().lineNumber = aPos.line; - GetEI().ensureNixCode().ensureErrLine().columnRange = { .start = aPos.column, .len = 1 }; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; - -template -class AddLOC : private T -{ -public: - T& linesOfCode(std::optional prevloc, string loc, std::optional nextloc) - { - GetEI().ensureNixCode().ensureErrLine().prevLineOfCode = prevloc; - GetEI().ensureNixCode().ensureErrLine().errLineOfCode = loc; - GetEI().ensureNixCode().ensureErrLine().nextLineOfCode = nextloc; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; -*/ - -/* -// the template layer for adding a hint. -template -class AddHint : private T -{ -public: - T& hint(const hintformat &hf) - { - GetEI().hint = std::optional(hf.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; - -typedef AddName< - AddDescription< - AddHint< - EIWarning>>> ProgramWarning; - -typedef AddName< - AddDescription< - AddPos< - AddLOC< - AddHint< - EIError>>>>> NixLangError; - -typedef AddName< - AddDescription< - AddPos< - AddLOC< - AddHint< - EIWarning>>>>> NixLangWarning; - - -*/ // -------------------------------------------------------- // error printing From 00c507cc52ceb0d879c43e88e70de0028ff47fc6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 7 Apr 2020 14:36:32 -0600 Subject: [PATCH 3/8] columnRange -> column --- src/libutil/error.cc | 14 +++++--------- src/libutil/error.hh | 13 ++++--------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 41fabbbcf..db8821a5c 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -46,8 +46,8 @@ ErrorInfo ErrorInfo::ProgramEI(ErrLevel level, string showErrLine(const ErrLine &errLine) { - if (errLine.columnRange.has_value()) { - return (format("(%1%:%2%)") % errLine.lineNumber % errLine.columnRange->start).str(); + if (errLine.column > 0) { + return (format("(%1%:%2%)") % errLine.lineNumber % errLine.column).str(); } else { return (format("(%1%)") % errLine.lineNumber).str(); }; @@ -74,18 +74,14 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) << std::endl; // error arrows for the column range. - if (nixCode.errLine->columnRange.has_value()) { - int start = nixCode.errLine->columnRange->start; + if (nixCode.errLine->column > 0) { + int start = nixCode.errLine->column; std::string spaces; 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) { - arrows.append("^"); - } + std::string arrows("^"); std::cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << std::endl; } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index a8a1afbca..e3bb2c1dd 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -17,20 +17,13 @@ typedef enum { elError } ErrLevel; -class ColumnRange -{ -public: - unsigned int start; - unsigned int len; -}; - class ErrorInfo; class ErrLine { public: int lineNumber; - std::optional columnRange; + int column; std::optional prevLineOfCode; string errLineOfCode; std::optional nextLineOfCode; @@ -107,6 +100,8 @@ public: static std::optional programName; + ErrorInfo& set_name(const string &name) { this->name = name; return *this; } + static ErrorInfo ProgramError(const string &name, const string &description, const std::optional &hf); @@ -165,7 +160,7 @@ private: ErrLine errline; errline.lineNumber = pos.line; - errline.columnRange = { .start = pos.column, .len = 1 }; + errline.column = pos.column; errline.prevLineOfCode = prevloc; errline.errLineOfCode = loc; errline.nextLineOfCode = nextloc; From 47ed067d45d3de7786cdb55f187b0db2eb6289c1 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 8 Apr 2020 09:07:58 -0600 Subject: [PATCH 4/8] initializer style --- src/error-demo/error-demo.cc | 22 +++--- src/libutil/error.cc | 85 ++++++--------------- src/libutil/error.hh | 144 +++++++++++++---------------------- 3 files changed, 91 insertions(+), 160 deletions(-) diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index ef8b56308..7eef0b162 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -18,22 +18,26 @@ int main() // ProgramError takes name, description, and an optional hint. printErrorInfo( - ErrorInfo::ProgramError("name", - "error description", - std::nullopt)); + ErrorInfo { .level = elError, + .name = "name", + .description = "error description", + }); // ProgramWarning takes name, description, and an optional hint. // The hint is in the form of a hintfmt class, which wraps boost::format(), // and makes all the substituted text yellow. printErrorInfo( - ErrorInfo::ProgramWarning("name", - "warning description", - std::optional( - hintfmt("there was a %1%", "warning")))); + ErrorInfo { .level = elWarning, + .name = "name", + .description = "error description", + .hint = std::optional( + hintfmt("there was a %1%", "warning")) + }); + // NixLangWarning adds nix file, line number, column range, and the lines of // code where a warning occurred. - SymbolTable testTable; +/* SymbolTable testTable; auto problem_symbol = testTable.create("problem"); printErrorInfo( @@ -58,5 +62,5 @@ int main() std::optional("next line of code"), hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); - return 0; +*/ return 0; } diff --git a/src/libutil/error.cc b/src/libutil/error.cc index db8821a5c..24ed4df2e 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -8,74 +8,37 @@ namespace nix std::optional ErrorInfo::programName = std::nullopt; -ErrorInfo ErrorInfo::ProgramError(const string &name, - const string &description, - const std::optional &hf) +string showErrPos(const ErrPos &errPos) { - return ProgramEI(elError, name, description, hf); -} - -ErrorInfo ErrorInfo::ProgramWarning(const string &name, - const string &description, - const std::optional &hf) -{ - return ProgramEI(elWarning, name, description, hf); -} - - - -ErrorInfo ErrorInfo::ProgramEI(ErrLevel level, - const string &name, - const string &description, - const std::optional &hf) -{ - ErrorInfo ei(elError); - ei.name = name; - ei.description = description; - if (hf.has_value()) - ei.hint = std::optional(hf->str()); - else - ei.hint = std::nullopt; - return ei; -} - - - - - - -string showErrLine(const ErrLine &errLine) -{ - if (errLine.column > 0) { - return (format("(%1%:%2%)") % errLine.lineNumber % errLine.column).str(); + if (errPos.column > 0) { + return (format("(%1%:%2%)") % errPos.lineNumber % errPos.column).str(); } else { - return (format("(%1%)") % errLine.lineNumber).str(); + return (format("(%1%)") % errPos.lineNumber).str(); }; } -void printCodeLines(const string &prefix, const NixCode &nixCode) +void printCodeLines(const string &prefix, const ErrorInfo &einfo) { - - if (nixCode.errLine.has_value()) { + if (einfo.errPos.has_value()) { // previous line of code. - if (nixCode.errLine->prevLineOfCode.has_value()) { + if (einfo.prevLineOfCode.has_value()) { std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errLine->lineNumber - 1) - % *nixCode.errLine->prevLineOfCode + % prefix + % (einfo.errPos->lineNumber - 1) + % *einfo.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 + % (einfo.errPos->lineNumber) + % einfo.errLineOfCode << std::endl; // error arrows for the column range. - if (nixCode.errLine->column > 0) { - int start = nixCode.errLine->column; + if (einfo.errPos->column > 0) { + int start = einfo.errPos->column; std::string spaces; for (int i = 0; i < start; ++i) { spaces.append(" "); @@ -89,11 +52,11 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) // next line of code. - if (nixCode.errLine->nextLineOfCode.has_value()) { + if (einfo.nextLineOfCode.has_value()) { std::cout << format("%1% %|2$5d|| %3%") % prefix - % (nixCode.errLine->lineNumber + 1) - % *nixCode.errLine->nextLineOfCode + % (einfo.errPos->lineNumber + 1) + % *einfo.nextLineOfCode << std::endl; } @@ -144,14 +107,14 @@ void printErrorInfo(const ErrorInfo &einfo) << std::endl; // filename. - if (einfo.nixCode.has_value()) { - if (einfo.nixCode->nixFile.has_value()) { - string eline = einfo.nixCode->errLine.has_value() - ? string(" ") + showErrLine(*einfo.nixCode->errLine) + if (einfo.errPos.has_value()) { + if (einfo.errPos->nixFile != "") { + string eline = einfo.errLineOfCode != "" + ? string(" ") + showErrPos(*einfo.errPos) : ""; std::cout << format("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL) - % prefix % *einfo.nixCode->nixFile % eline << std::endl; + % prefix % einfo.errPos->nixFile % eline << std::endl; std::cout << prefix << std::endl; } else { std::cout << format("%1%from command line argument") % prefix << std::endl; @@ -164,8 +127,8 @@ void printErrorInfo(const ErrorInfo &einfo) std::cout << prefix << std::endl; // lines of code. - if (einfo.nixCode.has_value()) { - printCodeLines(prefix, *einfo.nixCode); + if (einfo.errLineOfCode != "") { + printCodeLines(prefix, einfo); std::cout << prefix << std::endl; } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index e3bb2c1dd..b687bde81 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -17,23 +17,21 @@ typedef enum { elError } ErrLevel; -class ErrorInfo; - -class ErrLine +class ErrPos { public: int lineNumber; int column; - std::optional prevLineOfCode; - string errLineOfCode; - std::optional nextLineOfCode; -}; + string nixFile; -class NixCode -{ -public: - std::optional nixFile; - std::optional errLine; + template + ErrPos& operator=(const P &pos) + { + lineNumber = pos.line; + column = pos.column; + nixFile = pos.file.str(); + return *this; + } }; // ---------------------------------------------------------------- @@ -79,6 +77,11 @@ private: format fmt; }; +std::ostream& operator<<(std::ostream &os, const hintformat &hf) +{ + return os << hf.str(); +} + template inline hintformat hintfmt(const std::string & fs, const Args & ... args) { @@ -95,95 +98,56 @@ public: ErrLevel level; string name; string description; - std::optional nixCode; - std::optional hint; + std::optional hint; + std::optional prevLineOfCode; + string errLineOfCode; + std::optional nextLineOfCode; + std::optional errPos; static std::optional programName; - ErrorInfo& set_name(const string &name) { this->name = name; return *this; } - - static ErrorInfo ProgramError(const string &name, - const string &description, - const std::optional &hf); - - - static ErrorInfo ProgramWarning(const string &name, - const string &description, - const std::optional &hf); - - - template - static ErrorInfo NixLangError(const string &name, - const string &description, - const P &pos, - std::optional prevloc, - string loc, - std::optional nextloc, - const std::optional &hf) - { - return NixLangEI(elError, name, description, pos, prevloc, loc, nextloc, hf); - } - - - template - static ErrorInfo NixLangWarning(const string &name, - const string &description, - const P &pos, - std::optional prevloc, - string loc, - std::optional nextloc, - const std::optional &hf) - { - return NixLangEI(elWarning, name, description, pos, prevloc, loc, nextloc, hf); - } - - - private: - template - static ErrorInfo NixLangEI(ErrLevel level, - const string &name, - const string &description, - const P &pos, - std::optional prevloc, - string loc, - std::optional nextloc, - const std::optional &hf) - { - ErrorInfo ei(level); - ei.name = name; - ei.description = description; - if (hf.has_value()) - ei.hint = std::optional(hf->str()); - else - ei.hint = std::nullopt; + // template + // static ErrorInfo NixLangEI(ErrLevel level, + // const string &name, + // const string &description, + // const P &pos, + // std::optional prevloc, + // string loc, + // std::optional nextloc, + // const std::optional &hf) + // { + // ErrorInfo ei(level); + // ei.name = name; + // ei.description = description; + // if (hf.has_value()) + // ei.hint = std::optional(hf->str()); + // else + // ei.hint = std::nullopt; - ErrLine errline; - errline.lineNumber = pos.line; - errline.column = pos.column; - errline.prevLineOfCode = prevloc; - errline.errLineOfCode = loc; - errline.nextLineOfCode = nextloc; - NixCode nixcode; - nixcode.nixFile = pos.file; - nixcode.errLine = std::optional(errline); - ei.nixCode = std::optional(nixcode); + // ErrLine errline; + // errline.lineNumber = pos.line; + // errline.column = pos.column; + // errline.prevLineOfCode = prevloc; + // errline.errLineOfCode = loc; + // errline.nextLineOfCode = nextloc; + // NixCode nixcode; + // nixcode.nixFile = pos.file; + // nixcode.errLine = std::optional(errline); + // ei.nixCode = std::optional(nixcode); - return ei; - } + // return ei; + // } - static ErrorInfo ProgramEI(ErrLevel level, - const string &name, - const string &description, - const std::optional &hf); + // static ErrorInfo ProgramEI(ErrLevel level, + // const string &name, + // const string &description, + // const std::optional &hf); // constructor is protected, so only the builder classes can create an ErrorInfo. - ErrorInfo(ErrLevel level) - { - this->level = level; - } + }; // -------------------------------------------------------- From 54f91923c844a98c4f8fd4c06feab9421a879ad7 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 8 Apr 2020 09:48:21 -0600 Subject: [PATCH 5/8] return of NixCode --- src/error-demo/error-demo.cc | 47 +++++++++++-------- src/libutil/error.cc | 88 +++++++++++++++++------------------- src/libutil/error.hh | 63 +++++++------------------- 3 files changed, 85 insertions(+), 113 deletions(-) diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 7eef0b162..f8ec95533 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -31,36 +31,43 @@ int main() .name = "name", .description = "error description", .hint = std::optional( - hintfmt("there was a %1%", "warning")) + hintfmt("there was a %1%", "warning")), }); // NixLangWarning adds nix file, line number, column range, and the lines of // code where a warning occurred. -/* SymbolTable testTable; - auto problem_symbol = testTable.create("problem"); + SymbolTable testTable; + auto problem_file = testTable.create("myfile.nix"); printErrorInfo( - ErrorInfo::NixLangWarning( - "warning name", - "warning description", - Pos(problem_symbol, 40, 13), - std::nullopt, - "this is the problem line of code", - std::nullopt, - hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); + ErrorInfo{ + .level = elWarning, + .name = "warning name", + .description = "warning description", + .hint = hintfmt("this hint has %1% templated %2%!!", "yellow", "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13), + .prevLineOfCode = std::nullopt, + .errLineOfCode = "this is the problem line of code", + .nextLineOfCode = std::nullopt + }}); // NixLangError is just the same as NixLangWarning, except for the Error // flag. printErrorInfo( - ErrorInfo::NixLangError( - "error name", - "error description", - Pos(problem_symbol, 40, 13), - std::optional("previous line of code"), - "this is the problem line of code", - std::optional("next line of code"), - hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); + ErrorInfo{ + .level = elError, + .name = "error name", + .description = "error description", + .hint = hintfmt("this hint has %1% templated %2%!!", "yellow", "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13), + .prevLineOfCode = std::optional("previous line of code"), + .errLineOfCode = "this is the problem line of code", + .nextLineOfCode = std::optional("next line of code"), + }}); -*/ return 0; + + return 0; } diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 24ed4df2e..1b9836059 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -17,51 +17,45 @@ string showErrPos(const ErrPos &errPos) }; } -void printCodeLines(const string &prefix, const ErrorInfo &einfo) +void printCodeLines(const string &prefix, const NixCode &nixCode) { - if (einfo.errPos.has_value()) { - // previous line of code. - if (einfo.prevLineOfCode.has_value()) { - std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (einfo.errPos->lineNumber - 1) - % *einfo.prevLineOfCode - << std::endl; - } - - // line of code containing the error.%2$+5d% + // previous line of code. + if (nixCode.prevLineOfCode.has_value()) { std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (einfo.errPos->lineNumber) - % einfo.errLineOfCode + % prefix + % (nixCode.errPos.lineNumber - 1) + % *nixCode.prevLineOfCode << std::endl; - - // error arrows for the column range. - if (einfo.errPos->column > 0) { - int start = einfo.errPos->column; - std::string spaces; - for (int i = 0; i < start; ++i) { - spaces.append(" "); - } - - std::string arrows("^"); - - std::cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << std::endl; - } - - - - // next line of code. - if (einfo.nextLineOfCode.has_value()) { - std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (einfo.errPos->lineNumber + 1) - % *einfo.nextLineOfCode - << std::endl; - } - } + // line of code containing the error.%2$+5d% + std::cout << format("%1% %|2$5d|| %3%") + % prefix + % (nixCode.errPos.lineNumber) + % nixCode.errLineOfCode + << std::endl; + + // error arrows for the column range. + if (nixCode.errPos.column > 0) { + int start = nixCode.errPos.column; + std::string spaces; + for (int i = 0; i < start; ++i) { + spaces.append(" "); + } + + std::string arrows("^"); + + std::cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << std::endl; + } + + // next line of code. + if (nixCode.nextLineOfCode.has_value()) { + std::cout << format("%1% %|2$5d|| %3%") + % prefix + % (nixCode.errPos.lineNumber + 1) + % *nixCode.nextLineOfCode + << std::endl; + } } void printErrorInfo(const ErrorInfo &einfo) @@ -107,14 +101,14 @@ void printErrorInfo(const ErrorInfo &einfo) << std::endl; // filename. - if (einfo.errPos.has_value()) { - if (einfo.errPos->nixFile != "") { - string eline = einfo.errLineOfCode != "" - ? string(" ") + showErrPos(*einfo.errPos) + if (einfo.nixCode.has_value()) { + if (einfo.nixCode->errPos.nixFile != "") { + string eline = einfo.nixCode->errLineOfCode != "" + ? string(" ") + showErrPos(einfo.nixCode->errPos) : ""; std::cout << format("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL) - % prefix % einfo.errPos->nixFile % eline << std::endl; + % prefix % einfo.nixCode->errPos.nixFile % eline << std::endl; std::cout << prefix << std::endl; } else { std::cout << format("%1%from command line argument") % prefix << std::endl; @@ -127,8 +121,8 @@ void printErrorInfo(const ErrorInfo &einfo) std::cout << prefix << std::endl; // lines of code. - if (einfo.errLineOfCode != "") { - printCodeLines(prefix, einfo); + if (einfo.nixCode->errLineOfCode != "") { + printCodeLines(prefix, *einfo.nixCode); std::cout << prefix << std::endl; } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index b687bde81..7e76c0079 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -29,9 +29,24 @@ public: { lineNumber = pos.line; column = pos.column; - nixFile = pos.file.str(); + nixFile = pos.file; return *this; } + + template + ErrPos(const P &p) + { + *this = p; + } +}; + +class NixCode +{ +public: + ErrPos errPos; + std::optional prevLineOfCode; + string errLineOfCode; + std::optional nextLineOfCode; }; // ---------------------------------------------------------------- @@ -99,55 +114,11 @@ public: string name; string description; std::optional hint; - std::optional prevLineOfCode; - string errLineOfCode; - std::optional nextLineOfCode; - std::optional errPos; + std::optional nixCode; static std::optional programName; private: - // template - // static ErrorInfo NixLangEI(ErrLevel level, - // const string &name, - // const string &description, - // const P &pos, - // std::optional prevloc, - // string loc, - // std::optional nextloc, - // const std::optional &hf) - // { - // ErrorInfo ei(level); - // ei.name = name; - // ei.description = description; - // if (hf.has_value()) - // ei.hint = std::optional(hf->str()); - // else - // ei.hint = std::nullopt; - - // ErrLine errline; - // errline.lineNumber = pos.line; - // errline.column = pos.column; - // errline.prevLineOfCode = prevloc; - // errline.errLineOfCode = loc; - // errline.nextLineOfCode = nextloc; - // NixCode nixcode; - // nixcode.nixFile = pos.file; - // nixcode.errLine = std::optional(errline); - // ei.nixCode = std::optional(nixcode); - - // return ei; - // } - - // static ErrorInfo ProgramEI(ErrLevel level, - // const string &name, - // const string &description, - // const std::optional &hf); - - - - // constructor is protected, so only the builder classes can create an ErrorInfo. - }; // -------------------------------------------------------- From 555baa8fb07d4296c271ebc263a0a8fbe30268ee Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 8 Apr 2020 09:56:10 -0600 Subject: [PATCH 6/8] comments --- src/error-demo/error-demo.cc | 17 +++++------------ src/libutil/error.hh | 2 +- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index f8ec95533..a9ff6057c 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -11,21 +11,15 @@ int main() // In each program where errors occur, this has to be set. ErrorInfo::programName = std::optional("error-demo"); - // There are currently four constructor functions: - // - // ProgramError, ProgramWarning, NixLangError, NixLangWarning. - // - - // ProgramError takes name, description, and an optional hint. + // Error in a program; no hint and no nix code. printErrorInfo( ErrorInfo { .level = elError, .name = "name", .description = "error description", }); - // ProgramWarning takes name, description, and an optional hint. - // The hint is in the form of a hintfmt class, which wraps boost::format(), - // and makes all the substituted text yellow. + // Warning with name, description, and hint. + // The hintfmt function makes all the substituted text yellow. printErrorInfo( ErrorInfo { .level = elWarning, .name = "name", @@ -35,7 +29,7 @@ int main() }); - // NixLangWarning adds nix file, line number, column range, and the lines of + // Warning with nix file, line number, column, and the lines of // code where a warning occurred. SymbolTable testTable; auto problem_file = testTable.create("myfile.nix"); @@ -53,8 +47,7 @@ int main() .nextLineOfCode = std::nullopt }}); - // NixLangError is just the same as NixLangWarning, except for the Error - // flag. + // Error with previous and next lines of code. printErrorInfo( ErrorInfo{ .level = elError, diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 7e76c0079..8286eaab1 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -50,7 +50,7 @@ public: }; // ---------------------------------------------------------------- -// format for hints. same as fmt, except templated values +// format function for hints. same as fmt, except templated values // are always in yellow. template From 8c2bf15c4fbf5cd18d3ee0b88f6b510e8881a622 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 8 Apr 2020 11:17:02 -0600 Subject: [PATCH 7/8] format -> fmt --- src/libutil/error.cc | 57 +++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 1b9836059..138c50d2b 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -11,9 +11,9 @@ std::optional ErrorInfo::programName = std::nullopt; string showErrPos(const ErrPos &errPos) { if (errPos.column > 0) { - return (format("(%1%:%2%)") % errPos.lineNumber % errPos.column).str(); + return fmt("(%1%:%2%)", errPos.lineNumber, errPos.column); } else { - return (format("(%1%)") % errPos.lineNumber).str(); + return fmt("(%1%)", errPos.lineNumber); }; } @@ -21,18 +21,18 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) { // previous line of code. if (nixCode.prevLineOfCode.has_value()) { - std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errPos.lineNumber - 1) - % *nixCode.prevLineOfCode + std::cout << fmt("%1% %|2$5d|| %3%", + prefix, + (nixCode.errPos.lineNumber - 1), + *nixCode.prevLineOfCode) << std::endl; } // line of code containing the error.%2$+5d% - std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errPos.lineNumber) - % nixCode.errLineOfCode + std::cout << fmt("%1% %|2$5d|| %3%", + prefix, + (nixCode.errPos.lineNumber), + nixCode.errLineOfCode) << std::endl; // error arrows for the column range. @@ -45,15 +45,18 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) std::string arrows("^"); - std::cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << std::endl; + std::cout << fmt("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL, + prefix, + spaces, + arrows) << std::endl; } // next line of code. if (nixCode.nextLineOfCode.has_value()) { - std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errPos.lineNumber + 1) - % *nixCode.nextLineOfCode + std::cout << fmt("%1% %|2$5d|| %3%", + prefix, + (nixCode.errPos.lineNumber + 1), + *nixCode.nextLineOfCode) << std::endl; } } @@ -78,8 +81,8 @@ void printErrorInfo(const ErrorInfo &einfo) break; } default: { - levelString = (format("invalid error level: %1%") % einfo.level).str(); - break; + levelString = fmt("invalid error level: %1%", einfo.level); + break; } } @@ -91,13 +94,13 @@ void printErrorInfo(const ErrorInfo &einfo) dashes.append("-"); // divider. - std::cout << format("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL) - % prefix - % levelString - % "---" - % einfo.name - % dashes - % einfo.programName.value_or("") + std::cout << fmt("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL, + prefix, + levelString, + "---", + einfo.name, + dashes, + einfo.programName.value_or("")) << std::endl; // filename. @@ -107,11 +110,11 @@ void printErrorInfo(const ErrorInfo &einfo) ? string(" ") + showErrPos(einfo.nixCode->errPos) : ""; - std::cout << format("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL) - % prefix % einfo.nixCode->errPos.nixFile % eline << std::endl; + std::cout << fmt("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL + , prefix, einfo.nixCode->errPos.nixFile, eline) << std::endl; std::cout << prefix << std::endl; } else { - std::cout << format("%1%from command line argument") % prefix << std::endl; + std::cout << fmt("%1%from command line argument", prefix) << std::endl; std::cout << prefix << std::endl; } } From 805ffe1bc93b14ad8d1132c20179e85a914c91e6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 8 Apr 2020 11:33:46 -0600 Subject: [PATCH 8/8] indention --- src/libutil/error.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 138c50d2b..665361a2a 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -82,7 +82,7 @@ void printErrorInfo(const ErrorInfo &einfo) } default: { levelString = fmt("invalid error level: %1%", einfo.level); - break; + break; } }