From f694f43d7ddd270706e6e3a5f034336a5a83fb86 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 22 Mar 2020 12:25:47 -0600 Subject: [PATCH 01/46] straightforward port of rust mockup code --- src/libutil/error.cc | 137 +++++++++++++++++++++++++++++++++++++++++++ src/libutil/error.hh | 57 ++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 src/libutil/error.cc create mode 100644 src/libutil/error.hh diff --git a/src/libutil/error.cc b/src/libutil/error.cc new file mode 100644 index 000000000..4af4691d4 --- /dev/null +++ b/src/libutil/error.cc @@ -0,0 +1,137 @@ +#include "error.hh" + +#include + +namespace nix { + +using std::cout; +using std::endl; + +// return basic_format? +string showErrLine(ErrLine &errLine) +{ + if (errLine.columnRange.has_value()) + { + return (format("(%1%:%2%)") % errLine.lineNumber % errLine.columnRange->start).str(); + } + else + { + return (format("(%1%)") % errLine.lineNumber).str(); + }; +} + +void print_code_lines(string &prefix, NixCode &nix_code) +{ + if (nix_code.errLine.has_value()) + { + // previous line of code. + if (nix_code.errLine->prevLineOfCode.has_value()) { + cout << format("%1% %2$+5d%| %3%") % prefix % (nix_code.errLine->lineNumber - 1) % *nix_code.errLine->prevLineOfCode; + } + + // line of code containing the error. + cout << format("%1% %2$+5d%| %3%") % prefix % (nix_code.errLine->lineNumber) % nix_code.errLine->errLineOfCode; + + // error arrows for the column range. + if (nix_code.errLine->columnRange.has_value()) + { + int start = nix_code.errLine->columnRange->start; + std::string spaces; + for (int i = 0; i < start; ++i) + { + spaces.append(" "); + } + + int len = nix_code.errLine->columnRange->len; + std::string arrows; + for (int i = 0; i < len; ++i) + { + arrows.append("^"); + } + + cout << format("%1% |%2%%3%") % prefix % spaces % arrows; + } + + + // next line of code. + if (nix_code.errLine->nextLineOfCode.has_value()) { + cout << format("%1% %2$+5d%| %3%") % prefix % (nix_code.errLine->lineNumber + 1) % *nix_code.errLine->nextLineOfCode; + } + + } + else + { + } + +} + +void print_error(ErrorInfo &einfo) +{ + int errwidth = 80; + string prefix = " "; + + string level_string; + switch (einfo.level) + { + case ErrLevel::elError: + { + level_string = "error:"; // TODO make red. + break; + } + case ErrLevel::elWarning: + { + level_string = "warning:"; // TODO make yellow. + break; + } + } + + int ndl = level_string.length() + 3 + einfo.errName.length() + einfo.toolName.length(); + int dashwidth = errwidth - 3 ? 3 : 80 - ndl; + + string dashes; + for (int i = 0; i < dashwidth; ++i) + dashes.append("-"); + + // divider. + cout << format("%1%%2% %3% %4% %5% %6%") + % prefix + % level_string + % "---" + % einfo.errName + % dashes + % einfo.toolName; + + // filename. + if (einfo.nixCode.has_value()) + { + if (einfo.nixCode->nixFile.has_value()) + { + string eline = einfo.nixCode->errLine.has_value() + ? string(" ") + showErrLine(*einfo.nixCode->errLine) + : ""; + + cout << format("%1%in file: %2%%3%") % prefix % *einfo.nixCode->nixFile % eline; + cout << prefix << endl; + } + else + { + cout << format("%1%from command line argument") % prefix << endl; + cout << prefix << endl; + } + } + + // description + cout << prefix << einfo.description << endl; + cout << prefix << endl; + + // lines of code. + if (einfo.nixCode.has_value()) + print_code_lines(prefix, *einfo.nixCode); + + // hint + cout << prefix << einfo.hint << endl; + cout << prefix << endl; + +} + +} diff --git a/src/libutil/error.hh b/src/libutil/error.hh new file mode 100644 index 000000000..0bc1f4e24 --- /dev/null +++ b/src/libutil/error.hh @@ -0,0 +1,57 @@ +#pragma once + +#include "types.hh" +#include +#include +// #include + +using std::string; +using std::optional; +// using boost::format; + +namespace nix { + +enum ErrLevel + { elWarning + , elError + }; + +class ColumnRange { + public: + unsigned int start; + unsigned int len; +}; + +class ErrLine { + public: + int lineNumber; + optional columnRange; + optional prevLineOfCode; + string errLineOfCode; + optional nextLineOfCode; +}; + +class NixCode { + public: + optional nixFile; + optional errLine; +}; + + +class ErrorInfo { + public: + ErrLevel level; + string errName; + string description; + string toolName; + optional nixCode; + string hint; +}; + +string showErrLine(ErrLine &errLine); + +void print_code_lines(string &prefix, NixCode &nix_code); + +void print_error(ErrorInfo &einfo); +} + From aadd59d005bdabbb801f622dc1a0e3b12a5e5286 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 23 Mar 2020 15:29:49 -0600 Subject: [PATCH 02/46] error test --- src/libutil/error.cc | 36 +++++++++++++++++++++++++----------- src/libutil/error.hh | 2 -- tests/errors/main.cc | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 tests/errors/main.cc diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 4af4691d4..71f422622 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -8,7 +8,7 @@ using std::cout; using std::endl; // return basic_format? -string showErrLine(ErrLine &errLine) +string showErrLine(ErrLine &errLine) { if (errLine.columnRange.has_value()) { @@ -22,15 +22,26 @@ string showErrLine(ErrLine &errLine) void print_code_lines(string &prefix, NixCode &nix_code) { + if (nix_code.errLine.has_value()) { // previous line of code. if (nix_code.errLine->prevLineOfCode.has_value()) { - cout << format("%1% %2$+5d%| %3%") % prefix % (nix_code.errLine->lineNumber - 1) % *nix_code.errLine->prevLineOfCode; + cout << format("%1% %|2$5d|| %3%") + % prefix + % (nix_code.errLine->lineNumber - 1) + % *nix_code.errLine->prevLineOfCode + << endl; } - // line of code containing the error. - cout << format("%1% %2$+5d%| %3%") % prefix % (nix_code.errLine->lineNumber) % nix_code.errLine->errLineOfCode; + // line of code containing the error.%2$+5d% + cout << format("%1% %|2$5d|| %3%") + % prefix + % (nix_code.errLine->lineNumber) + % nix_code.errLine->errLineOfCode + << endl; + + // error arrows for the column range. if (nix_code.errLine->columnRange.has_value()) @@ -49,19 +60,21 @@ void print_code_lines(string &prefix, NixCode &nix_code) arrows.append("^"); } - cout << format("%1% |%2%%3%") % prefix % spaces % arrows; + cout << format("%1% |%2%%3%") % prefix % spaces % arrows; } + // next line of code. if (nix_code.errLine->nextLineOfCode.has_value()) { - cout << format("%1% %2$+5d%| %3%") % prefix % (nix_code.errLine->lineNumber + 1) % *nix_code.errLine->nextLineOfCode; + cout << format("%1% %|2$5d|| %3%") + % prefix + % (nix_code.errLine->lineNumber + 1) + % *nix_code.errLine->nextLineOfCode + << endl; } } - else - { - } } @@ -99,7 +112,8 @@ void print_error(ErrorInfo &einfo) % "---" % einfo.errName % dashes - % einfo.toolName; + % einfo.toolName + << endl; // filename. if (einfo.nixCode.has_value()) @@ -110,7 +124,7 @@ void print_error(ErrorInfo &einfo) ? string(" ") + showErrLine(*einfo.nixCode->errLine) : ""; - cout << format("%1%in file: %2%%3%") % prefix % *einfo.nixCode->nixFile % eline; + cout << format("%1%in file: %2%%3%") % prefix % *einfo.nixCode->nixFile % eline << endl; cout << prefix << endl; } else diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 0bc1f4e24..8dac1508e 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -3,11 +3,9 @@ #include "types.hh" #include #include -// #include using std::string; using std::optional; -// using boost::format; namespace nix { diff --git a/tests/errors/main.cc b/tests/errors/main.cc new file mode 100644 index 000000000..1c998103e --- /dev/null +++ b/tests/errors/main.cc @@ -0,0 +1,39 @@ +#include "error.hh" + +#include +#include + +using std::optional; + +int main() { + +using namespace nix; + + ColumnRange columnRange; + columnRange.start = 24; + columnRange.len = 14; + + ErrLine errline; + errline.lineNumber = 7; + errline.columnRange = optional(columnRange); + errline.errLineOfCode = "line of code where the error occurred"; + + NixCode nixcode; + nixcode.nixFile = optional("myfile.nix"); + nixcode.errLine = errline; + + ErrorInfo generic; + generic.level = elError; + generic.errName = "error name"; + generic.description = "general error description"; + generic.toolName = "nixtool.exe"; + generic.nixCode = nixcode; + + print_error(generic); + + return 0; +} + + + + From 4171ab4bbd95e9bb4b9d6c6e8c143002d92b0c06 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 24 Mar 2020 09:18:23 -0600 Subject: [PATCH 03/46] renaming --- src/libutil/error.cc | 8 +++----- src/libutil/error.hh | 31 +++++++++++++++++++++++++++++-- tests/errors/main.cc | 9 +++++++-- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 71f422622..81c1f1805 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -41,8 +41,6 @@ void print_code_lines(string &prefix, NixCode &nix_code) % nix_code.errLine->errLineOfCode << endl; - - // error arrows for the column range. if (nix_code.errLine->columnRange.has_value()) { @@ -98,7 +96,7 @@ void print_error(ErrorInfo &einfo) } } - int ndl = level_string.length() + 3 + einfo.errName.length() + einfo.toolName.length(); + int ndl = level_string.length() + 3 + einfo.name.length() + einfo.program.length(); int dashwidth = errwidth - 3 ? 3 : 80 - ndl; string dashes; @@ -110,9 +108,9 @@ void print_error(ErrorInfo &einfo) % prefix % level_string % "---" - % einfo.errName + % einfo.name % dashes - % einfo.toolName + % einfo.program << endl; // filename. diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 8dac1508e..69776eb8c 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -39,13 +39,40 @@ class NixCode { class ErrorInfo { public: ErrLevel level; - string errName; + string name; string description; - string toolName; + string program; optional nixCode; string hint; + ErrorInfo& GetEI() { return *this; } }; +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(); } +}; + +typedef AddName> StandardError; + string showErrLine(ErrLine &errLine); void print_code_lines(string &prefix, NixCode &nix_code); diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 1c998103e..0e6d781c9 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -24,13 +24,18 @@ using namespace nix; ErrorInfo generic; generic.level = elError; - generic.errName = "error name"; + generic.name = "error name"; generic.description = "general error description"; - generic.toolName = "nixtool.exe"; + generic.program = "nixtool.exe"; generic.nixCode = nixcode; print_error(generic); + + StandardError standardError; + + print_error(standardError.name("blah").description("blah")); + return 0; } From 0166e7ab6d1d4530e9d6d9562693a58ab54c36ba Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 24 Mar 2020 11:21:35 -0600 Subject: [PATCH 04/46] MkNixCode, MkErrLine approach --- src/libutil/error.cc | 6 +- src/libutil/error.hh | 187 +++++++++++++++++++++++++++++++++++++++---- tests/errors/main.cc | 38 ++++++++- 3 files changed, 211 insertions(+), 20 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 81c1f1805..f258d6a83 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -94,7 +94,11 @@ void print_error(ErrorInfo &einfo) level_string = "warning:"; // TODO make yellow. break; } - } + default: + { + level_string = "wat:"; + break; + }} int ndl = level_string.length() + 3 + einfo.name.length() + einfo.program.length(); int dashwidth = errwidth - 3 ? 3 : 80 - ndl; diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 69776eb8c..9449540af 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -3,6 +3,7 @@ #include "types.hh" #include #include +#include using std::string; using std::optional; @@ -16,35 +17,171 @@ enum ErrLevel class ColumnRange { public: - unsigned int start; - unsigned int len; + unsigned int start; + unsigned int len; }; +class ErrorInfo; + +// ------------------------------------------------- +// forward declarations before ErrLine. +template +class AddLineNumber; + +template +class AddColumnRange; + +template +class AddLOC; + class ErrLine { public: - int lineNumber; - optional columnRange; - optional prevLineOfCode; - string errLineOfCode; - optional nextLineOfCode; + int lineNumber; + optional columnRange; + optional prevLineOfCode; + string errLineOfCode; + optional nextLineOfCode; + + friend AddLineNumber; + friend AddColumnRange; + friend AddLOC; + ErrLine& GetEL() { return *this; } + private: + ErrLine() {} }; +template +class AddLineNumber : public T +{ + public: + T& lineNumber(int lineNumber) { + GetEL().lineNumber = lineNumber; + return *this; + } + protected: + ErrLine& GetEL() { return T::GetEL(); } +}; + +template +class AddColumnRange : public T +{ + public: + T& columnRange(unsigned int start, unsigned int len) { + GetEL().columnRange = { start, len }; + return *this; + } + protected: + ErrLine& GetEL() { return T::GetEL(); } +}; + +template +class AddLOC : public T +{ + public: + T& linesOfCode(optional prevloc, string loc, optional nextloc) { + GetEL().prevLineOfCode = prevloc; + GetEL().errLineOfCode = loc; + GetEL().nextLineOfCode = nextloc; + return *this; + } + protected: + ErrLine& GetEL() { return T::GetEL(); } +}; + +typedef AddLineNumber>> MkErrLine; +MkErrLine mkErrLine; + + +// ------------------------------------------------- +// NixCode. + +template +class AddNixFile; + +template +class AddErrLine; + class NixCode { public: - optional nixFile; - optional errLine; + optional nixFile; + optional errLine; + + friend AddNixFile; + friend AddErrLine; + friend ErrorInfo; + NixCode& GetNC() { return *this; } + private: + NixCode() {} }; +template +class AddNixFile : public T +{ + public: + T& nixFile(string filename) { + GetNC().nixFile = filename; + return *this; + } + protected: + NixCode& GetNC() { return T::GetNC(); } +}; + +template +class AddErrLine : public T +{ + public: + T& errLine(ErrLine errline) { + GetNC().errLine = errline; + return *this; + } + protected: + NixCode& GetNC() { return T::GetNC(); } +}; + +typedef AddNixFile> MkNixCode; + +// ------------------------------------------------- +// ErrorInfo. + +template +class AddName; + +template +class AddDescription; + +template +class AddNixCode; class ErrorInfo { public: - ErrLevel level; - string name; - string description; - string program; - optional nixCode; - string hint; - ErrorInfo& GetEI() { return *this; } + ErrLevel level; + string name; + string description; + string program; + optional nixCode; + string hint; + ErrorInfo& GetEI() { return *this; } + + // give these access to the private constructor, + // when they are direct descendants. + friend AddName; + friend AddDescription; + friend AddNixCode; + + protected: + ErrorInfo(ErrLevel level) { this->level = level; } +}; + +class EIError : public ErrorInfo +{ + protected: + EIError() : ErrorInfo(elError) {} +}; + +class EIWarning : public ErrorInfo +{ + protected: + EIWarning() : ErrorInfo(elWarning) {} }; template @@ -71,7 +208,23 @@ class AddDescription : private T ErrorInfo& GetEI() { return T::GetEI(); } }; -typedef AddName> StandardError; +template +class AddNixCode : private T +{ + public: + T& nixcode(const NixCode &nixcode){ + GetEI().nixCode = nixcode; + return *this; + } + protected: + ErrorInfo& GetEI() { return T::GetEI(); } +}; + +typedef AddName> StandardError; +typedef AddName> StandardWarning; + +typedef AddName>> MkNixError; +typedef AddName>> MkNixWarning; string showErrLine(ErrLine &errLine); diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 0e6d781c9..20dba046b 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -4,11 +4,13 @@ #include using std::optional; +using std::nullopt; int main() { using namespace nix; + /* ColumnRange columnRange; columnRange.start = 24; columnRange.len = 14; @@ -30,11 +32,43 @@ using namespace nix; generic.nixCode = nixcode; print_error(generic); - + */ StandardError standardError; - print_error(standardError.name("blah").description("blah")); + print_error(standardError + .name("name") + .description("description")); + + StandardWarning standardWarning; + + print_error(standardWarning + .name("warning name") + .description("warning description")); + + print_error(MkNixError() + .name("name") + .description("description") + .nixcode( + MkNixCode() + .nixFile("myfile.nix") + .errLine(MkErrLine().lineNumber(40) + .columnRange(50,10) + .linesOfCode(nullopt + ,"this is the problem line of code" + ,nullopt)))); + + print_error(MkNixWarning() + .name("name") + .description("description") + .nixcode( + MkNixCode() + .nixFile("myfile.nix") + .errLine(MkErrLine().lineNumber(40) + .columnRange(50,10) + .linesOfCode(nullopt + ,"this is the problem line of code" + ,nullopt)))); return 0; } From 657c08c852ce94123984c475bc9d5f094f7d8d46 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 24 Mar 2020 13:26:20 -0600 Subject: [PATCH 05/46] fix column range --- tests/errors/main.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 20dba046b..c2c4d0060 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -53,7 +53,7 @@ using namespace nix; MkNixCode() .nixFile("myfile.nix") .errLine(MkErrLine().lineNumber(40) - .columnRange(50,10) + .columnRange(13,7) .linesOfCode(nullopt ,"this is the problem line of code" ,nullopt)))); @@ -65,7 +65,7 @@ using namespace nix; MkNixCode() .nixFile("myfile.nix") .errLine(MkErrLine().lineNumber(40) - .columnRange(50,10) + .columnRange(13,7) .linesOfCode(nullopt ,"this is the problem line of code" ,nullopt)))); From fc310eda3afdf97c55a1a5ac6756f8d54a2a5ad6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 24 Mar 2020 14:24:57 -0600 Subject: [PATCH 06/46] switch to one level of builder function, not subobject functions --- src/libutil/error.hh | 197 ++++++++++++++++++++----------------------- tests/errors/main.cc | 47 +++++------ 2 files changed, 112 insertions(+), 132 deletions(-) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 9449540af..25f3e8ee8 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -23,17 +23,6 @@ class ColumnRange { class ErrorInfo; -// ------------------------------------------------- -// forward declarations before ErrLine. -template -class AddLineNumber; - -template -class AddColumnRange; - -template -class AddLOC; - class ErrLine { public: int lineNumber; @@ -42,107 +31,25 @@ class ErrLine { string errLineOfCode; optional nextLineOfCode; - friend AddLineNumber; - friend AddColumnRange; - friend AddLOC; - ErrLine& GetEL() { return *this; } - private: - ErrLine() {} }; -template -class AddLineNumber : public T -{ - public: - T& lineNumber(int lineNumber) { - GetEL().lineNumber = lineNumber; - return *this; - } - protected: - ErrLine& GetEL() { return T::GetEL(); } -}; - -template -class AddColumnRange : public T -{ - public: - T& columnRange(unsigned int start, unsigned int len) { - GetEL().columnRange = { start, len }; - return *this; - } - protected: - ErrLine& GetEL() { return T::GetEL(); } -}; - -template -class AddLOC : public T -{ - public: - T& linesOfCode(optional prevloc, string loc, optional nextloc) { - GetEL().prevLineOfCode = prevloc; - GetEL().errLineOfCode = loc; - GetEL().nextLineOfCode = nextloc; - return *this; - } - protected: - ErrLine& GetEL() { return T::GetEL(); } -}; - -typedef AddLineNumber>> MkErrLine; -MkErrLine mkErrLine; - - -// ------------------------------------------------- -// NixCode. - -template -class AddNixFile; - -template -class AddErrLine; - class NixCode { public: optional nixFile; optional errLine; - friend AddNixFile; - friend AddErrLine; - friend ErrorInfo; - NixCode& GetNC() { return *this; } - private: - NixCode() {} -}; - -template -class AddNixFile : public T -{ - public: - T& nixFile(string filename) { - GetNC().nixFile = filename; - return *this; + ErrLine& ensureErrLine() + { + if (!this->errLine.has_value()) + this->errLine = optional(ErrLine()); + return *this->errLine; } - protected: - NixCode& GetNC() { return T::GetNC(); } }; -template -class AddErrLine : public T -{ - public: - T& errLine(ErrLine errline) { - GetNC().errLine = errline; - return *this; - } - protected: - NixCode& GetNC() { return T::GetNC(); } -}; - -typedef AddNixFile> MkNixCode; - // ------------------------------------------------- // ErrorInfo. +// Forward friend class declarations. "builder classes" template class AddName; @@ -152,6 +59,22 @@ class AddDescription; template class AddNixCode; +template +class AddNixFile; + +template +class AddErrLine; + +template +class AddLineNumber; + +template +class AddColumnRange; + +template +class AddLOC; + +// The error info class itself. class ErrorInfo { public: ErrLevel level; @@ -167,9 +90,23 @@ class ErrorInfo { friend AddName; friend AddDescription; friend AddNixCode; + friend AddNixFile; + friend AddErrLine; + friend AddLineNumber; + friend AddColumnRange; + friend AddLOC; + NixCode& ensureNixCode() + { + if (!this->nixCode.has_value()) + this->nixCode = 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 EIError : public ErrorInfo @@ -208,23 +145,73 @@ class AddDescription : private T ErrorInfo& GetEI() { return T::GetEI(); } }; -template -class AddNixCode : private T +template +class AddNixFile : public T { public: - T& nixcode(const NixCode &nixcode){ - GetEI().nixCode = nixcode; + T& nixFile(string filename) { + GetEI().ensureNixCode().nixFile = filename; + return *this; + } + protected: + ErrorInfo& GetEI() { return T::GetEI(); } +}; + +template +class AddLineNumber : public T +{ + public: + T& lineNumber(int lineNumber) { + GetEI().ensureNixCode().ensureErrLine().lineNumber = lineNumber; return *this; } protected: ErrorInfo& GetEI() { return T::GetEI(); } }; +template +class AddColumnRange : public T +{ + 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 AddLOC : public T +{ + public: + T& linesOfCode(optional prevloc, string loc, 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(); } +}; + +typedef AddNixFile> MkNixCode; + typedef AddName> StandardError; typedef AddName> StandardWarning; -typedef AddName>> MkNixError; -typedef AddName>> MkNixWarning; +typedef AddName< + AddDescription< + AddNixFile< + AddLineNumber< + AddColumnRange< + AddLOC>>>>> MkNixError; +typedef AddName< + AddDescription< + AddNixFile< + AddLineNumber< + AddColumnRange< + AddLOC>>>>> MkNixWarning; string showErrLine(ErrLine &errLine); diff --git a/tests/errors/main.cc b/tests/errors/main.cc index c2c4d0060..6b024d287 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -34,41 +34,34 @@ using namespace nix; print_error(generic); */ - StandardError standardError; - - print_error(standardError + print_error(StandardError() .name("name") .description("description")); - StandardWarning standardWarning; - - print_error(standardWarning + print_error(StandardWarning() .name("warning name") .description("warning description")); - print_error(MkNixError() - .name("name") - .description("description") - .nixcode( - MkNixCode() - .nixFile("myfile.nix") - .errLine(MkErrLine().lineNumber(40) - .columnRange(13,7) - .linesOfCode(nullopt - ,"this is the problem line of code" - ,nullopt)))); print_error(MkNixWarning() - .name("name") - .description("description") - .nixcode( - MkNixCode() - .nixFile("myfile.nix") - .errLine(MkErrLine().lineNumber(40) - .columnRange(13,7) - .linesOfCode(nullopt - ,"this is the problem line of code" - ,nullopt)))); + .name("warning name") + .description("warning description") + .nixFile("myfile.nix") + .lineNumber(40) + .columnRange(13,7) + .linesOfCode(nullopt + ,"this is the problem line of code" + ,nullopt)); + + print_error(MkNixError() + .name("error name") + .description("warning description") + .nixFile("myfile.nix") + .lineNumber(40) + .columnRange(13,7) + .linesOfCode(nullopt + ,"this is the problem line of code" + ,nullopt)); return 0; } From 3582dc3c88d38d5c46091b4a23601d6f56a4c81e Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 25 Mar 2020 10:52:03 -0600 Subject: [PATCH 07/46] programName as static member var --- src/libutil/error.cc | 13 +++++++++---- src/libutil/error.hh | 6 +++++- tests/errors/main.cc | 4 ++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index f258d6a83..4abee052d 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -1,11 +1,15 @@ #include "error.hh" #include +#include namespace nix { using std::cout; using std::endl; +using std::nullopt; + +optional ErrorInfo::programName = nullopt; // return basic_format? string showErrLine(ErrLine &errLine) @@ -98,10 +102,11 @@ void print_error(ErrorInfo &einfo) { level_string = "wat:"; break; - }} + } + } - int ndl = level_string.length() + 3 + einfo.name.length() + einfo.program.length(); - int dashwidth = errwidth - 3 ? 3 : 80 - ndl; + int ndl = prefix.length() + level_string.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); + int dashwidth = ndl > (errwidth - 3) ? 3 : 80 - ndl; string dashes; for (int i = 0; i < dashwidth; ++i) @@ -114,7 +119,7 @@ void print_error(ErrorInfo &einfo) % "---" % einfo.name % dashes - % einfo.program + % einfo.programName.value_or("") << endl; // filename. diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 25f3e8ee8..7260dfd5b 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -80,11 +80,12 @@ class ErrorInfo { ErrLevel level; string name; string description; - string program; optional nixCode; string hint; ErrorInfo& GetEI() { return *this; } + static optional programName; + // give these access to the private constructor, // when they are direct descendants. friend AddName; @@ -109,18 +110,21 @@ class ErrorInfo { }; +// 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 { diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 6b024d287..5ac429b46 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -5,11 +5,15 @@ using std::optional; using std::nullopt; +using std::cout; +using std::endl; int main() { using namespace nix; + ErrorInfo::programName = optional("errorTest"); + /* ColumnRange columnRange; columnRange.start = 24; From d44c9c55817839a41a7b4c509da027d7b4176ca5 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 25 Mar 2020 11:20:44 -0600 Subject: [PATCH 08/46] some colors --- src/libutil/error.cc | 15 ++++++++++----- tests/errors/main.cc | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 4abee052d..9fbd234e0 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -62,7 +62,7 @@ void print_code_lines(string &prefix, NixCode &nix_code) arrows.append("^"); } - cout << format("%1% |%2%%3%") % prefix % spaces % arrows; + cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows; } @@ -90,12 +90,16 @@ void print_error(ErrorInfo &einfo) { case ErrLevel::elError: { - level_string = "error:"; // TODO make red. + level_string = ANSI_RED; + level_string += "error:"; + level_string += ANSI_NORMAL; break; } case ErrLevel::elWarning: { - level_string = "warning:"; // TODO make yellow. + level_string = ANSI_YELLOW; + level_string += "warning:"; + level_string += ANSI_NORMAL; break; } default: @@ -113,7 +117,7 @@ void print_error(ErrorInfo &einfo) dashes.append("-"); // divider. - cout << format("%1%%2% %3% %4% %5% %6%") + cout << format("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL) % prefix % level_string % "---" @@ -131,7 +135,8 @@ void print_error(ErrorInfo &einfo) ? string(" ") + showErrLine(*einfo.nixCode->errLine) : ""; - cout << format("%1%in file: %2%%3%") % prefix % *einfo.nixCode->nixFile % eline << endl; + cout << format("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL) + % prefix % *einfo.nixCode->nixFile % eline << endl; cout << prefix << endl; } else diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 5ac429b46..f53101629 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -59,7 +59,7 @@ using namespace nix; print_error(MkNixError() .name("error name") - .description("warning description") + .description("error description") .nixFile("myfile.nix") .lineNumber(40) .columnRange(13,7) From a3ef00be6c668bd59a879a4acdb1599225d86b44 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 27 Mar 2020 10:03:02 -0600 Subject: [PATCH 09/46] camelcase; optional hint --- src/libutil/error.cc | 60 +++++++++++++++++--------------- src/libutil/error.hh | 82 +++++++++++++++++++++++++++++++++++++------- tests/errors/main.cc | 34 +++++++++--------- 3 files changed, 119 insertions(+), 57 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 9fbd234e0..d6595070f 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -24,55 +24,55 @@ string showErrLine(ErrLine &errLine) }; } -void print_code_lines(string &prefix, NixCode &nix_code) +void printCodeLines(string &prefix, NixCode &nixCode) { - if (nix_code.errLine.has_value()) + if (nixCode.errLine.has_value()) { // previous line of code. - if (nix_code.errLine->prevLineOfCode.has_value()) { + if (nixCode.errLine->prevLineOfCode.has_value()) { cout << format("%1% %|2$5d|| %3%") % prefix - % (nix_code.errLine->lineNumber - 1) - % *nix_code.errLine->prevLineOfCode + % (nixCode.errLine->lineNumber - 1) + % *nixCode.errLine->prevLineOfCode << endl; } // line of code containing the error.%2$+5d% cout << format("%1% %|2$5d|| %3%") % prefix - % (nix_code.errLine->lineNumber) - % nix_code.errLine->errLineOfCode + % (nixCode.errLine->lineNumber) + % nixCode.errLine->errLineOfCode << endl; // error arrows for the column range. - if (nix_code.errLine->columnRange.has_value()) + if (nixCode.errLine->columnRange.has_value()) { - int start = nix_code.errLine->columnRange->start; + int start = nixCode.errLine->columnRange->start; std::string spaces; for (int i = 0; i < start; ++i) { spaces.append(" "); } - int len = nix_code.errLine->columnRange->len; + int len = nixCode.errLine->columnRange->len; std::string arrows; for (int i = 0; i < len; ++i) { arrows.append("^"); } - cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows; + cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << endl; } // next line of code. - if (nix_code.errLine->nextLineOfCode.has_value()) { + if (nixCode.errLine->nextLineOfCode.has_value()) { cout << format("%1% %|2$5d|| %3%") % prefix - % (nix_code.errLine->lineNumber + 1) - % *nix_code.errLine->nextLineOfCode + % (nixCode.errLine->lineNumber + 1) + % *nixCode.errLine->nextLineOfCode << endl; } @@ -80,36 +80,36 @@ void print_code_lines(string &prefix, NixCode &nix_code) } -void print_error(ErrorInfo &einfo) +void printErrorInfo(ErrorInfo &einfo) { int errwidth = 80; string prefix = " "; - string level_string; + string levelString; switch (einfo.level) { case ErrLevel::elError: { - level_string = ANSI_RED; - level_string += "error:"; - level_string += ANSI_NORMAL; + levelString = ANSI_RED; + levelString += "error:"; + levelString += ANSI_NORMAL; break; } case ErrLevel::elWarning: { - level_string = ANSI_YELLOW; - level_string += "warning:"; - level_string += ANSI_NORMAL; + levelString = ANSI_YELLOW; + levelString += "warning:"; + levelString += ANSI_NORMAL; break; } default: { - level_string = "wat:"; + levelString = "wat:"; break; } } - int ndl = prefix.length() + level_string.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); + int ndl = prefix.length() + levelString.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); int dashwidth = ndl > (errwidth - 3) ? 3 : 80 - ndl; string dashes; @@ -119,7 +119,7 @@ void print_error(ErrorInfo &einfo) // divider. cout << format("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL) % prefix - % level_string + % levelString % "---" % einfo.name % dashes @@ -152,11 +152,15 @@ void print_error(ErrorInfo &einfo) // lines of code. if (einfo.nixCode.has_value()) - print_code_lines(prefix, *einfo.nixCode); + printCodeLines(prefix, *einfo.nixCode); // hint - cout << prefix << einfo.hint << endl; - cout << prefix << endl; + if (einfo.hint.has_value()) + { + cout << prefix << endl; + cout << prefix << *einfo.hint << endl; + cout << prefix << endl; + } } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 7260dfd5b..f02d7288a 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -1,12 +1,16 @@ #pragma once -#include "types.hh" +#include "util.hh" #include #include #include +#include using std::string; using std::optional; +using boost::format; +using std::cout; +using std::endl; namespace nix { @@ -81,13 +85,13 @@ class ErrorInfo { string name; string description; optional nixCode; - string hint; + optional hint; ErrorInfo& GetEI() { return *this; } static optional programName; // give these access to the private constructor, - // when they are direct descendants. + // when they are direct descendants (children but not grandchildren). friend AddName; friend AddDescription; friend AddNixCode; @@ -150,7 +154,7 @@ class AddDescription : private T }; template -class AddNixFile : public T +class AddNixFile : private T { public: T& nixFile(string filename) { @@ -162,7 +166,7 @@ class AddNixFile : public T }; template -class AddLineNumber : public T +class AddLineNumber : private T { public: T& lineNumber(int lineNumber) { @@ -174,7 +178,7 @@ class AddLineNumber : public T }; template -class AddColumnRange : public T +class AddColumnRange : private T { public: T& columnRange(unsigned int start, unsigned int len) { @@ -186,7 +190,7 @@ class AddColumnRange : public T }; template -class AddLOC : public T +class AddLOC : private T { public: T& linesOfCode(optional prevloc, string loc, optional nextloc) { @@ -199,17 +203,64 @@ class AddLOC : public T ErrorInfo& GetEI() { return T::GetEI(); } }; -typedef AddNixFile> MkNixCode; +template +class yellowify +{ +public: + yellowify(T &s) : value(s) {} + T &value; +}; -typedef AddName> StandardError; -typedef AddName> StandardWarning; +template +std::ostream& operator<<(std::ostream &out, const yellowify &y) +{ + return out << ANSI_YELLOW << y.value << ANSI_NORMAL; +} + +// hint format shows templated values in yellow. +class hintfmt +{ + public: + hintfmt(string format) :fmt(format) {} + template + hintfmt& operator%(const T &value) { fmt % yellowify(value); return *this; } + + template + friend class AddHint; + private: + format fmt; + +}; + +template +class AddHint : private T +{ + public: + T& hint(hintfmt &hfmt) { + GetEI().hint = optional(hfmt.fmt.str()); + return *this; + } + T& nohint() { + GetEI().hint = std::nullopt; + return *this; + } + protected: + ErrorInfo& GetEI() { return T::GetEI(); } +}; + +// -------------------------------------------------------- +// error types + +typedef AddName>> StandardError; +typedef AddName>> StandardWarning; typedef AddName< AddDescription< AddNixFile< AddLineNumber< AddColumnRange< - AddLOC>>>>> MkNixError; + AddLOC< + AddHint>>>>>> MkNixError; typedef AddName< AddDescription< AddNixFile< @@ -217,10 +268,15 @@ typedef AddName< AddColumnRange< AddLOC>>>>> MkNixWarning; + +// -------------------------------------------------------- +// error printing + +void printErrorInfo(ErrorInfo &einfo); + string showErrLine(ErrLine &errLine); -void print_code_lines(string &prefix, NixCode &nix_code); +void printCodeLines(string &prefix, NixCode &nixCode); -void print_error(ErrorInfo &einfo); } diff --git a/tests/errors/main.cc b/tests/errors/main.cc index f53101629..35d2a1cdf 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -8,9 +8,9 @@ using std::nullopt; using std::cout; using std::endl; -int main() { - -using namespace nix; +int main() +{ + using namespace nix; ErrorInfo::programName = optional("errorTest"); @@ -35,19 +35,23 @@ using namespace nix; generic.program = "nixtool.exe"; generic.nixCode = nixcode; - print_error(generic); + printErrorInfo(generic); */ - print_error(StandardError() + printErrorInfo(StandardError() .name("name") - .description("description")); + .description("description") + .nohint() + ); - print_error(StandardWarning() + printErrorInfo(StandardWarning() .name("warning name") - .description("warning description")); + .description("warning description") + .nohint() + ); - print_error(MkNixWarning() + printErrorInfo(MkNixWarning() .name("warning name") .description("warning description") .nixFile("myfile.nix") @@ -57,19 +61,17 @@ using namespace nix; ,"this is the problem line of code" ,nullopt)); - print_error(MkNixError() + printErrorInfo(MkNixError() .name("error name") .description("error description") .nixFile("myfile.nix") .lineNumber(40) .columnRange(13,7) - .linesOfCode(nullopt + .linesOfCode(optional("previous line of code") ,"this is the problem line of code" - ,nullopt)); + ,optional("next line of code")) + .hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values") + ); return 0; } - - - - From 00eb3fcb7a19a38d5ca94f4dcbda149f16e73a6e Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 27 Mar 2020 10:13:46 -0600 Subject: [PATCH 10/46] more cleanup --- src/libutil/error.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index d6595070f..9194539a5 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -104,13 +104,13 @@ void printErrorInfo(ErrorInfo &einfo) } default: { - levelString = "wat:"; + levelString = format("invalid error level: %1%") % einfo.level; break; } } int ndl = prefix.length() + levelString.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); - int dashwidth = ndl > (errwidth - 3) ? 3 : 80 - ndl; + int dashwidth = ndl > (errwidth - 3) ? 3 : errwidth - ndl; string dashes; for (int i = 0; i < dashwidth; ++i) @@ -161,7 +161,6 @@ void printErrorInfo(ErrorInfo &einfo) cout << prefix << *einfo.hint << endl; cout << prefix << endl; } - } } From 759f39800bb80eaa297ea2532b1640959487ed9c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 27 Mar 2020 10:55:09 -0600 Subject: [PATCH 11/46] remove util.hh from deps --- src/libutil/ansicolor.hh | 13 +++++++++++++ src/libutil/error.cc | 2 +- src/libutil/error.hh | 25 ++++++++++++++++--------- src/libutil/util.hh | 10 +--------- 4 files changed, 31 insertions(+), 19 deletions(-) create mode 100644 src/libutil/ansicolor.hh diff --git a/src/libutil/ansicolor.hh b/src/libutil/ansicolor.hh new file mode 100644 index 000000000..390bd4d17 --- /dev/null +++ b/src/libutil/ansicolor.hh @@ -0,0 +1,13 @@ +#pragma once + +namespace nix +{ + /* Some ANSI escape sequences. */ + #define ANSI_NORMAL "\e[0m" + #define ANSI_BOLD "\e[1m" + #define ANSI_FAINT "\e[2m" + #define ANSI_RED "\e[31;1m" + #define ANSI_GREEN "\e[32;1m" + #define ANSI_YELLOW "\e[33;1m" + #define ANSI_BLUE "\e[34;1m" +} diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 9194539a5..c986affcc 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -104,7 +104,7 @@ void printErrorInfo(ErrorInfo &einfo) } default: { - levelString = format("invalid error level: %1%") % einfo.level; + levelString = (format("invalid error level: %1%") % einfo.level).str(); break; } } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index f02d7288a..88980afb7 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -1,11 +1,13 @@ #pragma once -#include "util.hh" +#include "ansicolor.hh" #include #include #include #include +#include + using std::string; using std::optional; using boost::format; @@ -251,8 +253,14 @@ class AddHint : private T // -------------------------------------------------------- // error types -typedef AddName>> StandardError; -typedef AddName>> StandardWarning; +typedef AddName< + AddDescription< + AddHint< + EIError>>> StandardError; +typedef AddName< + AddDescription< + AddHint< + EIWarning>>> StandardWarning; typedef AddName< AddDescription< @@ -260,13 +268,16 @@ typedef AddName< AddLineNumber< AddColumnRange< AddLOC< - AddHint>>>>>> MkNixError; + AddHint< + EIError>>>>>>> MkNixError; typedef AddName< AddDescription< AddNixFile< AddLineNumber< AddColumnRange< - AddLOC>>>>> MkNixWarning; + AddLOC< + AddHint< + EIWarning>>>>>>> MkNixWarning; // -------------------------------------------------------- @@ -274,9 +285,5 @@ typedef AddName< void printErrorInfo(ErrorInfo &einfo); -string showErrLine(ErrLine &errLine); - -void printCodeLines(string &prefix, NixCode &nixCode); - } diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 3bfebcd15..d69e29158 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -2,6 +2,7 @@ #include "types.hh" #include "logging.hh" +#include "ansicolor.hh" #include #include @@ -423,15 +424,6 @@ std::string shellEscape(const std::string & s); void ignoreException(); -/* Some ANSI escape sequences. */ -#define ANSI_NORMAL "\e[0m" -#define ANSI_BOLD "\e[1m" -#define ANSI_FAINT "\e[2m" -#define ANSI_RED "\e[31;1m" -#define ANSI_GREEN "\e[32;1m" -#define ANSI_YELLOW "\e[33;1m" -#define ANSI_BLUE "\e[34;1m" - /* Truncate a string to 'width' printable characters. If 'filterAll' is true, all ANSI escape sequences are filtered out. Otherwise, From 35c7bab09ac97efd3561d3c5a0c827e4dc391141 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 30 Mar 2020 09:14:29 -0600 Subject: [PATCH 12/46] build with make --- Makefile | 3 ++- src/libutil/util.hh | 1 + tests/errors/local.mk | 17 +++++++++++++++++ tests/errors/main.cc | 6 ++++-- 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 tests/errors/local.mk diff --git a/Makefile b/Makefile index 469070533..2d70aeb27 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,8 @@ makefiles = \ misc/upstart/local.mk \ doc/manual/local.mk \ tests/local.mk \ - tests/plugins/local.mk + tests/plugins/local.mk \ + tests/errors/local.mk -include Makefile.config diff --git a/src/libutil/util.hh b/src/libutil/util.hh index d69e29158..0b55c6788 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -3,6 +3,7 @@ #include "types.hh" #include "logging.hh" #include "ansicolor.hh" +#include "error.hh" #include #include diff --git a/tests/errors/local.mk b/tests/errors/local.mk new file mode 100644 index 000000000..c5b9cc5c8 --- /dev/null +++ b/tests/errors/local.mk @@ -0,0 +1,17 @@ +programs += error-test + +error-test_DIR := $(d) + +error-test_SOURCES := \ + $(wildcard $(d)/*.cc) \ + +error-test_LIBS = libutil + +error-test_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system + +# $(foreach name, \ +# nix-build nix-channel nix-collect-garbage nix-copy-closure nix-daemon nix-env nix-hash nix-instantiate nix-prefetch-url nix-shell nix-store, \ +# $(eval $(call install-symlink, nix, $(bindir)/$(name)))) +# $(eval $(call install-symlink, $(bindir)/nix, $(libexecdir)/nix/build-remote)) + +# src/nix-env/user-env.cc: src/nix-env/buildenv.nix.gen.hh diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 35d2a1cdf..39adc2ece 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -12,7 +12,7 @@ int main() { using namespace nix; - ErrorInfo::programName = optional("errorTest"); + ErrorInfo::programName = optional("error-test"); /* ColumnRange columnRange; @@ -59,7 +59,9 @@ int main() .columnRange(13,7) .linesOfCode(nullopt ,"this is the problem line of code" - ,nullopt)); + ,nullopt) + .hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values") + ); printErrorInfo(MkNixError() .name("error name") From 28d073e810d5e692a4f6c57d23afc011e6fcc153 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 30 Mar 2020 09:15:21 -0600 Subject: [PATCH 13/46] remove cruft --- tests/errors/local.mk | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/errors/local.mk b/tests/errors/local.mk index c5b9cc5c8..0d64c8dbd 100644 --- a/tests/errors/local.mk +++ b/tests/errors/local.mk @@ -8,10 +8,3 @@ error-test_SOURCES := \ error-test_LIBS = libutil error-test_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system - -# $(foreach name, \ -# nix-build nix-channel nix-collect-garbage nix-copy-closure nix-daemon nix-env nix-hash nix-instantiate nix-prefetch-url nix-shell nix-store, \ -# $(eval $(call install-symlink, nix, $(bindir)/$(name)))) -# $(eval $(call install-symlink, $(bindir)/nix, $(libexecdir)/nix/build-remote)) - -# src/nix-env/user-env.cc: src/nix-env/buildenv.nix.gen.hh From 09652f597cb44fbb452353f9eeaba2d9bc70a7f3 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 31 Mar 2020 09:36:20 -0600 Subject: [PATCH 14/46] enum style --- src/libutil/error.hh | 4 ++-- tests/errors/main.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 88980afb7..1acc70d9d 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -16,10 +16,10 @@ using std::endl; namespace nix { -enum ErrLevel +typedef enum { elWarning , elError - }; + } ErrLevel; class ColumnRange { public: diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 39adc2ece..ffce334b7 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -40,7 +40,7 @@ int main() printErrorInfo(StandardError() .name("name") - .description("description") + .description("error description") .nohint() ); From 9e7b89bf100500cf252f785e2dd77f83ee5cf7a4 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 31 Mar 2020 11:56:37 -0600 Subject: [PATCH 15/46] rename errors/warnings --- src/libutil/error.hh | 8 ++++---- tests/errors/main.cc | 32 ++++---------------------------- 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 1acc70d9d..cd2b2832d 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -256,11 +256,11 @@ class AddHint : private T typedef AddName< AddDescription< AddHint< - EIError>>> StandardError; + EIError>>> ProgramError; typedef AddName< AddDescription< AddHint< - EIWarning>>> StandardWarning; + EIWarning>>> ProgramWarning; typedef AddName< AddDescription< @@ -269,7 +269,7 @@ typedef AddName< AddColumnRange< AddLOC< AddHint< - EIError>>>>>>> MkNixError; + EIError>>>>>>> NixLangError; typedef AddName< AddDescription< AddNixFile< @@ -277,7 +277,7 @@ typedef AddName< AddColumnRange< AddLOC< AddHint< - EIWarning>>>>>>> MkNixWarning; + EIWarning>>>>>>> NixLangWarning; // -------------------------------------------------------- diff --git a/tests/errors/main.cc b/tests/errors/main.cc index ffce334b7..101d44a7e 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -14,44 +14,20 @@ int main() ErrorInfo::programName = optional("error-test"); - /* - ColumnRange columnRange; - columnRange.start = 24; - columnRange.len = 14; - - ErrLine errline; - errline.lineNumber = 7; - errline.columnRange = optional(columnRange); - errline.errLineOfCode = "line of code where the error occurred"; - - NixCode nixcode; - nixcode.nixFile = optional("myfile.nix"); - nixcode.errLine = errline; - - ErrorInfo generic; - generic.level = elError; - generic.name = "error name"; - generic.description = "general error description"; - generic.program = "nixtool.exe"; - generic.nixCode = nixcode; - - printErrorInfo(generic); - */ - - printErrorInfo(StandardError() + printErrorInfo(ProgramError() .name("name") .description("error description") .nohint() ); - printErrorInfo(StandardWarning() + printErrorInfo(ProgramWarning() .name("warning name") .description("warning description") .nohint() ); - printErrorInfo(MkNixWarning() + printErrorInfo(NixLangWarning() .name("warning name") .description("warning description") .nixFile("myfile.nix") @@ -63,7 +39,7 @@ int main() .hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values") ); - printErrorInfo(MkNixError() + printErrorInfo(NixLangError() .name("error name") .description("error description") .nixFile("myfile.nix") From 5b3aefff857d038d49ad9a5d92371b4f6b19e8b9 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 31 Mar 2020 12:42:41 -0600 Subject: [PATCH 16/46] add some explanatory comments --- src/libutil/error.cc | 4 ++- src/libutil/error.hh | 2 ++ tests/errors/main.cc | 83 +++++++++++++++++++++++++++----------------- 3 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index c986affcc..5384248f8 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -152,12 +152,14 @@ void printErrorInfo(ErrorInfo &einfo) // lines of code. if (einfo.nixCode.has_value()) + { printCodeLines(prefix, *einfo.nixCode); + cout << prefix << endl; + } // hint if (einfo.hint.has_value()) { - cout << prefix << endl; cout << prefix << *einfo.hint << endl; cout << prefix << endl; } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index cd2b2832d..00539f06a 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -257,6 +257,7 @@ typedef AddName< AddDescription< AddHint< EIError>>> ProgramError; + typedef AddName< AddDescription< AddHint< @@ -270,6 +271,7 @@ typedef AddName< AddLOC< AddHint< EIError>>>>>>> NixLangError; + typedef AddName< AddDescription< AddNixFile< diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 101d44a7e..1aff5a016 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -8,48 +8,67 @@ using std::nullopt; using std::cout; using std::endl; + int main() { using namespace nix; + // In each program where errors occur, this has to be set. ErrorInfo::programName = optional("error-test"); - printErrorInfo(ProgramError() - .name("name") - .description("error description") - .nohint() - ); + // There are currently four error types - + // 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. - printErrorInfo(ProgramWarning() - .name("warning name") - .description("warning description") - .nohint() - ); + // ProgramError takes name, description, and an optional hint. + printErrorInfo( + ProgramError() + .name("name") + .description("error description") + .nohint() + ); + // 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") + .hint(hintfmt("there was a %1%") % "warning") // 'warning' will be yellow. + ); - printErrorInfo(NixLangWarning() - .name("warning name") - .description("warning description") - .nixFile("myfile.nix") - .lineNumber(40) - .columnRange(13,7) - .linesOfCode(nullopt - ,"this is the problem line of code" - ,nullopt) - .hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values") - ); + // NixLangWarning adds nix file, line number, column range, and the lines of code + // where a warning occurred. + printErrorInfo( + NixLangWarning() + .name("warning name") + .description("warning description") + .nixFile("myfile.nix") + .lineNumber(40) + .columnRange(13,7) + .linesOfCode(nullopt + ,"this is the problem line of code" + ,nullopt) + .hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values") + ); - printErrorInfo(NixLangError() - .name("error name") - .description("error description") - .nixFile("myfile.nix") - .lineNumber(40) - .columnRange(13,7) - .linesOfCode(optional("previous line of code") - ,"this is the problem line of code" - ,optional("next line of code")) - .hint(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") + .nixFile("myfile.nix") + .lineNumber(40) + .columnRange(13,7) + .linesOfCode(optional("previous line of code") + ,"this is the problem line of code" + ,optional("next line of code")) + .hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values") + ); return 0; } From a72b6b2ec80a8500015315acd36991aad9817907 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 31 Mar 2020 18:29:41 -0600 Subject: [PATCH 17/46] examples of invalid errors --- tests/errors/main.cc | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 1aff5a016..9d08e82ea 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -16,8 +16,10 @@ int main() // In each program where errors occur, this has to be set. ErrorInfo::programName = optional("error-test"); - // There are currently four error types - + // There are currently four error types: + // // 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. @@ -41,6 +43,27 @@ int main() .hint(hintfmt("there was a %1%") % "warning") // 'warning' will be yellow. ); + /* + // 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"); + */ + // NixLangWarning adds nix file, line number, column range, and the lines of code // where a warning occurred. printErrorInfo( From 8713aeac5e29f019286df6dc6c52a2da956972e7 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 1 Apr 2020 15:51:14 -0600 Subject: [PATCH 18/46] remove using std::*, switch to include guard --- src/libutil/error.cc | 6 +- src/libutil/error.hh | 14 ++-- tests/errors/main.cc | 150 +++++++++++++++++++++---------------------- 3 files changed, 78 insertions(+), 92 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 5384248f8..2b7a079dc 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -5,11 +5,7 @@ namespace nix { -using std::cout; -using std::endl; -using std::nullopt; - -optional ErrorInfo::programName = nullopt; +optional ErrorInfo::programName = std::nullopt; // return basic_format? string showErrLine(ErrLine &errLine) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 00539f06a..614f08a35 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -1,4 +1,5 @@ -#pragma once +#ifndef error_hh +#define error_hh #include "ansicolor.hh" #include @@ -8,12 +9,6 @@ #include -using std::string; -using std::optional; -using boost::format; -using std::cout; -using std::endl; - namespace nix { typedef enum @@ -36,7 +31,6 @@ class ErrLine { optional prevLineOfCode; string errLineOfCode; optional nextLineOfCode; - }; class NixCode { @@ -112,8 +106,6 @@ class ErrorInfo { protected: // constructor is protected, so only the builder classes can create an ErrorInfo. ErrorInfo(ErrLevel level) { this->level = level; } - - }; // Init as error @@ -285,7 +277,9 @@ typedef AddName< // -------------------------------------------------------- // error printing +// just to cout for now. void printErrorInfo(ErrorInfo &einfo); } +#endif diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 9d08e82ea..f11390c73 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -3,95 +3,91 @@ #include #include -using std::optional; -using std::nullopt; -using std::cout; -using std::endl; int main() { - using namespace nix; + using namespace nix; - // In each program where errors occur, this has to be set. - ErrorInfo::programName = optional("error-test"); + // In each program where errors occur, this has to be set. + ErrorInfo::programName = optional("error-test"); - // There are currently four error types: - // - // 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. + // There are currently four error types: + // + // 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( - ProgramError() - .name("name") - .description("error description") - .nohint() - ); + // ProgramError takes name, description, and an optional hint. + printErrorInfo( + ProgramError() + .name("name") + .description("error description") + .nohint() + ); - // 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") - .hint(hintfmt("there was a %1%") % "warning") // 'warning' will be yellow. - ); + // 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") + .hint(hintfmt("there was a %1%") % "warning") // 'warning' will be yellow. + ); - /* - // some invalid errors: - - // type error: no hint function. - ProgramError() - .name("name") - .description("error description"); + /* + // 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: 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"); - */ + // type error: hint function with regular boost format, not special hintfmt. + ProgramError() + .description("error description") + .name("name") + .hint(format("there was a %1%") % "warning"); + */ - // NixLangWarning adds nix file, line number, column range, and the lines of code - // where a warning occurred. - printErrorInfo( - NixLangWarning() - .name("warning name") - .description("warning description") - .nixFile("myfile.nix") - .lineNumber(40) - .columnRange(13,7) - .linesOfCode(nullopt - ,"this is the problem line of code" - ,nullopt) - .hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values") - ); + // NixLangWarning adds nix file, line number, column range, and the lines of code + // where a warning occurred. + printErrorInfo( + NixLangWarning() + .name("warning name") + .description("warning description") + .nixFile("myfile.nix") + .lineNumber(40) + .columnRange(13,7) + .linesOfCode(std::nullopt + ,"this is the problem line of code" + ,std::nullopt) + .hint(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") - .nixFile("myfile.nix") - .lineNumber(40) - .columnRange(13,7) - .linesOfCode(optional("previous line of code") - ,"this is the problem line of code" - ,optional("next line of code")) - .hint(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") + .nixFile("myfile.nix") + .lineNumber(40) + .columnRange(13,7) + .linesOfCode(optional("previous line of code") + ,"this is the problem line of code" + ,optional("next line of code")) + .hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values") + ); - return 0; + return 0; } From dd7b8183a5065bc0279d9bd87c27dd0ac91ccd8a Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 1 Apr 2020 16:20:20 -0600 Subject: [PATCH 19/46] indenting --- src/libutil/error.cc | 256 +++++++++++++++++++++---------------------- src/libutil/error.hh | 244 ++++++++++++++++++++--------------------- 2 files changed, 250 insertions(+), 250 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 2b7a079dc..4480e80bf 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -10,155 +10,155 @@ optional ErrorInfo::programName = std::nullopt; // return basic_format? string showErrLine(ErrLine &errLine) { - if (errLine.columnRange.has_value()) - { - return (format("(%1%:%2%)") % errLine.lineNumber % errLine.columnRange->start).str(); - } - else - { - return (format("(%1%)") % errLine.lineNumber).str(); - }; + if (errLine.columnRange.has_value()) + { + return (format("(%1%:%2%)") % errLine.lineNumber % errLine.columnRange->start).str(); + } + else + { + return (format("(%1%)") % errLine.lineNumber).str(); + }; } void printCodeLines(string &prefix, NixCode &nixCode) { - + if (nixCode.errLine.has_value()) - { - // previous line of code. - if (nixCode.errLine->prevLineOfCode.has_value()) { - cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errLine->lineNumber - 1) - % *nixCode.errLine->prevLineOfCode - << endl; - } - - // line of code containing the error.%2$+5d% - cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errLine->lineNumber) - % nixCode.errLine->errLineOfCode - << 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) - { - spaces.append(" "); - } + // previous line of code. + if (nixCode.errLine->prevLineOfCode.has_value()) { + cout << format("%1% %|2$5d|| %3%") + % prefix + % (nixCode.errLine->lineNumber - 1) + % *nixCode.errLine->prevLineOfCode + << endl; + } + + // line of code containing the error.%2$+5d% + cout << format("%1% %|2$5d|| %3%") + % prefix + % (nixCode.errLine->lineNumber) + % nixCode.errLine->errLineOfCode + << 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) + { + spaces.append(" "); + } + + int len = nixCode.errLine->columnRange->len; + std::string arrows; + for (int i = 0; i < len; ++i) + { + arrows.append("^"); + } + + cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << endl; + } + + + + // next line of code. + if (nixCode.errLine->nextLineOfCode.has_value()) { + cout << format("%1% %|2$5d|| %3%") + % prefix + % (nixCode.errLine->lineNumber + 1) + % *nixCode.errLine->nextLineOfCode + << endl; + } - int len = nixCode.errLine->columnRange->len; - std::string arrows; - for (int i = 0; i < len; ++i) - { - arrows.append("^"); - } - - cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << endl; } - - - // next line of code. - if (nixCode.errLine->nextLineOfCode.has_value()) { - cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errLine->lineNumber + 1) - % *nixCode.errLine->nextLineOfCode - << endl; - } - - } - } void printErrorInfo(ErrorInfo &einfo) { - int errwidth = 80; - string prefix = " "; + 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; - } - } - - int ndl = prefix.length() + levelString.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); - int dashwidth = ndl > (errwidth - 3) ? 3 : errwidth - ndl; - - string dashes; - for (int i = 0; i < dashwidth; ++i) - dashes.append("-"); - - // divider. - cout << format("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL) - % prefix - % levelString - % "---" - % einfo.name - % dashes - % einfo.programName.value_or("") - << endl; - - // filename. - if (einfo.nixCode.has_value()) - { - if (einfo.nixCode->nixFile.has_value()) + string levelString; + switch (einfo.level) { - string eline = einfo.nixCode->errLine.has_value() - ? string(" ") + showErrLine(*einfo.nixCode->errLine) - : ""; - - cout << format("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL) - % prefix % *einfo.nixCode->nixFile % eline << endl; - cout << prefix << endl; + 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; + } } - else + + int ndl = prefix.length() + levelString.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); + int dashwidth = ndl > (errwidth - 3) ? 3 : errwidth - ndl; + + string dashes; + for (int i = 0; i < dashwidth; ++i) + dashes.append("-"); + + // divider. + cout << format("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL) + % prefix + % levelString + % "---" + % einfo.name + % dashes + % einfo.programName.value_or("") + << endl; + + // filename. + if (einfo.nixCode.has_value()) { - cout << format("%1%from command line argument") % prefix << endl; - cout << prefix << endl; + if (einfo.nixCode->nixFile.has_value()) + { + string eline = einfo.nixCode->errLine.has_value() + ? string(" ") + showErrLine(*einfo.nixCode->errLine) + : ""; + + cout << format("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL) + % prefix % *einfo.nixCode->nixFile % eline << endl; + cout << prefix << endl; + } + else + { + cout << format("%1%from command line argument") % prefix << endl; + cout << prefix << endl; + } } - } - // description - cout << prefix << einfo.description << endl; - cout << prefix << endl; - - // lines of code. - if (einfo.nixCode.has_value()) - { - printCodeLines(prefix, *einfo.nixCode); + // description + cout << prefix << einfo.description << endl; cout << prefix << endl; - } - // hint - if (einfo.hint.has_value()) - { - cout << prefix << *einfo.hint << endl; - cout << prefix << endl; - } + // lines of code. + if (einfo.nixCode.has_value()) + { + printCodeLines(prefix, *einfo.nixCode); + cout << prefix << endl; + } + + // hint + if (einfo.hint.has_value()) + { + cout << prefix << *einfo.hint << endl; + cout << prefix << endl; + } } } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 614f08a35..00c32ff21 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -11,45 +11,45 @@ namespace nix { -typedef enum - { elWarning - , elError - } ErrLevel; +typedef enum { + elWarning + , elError + } ErrLevel; class ColumnRange { - public: - unsigned int start; - unsigned int len; + public: + unsigned int start; + unsigned int len; }; class ErrorInfo; class ErrLine { - public: - int lineNumber; - optional columnRange; - optional prevLineOfCode; - string errLineOfCode; - optional nextLineOfCode; + public: + int lineNumber; + optional columnRange; + optional prevLineOfCode; + string errLineOfCode; + optional nextLineOfCode; }; class NixCode { - public: - optional nixFile; - optional errLine; + public: + optional nixFile; + optional errLine; - ErrLine& ensureErrLine() - { - if (!this->errLine.has_value()) - this->errLine = optional(ErrLine()); - return *this->errLine; - } + ErrLine& ensureErrLine() + { + if (!this->errLine.has_value()) + this->errLine = optional(ErrLine()); + return *this->errLine; + } }; // ------------------------------------------------- // ErrorInfo. -// Forward friend class declarations. "builder classes" +// Forward friend class declarations. "builder classes" template class AddName; @@ -76,170 +76,170 @@ class AddLOC; // The error info class itself. class ErrorInfo { - public: - ErrLevel level; - string name; - string description; - optional nixCode; - optional hint; - ErrorInfo& GetEI() { return *this; } + public: + ErrLevel level; + string name; + string description; + optional nixCode; + optional hint; + ErrorInfo& GetEI() { return *this; } - static optional programName; + static optional programName; - // give these access to the private constructor, - // when they are direct descendants (children but not grandchildren). - friend AddName; - friend AddDescription; - friend AddNixCode; - friend AddNixFile; - friend AddErrLine; - friend AddLineNumber; - friend AddColumnRange; - friend AddLOC; - - NixCode& ensureNixCode() - { - if (!this->nixCode.has_value()) - this->nixCode = optional(NixCode()); - return *this->nixCode; - } - protected: - // constructor is protected, so only the builder classes can create an ErrorInfo. - ErrorInfo(ErrLevel level) { this->level = level; } + // give these access to the private constructor, + // when they are direct descendants (children but not grandchildren). + friend AddName; + friend AddDescription; + friend AddNixCode; + friend AddNixFile; + friend AddErrLine; + friend AddLineNumber; + friend AddColumnRange; + friend AddLOC; + + NixCode& ensureNixCode() + { + if (!this->nixCode.has_value()) + this->nixCode = 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 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 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 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 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 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 AddLOC : private T { - public: - T& linesOfCode(optional prevloc, string loc, 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(); } + public: + T& linesOfCode(optional prevloc, string loc, 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(); } }; template class yellowify { public: - yellowify(T &s) : value(s) {} - T &value; + yellowify(T &s) : value(s) {} + T &value; }; template std::ostream& operator<<(std::ostream &out, const yellowify &y) { - return out << ANSI_YELLOW << y.value << ANSI_NORMAL; + return out << ANSI_YELLOW << y.value << ANSI_NORMAL; } // hint format shows templated values in yellow. class hintfmt { - public: - hintfmt(string format) :fmt(format) {} - template - hintfmt& operator%(const T &value) { fmt % yellowify(value); return *this; } + public: + hintfmt(string format) :fmt(format) {} + template + hintfmt& operator%(const T &value) { fmt % yellowify(value); return *this; } + + template + friend class AddHint; + private: + format fmt; - template - friend class AddHint; - private: - format fmt; - }; template class AddHint : private T { - public: - T& hint(hintfmt &hfmt) { - GetEI().hint = 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 = optional(hfmt.fmt.str()); + return *this; + } + T& nohint() { + GetEI().hint = std::nullopt; + return *this; + } + protected: + ErrorInfo& GetEI() { return T::GetEI(); } }; // -------------------------------------------------------- From e697884f654fb48f0fee05de25910b27fa147f07 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 1 Apr 2020 21:30:19 -0600 Subject: [PATCH 20/46] using std:: everywhere; fix a formatting error; add exception flags --- src/libutil/error.cc | 41 ++++++++++++++++++++--------------------- src/libutil/error.hh | 35 +++++++++++++++++++++-------------- tests/errors/main.cc | 8 +++----- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 4480e80bf..04da075ed 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -5,9 +5,8 @@ namespace nix { -optional ErrorInfo::programName = std::nullopt; +std::optional ErrorInfo::programName = std::nullopt; -// return basic_format? string showErrLine(ErrLine &errLine) { if (errLine.columnRange.has_value()) @@ -27,19 +26,19 @@ void printCodeLines(string &prefix, NixCode &nixCode) { // previous line of code. if (nixCode.errLine->prevLineOfCode.has_value()) { - cout << format("%1% %|2$5d|| %3%") + std::cout << format("%1% %|2$5d|| %3%") % prefix % (nixCode.errLine->lineNumber - 1) % *nixCode.errLine->prevLineOfCode - << endl; + << std::endl; } // line of code containing the error.%2$+5d% - cout << format("%1% %|2$5d|| %3%") + std::cout << format("%1% %|2$5d|| %3%") % prefix % (nixCode.errLine->lineNumber) % nixCode.errLine->errLineOfCode - << endl; + << std::endl; // error arrows for the column range. if (nixCode.errLine->columnRange.has_value()) @@ -58,18 +57,18 @@ void printCodeLines(string &prefix, NixCode &nixCode) arrows.append("^"); } - cout << format("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL) % prefix % spaces % arrows << 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()) { - cout << format("%1% %|2$5d|| %3%") + std::cout << format("%1% %|2$5d|| %3%") % prefix % (nixCode.errLine->lineNumber + 1) % *nixCode.errLine->nextLineOfCode - << endl; + << std::endl; } } @@ -113,14 +112,14 @@ void printErrorInfo(ErrorInfo &einfo) dashes.append("-"); // divider. - cout << format("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL) + std::cout << format("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL) % prefix % levelString % "---" % einfo.name % dashes % einfo.programName.value_or("") - << endl; + << std::endl; // filename. if (einfo.nixCode.has_value()) @@ -131,33 +130,33 @@ void printErrorInfo(ErrorInfo &einfo) ? string(" ") + showErrLine(*einfo.nixCode->errLine) : ""; - cout << format("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL) - % prefix % *einfo.nixCode->nixFile % eline << endl; - cout << prefix << 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 { - cout << format("%1%from command line argument") % prefix << endl; - cout << prefix << endl; + std::cout << format("%1%from command line argument") % prefix << std::endl; + std::cout << prefix << std::endl; } } // description - cout << prefix << einfo.description << endl; - cout << prefix << endl; + std::cout << prefix << einfo.description << std::endl; + std::cout << prefix << std::endl; // lines of code. if (einfo.nixCode.has_value()) { printCodeLines(prefix, *einfo.nixCode); - cout << prefix << endl; + std::cout << prefix << std::endl; } // hint if (einfo.hint.has_value()) { - cout << prefix << *einfo.hint << endl; - cout << prefix << endl; + 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 00c32ff21..9dcb42e14 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -27,21 +27,21 @@ class ErrorInfo; class ErrLine { public: int lineNumber; - optional columnRange; - optional prevLineOfCode; + std::optional columnRange; + std::optional prevLineOfCode; string errLineOfCode; - optional nextLineOfCode; + std::optional nextLineOfCode; }; class NixCode { public: - optional nixFile; - optional errLine; + std::optional nixFile; + std::optional errLine; ErrLine& ensureErrLine() { if (!this->errLine.has_value()) - this->errLine = optional(ErrLine()); + this->errLine = std::optional(ErrLine()); return *this->errLine; } }; @@ -80,11 +80,11 @@ class ErrorInfo { ErrLevel level; string name; string description; - optional nixCode; - optional hint; + std::optional nixCode; + std::optional hint; ErrorInfo& GetEI() { return *this; } - static optional programName; + static std::optional programName; // give these access to the private constructor, // when they are direct descendants (children but not grandchildren). @@ -100,7 +100,7 @@ class ErrorInfo { NixCode& ensureNixCode() { if (!this->nixCode.has_value()) - this->nixCode = optional(NixCode()); + this->nixCode = std::optional(NixCode()); return *this->nixCode; } protected: @@ -187,7 +187,7 @@ template class AddLOC : private T { public: - T& linesOfCode(optional prevloc, string loc, optional nextloc) { + 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; @@ -197,6 +197,11 @@ class AddLOC : private T ErrorInfo& GetEI() { return T::GetEI(); } }; + +// ---------------------------------------------------------------- +// format for hints. same as boost format, except templated values +// are always in yellow. + template class yellowify { @@ -211,11 +216,12 @@ std::ostream& operator<<(std::ostream &out, const yellowify &y) return out << ANSI_YELLOW << y.value << ANSI_NORMAL; } -// hint format shows templated values in yellow. class hintfmt { public: - hintfmt(string format) :fmt(format) {} + hintfmt(string format) :fmt(format) { + fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); + } template hintfmt& operator%(const T &value) { fmt % yellowify(value); return *this; } @@ -226,12 +232,13 @@ class hintfmt }; +// the template layer for adding a hint. template class AddHint : private T { public: T& hint(hintfmt &hfmt) { - GetEI().hint = optional(hfmt.fmt.str()); + GetEI().hint = std::optional(hfmt.fmt.str()); return *this; } T& nohint() { diff --git a/tests/errors/main.cc b/tests/errors/main.cc index f11390c73..870af75d3 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -3,14 +3,12 @@ #include #include - - int main() { using namespace nix; // In each program where errors occur, this has to be set. - ErrorInfo::programName = optional("error-test"); + ErrorInfo::programName = std::optional("error-test"); // There are currently four error types: // @@ -83,9 +81,9 @@ int main() .nixFile("myfile.nix") .lineNumber(40) .columnRange(13,7) - .linesOfCode(optional("previous line of code") + .linesOfCode(std::optional("previous line of code") ,"this is the problem line of code" - ,optional("next line of code")) + ,std::optional("next line of code")) .hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values") ); From b85ba3e30da663a00847a30fd9ceb1bc8284bafc Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 2 Apr 2020 14:08:05 -0600 Subject: [PATCH 21/46] full include path --- tests/errors/main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 870af75d3..5de36a37d 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -1,4 +1,4 @@ -#include "error.hh" +#include "../../src/libutil/error.hh" #include #include From 1c329ca433e78ba9018a54f5d499c7cabe3c7b66 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 2 Apr 2020 14:25:43 -0600 Subject: [PATCH 22/46] indenting --- src/libutil/error.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 9dcb42e14..32571d97f 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -12,9 +12,9 @@ namespace nix { typedef enum { - elWarning - , elError - } ErrLevel; + elWarning, + elError +} ErrLevel; class ColumnRange { public: From c6b3fcddb0d05718ec11807ad847d7bf60cc703f Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 2 Apr 2020 16:02:40 -0600 Subject: [PATCH 23/46] formatted with astyle --- src/libutil/error.cc | 136 ++++++++--------- src/libutil/error.hh | 351 ++++++++++++++++++++++++------------------- tests/errors/main.cc | 103 ++++++------- 3 files changed, 308 insertions(+), 282 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 #include -namespace nix { +namespace nix +{ std::optional 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; + % prefix + % (nixCode.errLine->lineNumber) + % nixCode.errLine->errLineOfCode + << std::endl; - // error arrows for the column range. - if (nixCode.errLine->columnRange.has_value()) - { + // 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 -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; - std::optional prevLineOfCode; - string errLineOfCode; - std::optional nextLineOfCode; +class ErrLine +{ +public: + int lineNumber; + std::optional columnRange; + std::optional prevLineOfCode; + string errLineOfCode; + std::optional nextLineOfCode; }; -class NixCode { - public: - std::optional nixFile; - std::optional errLine; +class NixCode +{ +public: + std::optional nixFile; + std::optional errLine; - ErrLine& ensureErrLine() - { - if (!this->errLine.has_value()) - this->errLine = std::optional(ErrLine()); - return *this->errLine; - } + ErrLine& ensureErrLine() + { + if (!this->errLine.has_value()) + this->errLine = std::optional(ErrLine()); + return *this->errLine; + } }; // ------------------------------------------------- @@ -65,149 +69,180 @@ class AddNixFile; template class AddErrLine; -template +template class AddLineNumber; -template +template class AddColumnRange; -template +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; } +class ErrorInfo +{ +public: + ErrLevel level; + string name; + string description; + std::optional nixCode; + std::optional hint; + ErrorInfo& GetEI() + { + return *this; + } - static std::optional programName; + 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 AddNixCode; - friend AddNixFile; - friend AddErrLine; - friend AddLineNumber; - friend AddColumnRange; - friend AddLOC; + // give these access to the private constructor, + // when they are direct descendants (children but not grandchildren). + friend AddName; + friend AddDescription; + friend AddNixCode; + friend AddNixFile; + friend AddErrLine; + friend AddLineNumber; + friend AddColumnRange; + 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; } + 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 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 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 +template 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 +template 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 +template 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 +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(); } +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 boost format, except templated values +// format for hints. same as boost format, except templated values // are always in yellow. template class yellowify { public: - yellowify(T &s) : value(s) {} - T &value; + yellowify(T &s) : value(s) {} + T &value; }; template @@ -216,69 +251,79 @@ std::ostream& operator<<(std::ostream &out, const yellowify &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 - hintfmt& operator%(const T &value) { fmt % yellowify(value); return *this; } +public: + hintfmt(string format) :fmt(format) + { + fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); + } + template + hintfmt& operator%(const T &value) + { + fmt % yellowify(value); + return *this; + } - template - friend class AddHint; - private: - format fmt; + template + friend class AddHint; +private: + format fmt; }; // the template layer for adding a hint. -template +template 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; // -------------------------------------------------------- diff --git a/tests/errors/main.cc b/tests/errors/main.cc index 5de36a37d..e035882e7 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -1,45 +1,45 @@ #include "../../src/libutil/error.hh" -#include #include +#include -int main() +int main() { - using namespace nix; + using namespace nix; // In each program where errors occur, this has to be set. ErrorInfo::programName = std::optional("error-test"); // There are currently four error types: - // + // // 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. + // 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( - ProgramError() - .name("name") - .description("error description") - .nohint() - ); + printErrorInfo( ProgramError() + .name("name") + .description("error description") + .nohint() + ); // 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") - .hint(hintfmt("there was a %1%") % "warning") // 'warning' will be yellow. - ); + // 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") + .hint(hintfmt("there was a %1%") % + "warning") // 'warning' will be yellow. + ); /* // some invalid errors: - + // type error: no hint function. ProgramError() .name("name") @@ -51,41 +51,38 @@ int main() .name("name") .nohint(); - // type error: hint function with regular boost format, not special hintfmt. - ProgramError() - .description("error description") - .name("name") + // type error: hint function with regular boost format, not special + hintfmt. ProgramError() .description("error description") .name("name") .hint(format("there was a %1%") % "warning"); */ - // NixLangWarning adds nix file, line number, column range, and the lines of code - // where a warning occurred. - printErrorInfo( - NixLangWarning() - .name("warning name") - .description("warning description") - .nixFile("myfile.nix") - .lineNumber(40) - .columnRange(13,7) - .linesOfCode(std::nullopt - ,"this is the problem line of code" - ,std::nullopt) - .hint(hintfmt("this hint has %1% templated %2%!!") % "yellow" % "values") - ); + // NixLangWarning adds nix file, line number, column range, and the lines of + // code where a warning occurred. + printErrorInfo(NixLangWarning() + .name("warning name") + .description("warning description") + .nixFile("myfile.nix") + .lineNumber(40) + .columnRange(13, 7) + .linesOfCode(std::nullopt, + "this is the problem line of code", + std::nullopt) + .hint(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") - .nixFile("myfile.nix") - .lineNumber(40) - .columnRange(13,7) - .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") - ); + // NixLangError is just the same as NixLangWarning, except for the Error + // flag. + printErrorInfo(NixLangError() + .name("error name") + .description("error description") + .nixFile("myfile.nix") + .lineNumber(40) + .columnRange(13, 7) + .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; } From 7b7801d3f0e0e1cd32b1279979970ad71b66b879 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 3 Apr 2020 08:48:20 -0600 Subject: [PATCH 24/46] variadic args for hint format --- src/libutil/error.hh | 26 ++++++++++++++++++++------ src/libutil/types.hh | 10 ++++++---- tests/errors/main.cc | 10 ++++------ 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 70884c189..1c5d6d13c 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -7,6 +7,7 @@ #include #include +#include "types.hh" #include namespace nix @@ -234,7 +235,7 @@ protected: // ---------------------------------------------------------------- -// format for hints. same as boost format, except templated values +// format for hints. same as fmt, except templated values // are always in yellow. template @@ -251,20 +252,25 @@ std::ostream& operator<<(std::ostream &out, const yellowify &y) return out << ANSI_YELLOW << y.value << ANSI_NORMAL; } -class hintfmt +class hintformat { public: - hintfmt(string format) :fmt(format) + hintformat(string format) :fmt(format) { fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); } template - hintfmt& operator%(const T &value) + hintformat& operator%(const T &value) { fmt % yellowify(value); return *this; } + std::string str() const + { + return fmt.str(); + } + template friend class AddHint; private: @@ -272,14 +278,22 @@ private: }; +template +inline hintformat hintfmt(const std::string & fs, const Args & ... args) +{ + hintformat f(fs); + formatHelper(f, args...); + return f; +} + // the template layer for adding a hint. template class AddHint : private T { public: - T& hint(hintfmt &hfmt) + T& hint(const hintformat &hf) { - GetEI().hint = std::optional(hfmt.fmt.str()); + GetEI().hint = std::optional(hf.str()); return *this; } T& nohint() diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 20b96a85c..981af528b 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -41,7 +41,8 @@ struct FormatOrString { string s; FormatOrString(const string & s) : s(s) { }; - FormatOrString(const format & f) : s(f.str()) { }; + template + FormatOrString(const F & f) : s(f.str()) { }; FormatOrString(const char * s) : s(s) { }; }; @@ -51,12 +52,13 @@ struct FormatOrString ... a_n’. However, ‘fmt(s)’ is equivalent to ‘s’ (so no %-expansion takes place). */ -inline void formatHelper(boost::format & f) +template +inline void formatHelper(F & f) { } -template -inline void formatHelper(boost::format & f, const T & x, const Args & ... args) +template +inline void formatHelper(F & f, const T & x, const Args & ... args) { formatHelper(f % x, args...); } diff --git a/tests/errors/main.cc b/tests/errors/main.cc index e035882e7..be98bd5b8 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -33,8 +33,8 @@ int main() printErrorInfo( ProgramWarning() .name("warning name") .description("warning description") - .hint(hintfmt("there was a %1%") % - "warning") // 'warning' will be yellow. + // the templated value, 'warning', is automatically colored yellow. + .hint(hintfmt("there was a %1%", "warning")) ); /* @@ -67,8 +67,7 @@ int main() .linesOfCode(std::nullopt, "this is the problem line of code", std::nullopt) - .hint(hintfmt("this hint has %1% templated %2%!!") % - "yellow" % "values")); + .hint(hintfmt("this hint has %1% templated %2%!!", "yellow" , "values"))); // NixLangError is just the same as NixLangWarning, except for the Error // flag. @@ -81,8 +80,7 @@ int main() .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")); + .hint(hintfmt("this hint has %1% templated %2%!!", "yellow", "values"))); return 0; } From 9bb528d3920559454a1ce0f8f4ac3ba58b18f6d1 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 3 Apr 2020 13:15:59 -0600 Subject: [PATCH 25/46] handle Pos instead of individual file/line/columnrange args --- src/libutil/error.hh | 98 +++++++++++--------------------------------- tests/errors/main.cc | 13 +++--- 2 files changed, 31 insertions(+), 80 deletions(-) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 1c5d6d13c..57a9944be 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -8,7 +8,6 @@ #include #include "types.hh" -#include namespace nix { @@ -62,19 +61,7 @@ template class AddDescription; template -class AddNixCode; - -template -class AddNixFile; - -template -class AddErrLine; - -template -class AddLineNumber; - -template -class AddColumnRange; +class AddPos; template class AddLOC; @@ -99,11 +86,7 @@ public: // when they are direct descendants (children but not grandchildren). friend AddName; friend AddDescription; - friend AddNixCode; - friend AddNixFile; - friend AddErrLine; - friend AddLineNumber; - friend AddColumnRange; + friend AddPos; friend AddLOC; NixCode& ensureNixCode() @@ -168,44 +151,15 @@ protected: }; template -class AddNixFile : private T +class AddPos : private T { public: - T& nixFile(string filename) + template + T& pos(const P &aPos) { - GetEI().ensureNixCode().nixFile = filename; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; - -template -class AddLineNumber : private T -{ -public: - T& lineNumber(int lineNumber) - { - GetEI().ensureNixCode().ensureErrLine().lineNumber = lineNumber; - return *this; - } -protected: - ErrorInfo& GetEI() - { - return T::GetEI(); - } -}; - -template -class AddColumnRange : private T -{ -public: - T& columnRange(unsigned int start, unsigned int len) - { - GetEI().ensureNixCode().ensureErrLine().columnRange = { start, len }; + GetEI().ensureNixCode().nixFile = aPos.file; + GetEI().ensureNixCode().ensureErrLine().lineNumber = aPos.line; + GetEI().ensureNixCode().ensureErrLine().columnRange = { .start = aPos.column, .len = 1 }; return *this; } protected: @@ -312,32 +266,28 @@ protected: // 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< + AddPos< + AddLOC< + AddHint< + EIError>>>>> NixLangError; typedef AddName< -AddDescription< -AddNixFile< -AddLineNumber< -AddColumnRange< -AddLOC< -AddHint< -EIWarning>>>>>>> NixLangWarning; + AddDescription< + AddPos< + AddLOC< + AddHint< + EIWarning>>>>> NixLangWarning; // -------------------------------------------------------- diff --git a/tests/errors/main.cc b/tests/errors/main.cc index be98bd5b8..cd6ca7caf 100644 --- a/tests/errors/main.cc +++ b/tests/errors/main.cc @@ -1,4 +1,5 @@ #include "../../src/libutil/error.hh" +#include "../../src/libexpr/nixexpr.hh" #include #include @@ -58,12 +59,14 @@ int main() // 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(NixLangWarning() .name("warning name") .description("warning description") - .nixFile("myfile.nix") - .lineNumber(40) - .columnRange(13, 7) + .pos(Pos(problem_symbol, 40, 13)) .linesOfCode(std::nullopt, "this is the problem line of code", std::nullopt) @@ -74,9 +77,7 @@ int main() printErrorInfo(NixLangError() .name("error name") .description("error description") - .nixFile("myfile.nix") - .lineNumber(40) - .columnRange(13, 7) + .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")) From 9a8b3e97477f1621d8dc5a968217e4b44eaf59a8 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 3 Apr 2020 14:55:26 -0600 Subject: [PATCH 26/46] move out of tests/ --- Makefile | 2 +- tests/errors/main.cc => src/error-demo/error-demo.cc | 6 +++--- src/error-demo/local.mk | 10 ++++++++++ tests/errors/local.mk | 10 ---------- 4 files changed, 14 insertions(+), 14 deletions(-) rename tests/errors/main.cc => src/error-demo/error-demo.cc (95%) create mode 100644 src/error-demo/local.mk delete mode 100644 tests/errors/local.mk diff --git a/Makefile b/Makefile index 2d70aeb27..4fac27c47 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ makefiles = \ doc/manual/local.mk \ tests/local.mk \ tests/plugins/local.mk \ - tests/errors/local.mk + src/error-demo/local.mk -include Makefile.config diff --git a/tests/errors/main.cc b/src/error-demo/error-demo.cc similarity index 95% rename from tests/errors/main.cc rename to src/error-demo/error-demo.cc index cd6ca7caf..8fb20d38c 100644 --- a/tests/errors/main.cc +++ b/src/error-demo/error-demo.cc @@ -1,5 +1,5 @@ -#include "../../src/libutil/error.hh" -#include "../../src/libexpr/nixexpr.hh" +#include "error.hh" +#include "nixexpr.hh" #include #include @@ -9,7 +9,7 @@ int main() using namespace nix; // In each program where errors occur, this has to be set. - ErrorInfo::programName = std::optional("error-test"); + ErrorInfo::programName = std::optional("error-demo"); // There are currently four error types: // diff --git a/src/error-demo/local.mk b/src/error-demo/local.mk new file mode 100644 index 000000000..121cab9e3 --- /dev/null +++ b/src/error-demo/local.mk @@ -0,0 +1,10 @@ +programs += error-demo + +error-demo_DIR := $(d) + +error-demo_SOURCES := \ + $(wildcard $(d)/*.cc) \ + +error-demo_LIBS = libutil + +error-demo_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system diff --git a/tests/errors/local.mk b/tests/errors/local.mk deleted file mode 100644 index 0d64c8dbd..000000000 --- a/tests/errors/local.mk +++ /dev/null @@ -1,10 +0,0 @@ -programs += error-test - -error-test_DIR := $(d) - -error-test_SOURCES := \ - $(wildcard $(d)/*.cc) \ - -error-test_LIBS = libutil - -error-test_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system From 1221ae3dd07959d47d9f27e9d2271671003d2bed Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 5 Apr 2020 07:12:16 -0600 Subject: [PATCH 27/46] libexpr --- src/error-demo/local.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error-demo/local.mk b/src/error-demo/local.mk index 121cab9e3..2cb2a0dc4 100644 --- a/src/error-demo/local.mk +++ b/src/error-demo/local.mk @@ -5,6 +5,6 @@ error-demo_DIR := $(d) error-demo_SOURCES := \ $(wildcard $(d)/*.cc) \ -error-demo_LIBS = libutil +error-demo_LIBS = libutil libexpr error-demo_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system From 85f14c4582ae3e64d7423ac48daaa0ea437fc144 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 6 Apr 2020 11:15:01 -0600 Subject: [PATCH 28/46] add libutil, libexpr include dirs --- src/error-demo/local.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/error-demo/local.mk b/src/error-demo/local.mk index 2cb2a0dc4..2c528490a 100644 --- a/src/error-demo/local.mk +++ b/src/error-demo/local.mk @@ -5,6 +5,8 @@ error-demo_DIR := $(d) error-demo_SOURCES := \ $(wildcard $(d)/*.cc) \ +error-demo_CXXFLAGS += -I src/libutil -I src/libexpr + error-demo_LIBS = libutil libexpr error-demo_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system From 2248cc6716ad5a9a56f9368e3cf6784a01cbb646 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 6 Apr 2020 12:05:17 -0600 Subject: [PATCH 29/46] ignore error-demo --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e3186fa76..ad5684123 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,8 @@ perl/Makefile.config /src/nix-copy-closure/nix-copy-closure +/src/error-demo/error-demo + /src/build-remote/build-remote # /tests/ From ec449c845056dad43eeec4d6ff983002f038cf69 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 6 Apr 2020 19:43:22 -0600 Subject: [PATCH 30/46] 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 31/46] 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 20c0984a46b6fbc1be0b073f14f5e20b7c82a26a Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 7 Apr 2020 10:14:15 -0600 Subject: [PATCH 32/46] remove columnrange; switch to fmt in error.cc --- src/libutil/error.cc | 68 ++++++++++++++++++++++---------------------- src/libutil/error.hh | 11 ++----- 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 8ab4a2dea..106ea127e 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -10,10 +10,10 @@ std::optional ErrorInfo::programName = std::nullopt; string showErrLine(ErrLine &errLine) { - if (errLine.columnRange.has_value()) { - return (format("(%1%:%2%)") % errLine.lineNumber % errLine.columnRange->start).str(); + if (errLine.column > 0) { + return fmt("(%1%:%2%)", errLine.lineNumber, errLine.column); } else { - return (format("(%1%)") % errLine.lineNumber).str(); + return fmt("(%1%)", errLine.lineNumber); }; } @@ -23,45 +23,45 @@ void printCodeLines(string &prefix, NixCode &nixCode) if (nixCode.errLine.has_value()) { // previous line of code. if (nixCode.errLine->prevLineOfCode.has_value()) { - std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errLine->lineNumber - 1) - % *nixCode.errLine->prevLineOfCode + std::cout << fmt("%1% %|2$5d|| %3%", + 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::cout << fmt("%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()) { - 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("^"); - } + // for now, length of 1. + 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.errLine->nextLineOfCode.has_value()) { - std::cout << format("%1% %|2$5d|| %3%") - % prefix - % (nixCode.errLine->lineNumber + 1) - % *nixCode.errLine->nextLineOfCode + std::cout << fmt("%1% %|2$5d|| %3%", + prefix, + (nixCode.errLine->lineNumber + 1), + *nixCode.errLine->nextLineOfCode) << std::endl; } @@ -89,7 +89,7 @@ void printErrorInfo(ErrorInfo &einfo) break; } default: { - levelString = (format("invalid error level: %1%") % einfo.level).str(); + levelString = fmt("invalid error level: %1%", einfo.level); break; } } @@ -102,13 +102,13 @@ void printErrorInfo(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. @@ -118,11 +118,11 @@ void printErrorInfo(ErrorInfo &einfo) ? 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 << fmt("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL + , prefix, *einfo.nixCode->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; } } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 57a9944be..664bfbb5a 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; @@ -159,7 +152,7 @@ public: { GetEI().ensureNixCode().nixFile = aPos.file; GetEI().ensureNixCode().ensureErrLine().lineNumber = aPos.line; - GetEI().ensureNixCode().ensureErrLine().columnRange = { .start = aPos.column, .len = 1 }; + GetEI().ensureNixCode().ensureErrLine().column = aPos.column; return *this; } protected: From 00c507cc52ceb0d879c43e88e70de0028ff47fc6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 7 Apr 2020 14:36:32 -0600 Subject: [PATCH 33/46] 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 34/46] 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 35/46] 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 36/46] 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 37/46] 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 38/46] 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; } } From 057e5b6b2e8bf7977c1f57d6f80cc17aa40096d9 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 15 Apr 2020 10:09:43 -0600 Subject: [PATCH 39/46] move implementation to cc --- src/libutil/error.cc | 5 +++++ src/libutil/error.hh | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 40354cc87..a5571d4ec 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -8,6 +8,11 @@ namespace nix std::optional ErrorInfo::programName = std::nullopt; +std::ostream& operator<<(std::ostream &os, const hintformat &hf) +{ + return os << hf.str(); +} + string showErrPos(const ErrPos &errPos) { if (errPos.column > 0) { diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 8286eaab1..5658e6335 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -92,10 +92,7 @@ private: format fmt; }; -std::ostream& operator<<(std::ostream &os, const hintformat &hf) -{ - return os << hf.str(); -} +std::ostream& operator<<(std::ostream &os, const hintformat &hf); template inline hintformat hintfmt(const std::string & fs, const Args & ... args) From b865b5b40c13cfff32e1a0ab685baff1bef5ae5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 16 Apr 2020 12:32:07 +0200 Subject: [PATCH 40/46] pass Pos to forceValue to improve infinite recursion error --- src/libexpr/eval-inline.hh | 4 +-- src/libexpr/eval.cc | 6 ++-- src/libexpr/primops.cc | 64 +++++++++++++++++++------------------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh index c27116e3b..942cda1ea 100644 --- a/src/libexpr/eval-inline.hh +++ b/src/libexpr/eval-inline.hh @@ -57,7 +57,7 @@ inline void EvalState::forceAttrs(Value & v) inline void EvalState::forceAttrs(Value & v, const Pos & pos) { - forceValue(v); + forceValue(v, pos); if (v.type != tAttrs) throwTypeError("value is %1% while a set was expected, at %2%", v, pos); } @@ -73,7 +73,7 @@ inline void EvalState::forceList(Value & v) inline void EvalState::forceList(Value & v, const Pos & pos) { - forceValue(v); + forceValue(v, pos); if (!v.isList()) throwTypeError("value is %1% while a list was expected, at %2%", v, pos); } diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f963a42ca..3b4d9bfdc 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1502,7 +1502,7 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) bool EvalState::forceBool(Value & v, const Pos & pos) { - forceValue(v); + forceValue(v, pos); if (v.type != tBool) throwTypeError("value is %1% while a Boolean was expected, at %2%", v, pos); return v.boolean; @@ -1517,7 +1517,7 @@ bool EvalState::isFunctor(Value & fun) void EvalState::forceFunction(Value & v, const Pos & pos) { - forceValue(v); + forceValue(v, pos); if (v.type != tLambda && v.type != tPrimOp && v.type != tPrimOpApp && !isFunctor(v)) throwTypeError("value is %1% while a function was expected, at %2%", v, pos); } @@ -1594,7 +1594,7 @@ std::optional EvalState::tryAttrsToString(const Pos & pos, Value & v, string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, bool coerceMore, bool copyToStore) { - forceValue(v); + forceValue(v, pos); string s; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index fc6c8296b..a00b93676 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -241,7 +241,7 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v) /* Return a string representing the type of the expression. */ static void prim_typeOf(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); string t; switch (args[0]->type) { case tInt: t = "int"; break; @@ -269,7 +269,7 @@ static void prim_typeOf(EvalState & state, const Pos & pos, Value * * args, Valu /* Determine whether the argument is the null value. */ static void prim_isNull(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); mkBool(v, args[0]->type == tNull); } @@ -277,7 +277,7 @@ static void prim_isNull(EvalState & state, const Pos & pos, Value * * args, Valu /* Determine whether the argument is a function. */ static void prim_isFunction(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); bool res; switch (args[0]->type) { case tLambda: @@ -296,21 +296,21 @@ static void prim_isFunction(EvalState & state, const Pos & pos, Value * * args, /* Determine whether the argument is an integer. */ static void prim_isInt(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); mkBool(v, args[0]->type == tInt); } /* Determine whether the argument is a float. */ static void prim_isFloat(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); mkBool(v, args[0]->type == tFloat); } /* Determine whether the argument is a string. */ static void prim_isString(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); mkBool(v, args[0]->type == tString); } @@ -318,14 +318,14 @@ static void prim_isString(EvalState & state, const Pos & pos, Value * * args, Va /* Determine whether the argument is a Boolean. */ static void prim_isBool(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); mkBool(v, args[0]->type == tBool); } /* Determine whether the argument is a path. */ static void prim_isPath(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); mkBool(v, args[0]->type == tPath); } @@ -382,7 +382,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar args[0]->attrs->find(state.symbols.create("operator")); if (op == args[0]->attrs->end()) throw EvalError(format("attribute 'operator' required, at %1%") % pos); - state.forceValue(*op->value); + state.forceValue(*op->value, pos); /* Construct the closure by applying the operator to element of `workSet', adding the result to `workSet', continuing until @@ -401,7 +401,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar e->attrs->find(state.symbols.create("key")); if (key == e->attrs->end()) throw EvalError(format("attribute 'key' required, at %1%") % pos); - state.forceValue(*key->value); + state.forceValue(*key->value, pos); if (!doneKeys.insert(key->value).second) continue; res.push_back(e); @@ -413,7 +413,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar /* Add the values returned by the operator to the work set. */ for (unsigned int n = 0; n < call.listSize(); ++n) { - state.forceValue(*call.listElems()[n]); + state.forceValue(*call.listElems()[n], pos); workSet.push_back(call.listElems()[n]); } } @@ -445,7 +445,7 @@ static void prim_throw(EvalState & state, const Pos & pos, Value * * args, Value static void prim_addErrorContext(EvalState & state, const Pos & pos, Value * * args, Value & v) { try { - state.forceValue(*args[1]); + state.forceValue(*args[1], pos); v = *args[1]; } catch (Error & e) { PathSet context; @@ -461,7 +461,7 @@ static void prim_tryEval(EvalState & state, const Pos & pos, Value * * args, Val { state.mkAttrs(v, 2); try { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); v.attrs->push_back(Attr(state.sValue, args[0])); mkBool(*state.allocAttr(v, state.symbols.create("success")), true); } catch (AssertionError & e) { @@ -483,8 +483,8 @@ static void prim_getEnv(EvalState & state, const Pos & pos, Value * * args, Valu /* Evaluate the first argument, then return the second argument. */ static void prim_seq(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); - state.forceValue(*args[1]); + state.forceValue(*args[0], pos); + state.forceValue(*args[1], pos); v = *args[1]; } @@ -494,7 +494,7 @@ static void prim_seq(EvalState & state, const Pos & pos, Value * * args, Value & static void prim_deepSeq(EvalState & state, const Pos & pos, Value * * args, Value & v) { state.forceValueDeep(*args[0]); - state.forceValue(*args[1]); + state.forceValue(*args[1], pos); v = *args[1]; } @@ -503,12 +503,12 @@ static void prim_deepSeq(EvalState & state, const Pos & pos, Value * * args, Val return the second expression. Useful for debugging. */ static void prim_trace(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); if (args[0]->type == tString) printError(format("trace: %1%") % args[0]->string.s); else printError(format("trace: %1%") % *args[0]); - state.forceValue(*args[1]); + state.forceValue(*args[1], pos); v = *args[1]; } @@ -599,7 +599,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * try { if (ignoreNulls) { - state.forceValue(*i->value); + state.forceValue(*i->value, pos); if (i->value->type == tNull) continue; } @@ -1092,7 +1092,7 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args if (!context.empty()) throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") % path % pos); - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); if (args[0]->type != tLambda) throw TypeError(format("first argument in call to 'filterSource' is not a function but %1%, at %2%") % showType(*args[0]) % pos); @@ -1118,7 +1118,7 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value } else if (attr.name == state.sName) name = state.forceStringNoCtx(*attr.value, *attr.pos); else if (n == "filter") { - state.forceValue(*attr.value); + state.forceValue(*attr.value, pos); filterFun = attr.value; } else if (n == "recursive") recursive = state.forceBool(*attr.value, *attr.pos); @@ -1189,7 +1189,7 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) throw EvalError(format("attribute '%1%' missing, at %2%") % attr % pos); // !!! add to stack trace? if (state.countCalls && i->pos) state.attrSelects[*i->pos]++; - state.forceValue(*i->value); + state.forceValue(*i->value, pos); v = *i->value; } @@ -1219,7 +1219,7 @@ static void prim_hasAttr(EvalState & state, const Pos & pos, Value * * args, Val /* Determine whether the argument is a set. */ static void prim_isAttrs(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); mkBool(v, args[0]->type == tAttrs); } @@ -1345,7 +1345,7 @@ static void prim_catAttrs(EvalState & state, const Pos & pos, Value * * args, Va */ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); if (args[0]->type != tLambda) throw TypeError(format("'functionArgs' requires a function, at %1%") % pos); @@ -1391,7 +1391,7 @@ static void prim_mapAttrs(EvalState & state, const Pos & pos, Value * * args, Va /* Determine whether the argument is a list. */ static void prim_isList(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); + state.forceValue(*args[0], pos); mkBool(v, args[0]->isList()); } @@ -1401,7 +1401,7 @@ static void elemAt(EvalState & state, const Pos & pos, Value & list, int n, Valu state.forceList(list, pos); if (n < 0 || (unsigned int) n >= list.listSize()) throw Error(format("list index %1% is out of bounds, at %2%") % n % pos); - state.forceValue(*list.listElems()[n]); + state.forceValue(*list.listElems()[n], pos); v = *list.listElems()[n]; } @@ -1524,9 +1524,9 @@ static void prim_foldlStrict(EvalState & state, const Pos & pos, Value * * args, vCur = n == args[2]->listSize() - 1 ? &v : state.allocValue(); state.callFunction(vTmp, *args[2]->listElems()[n], *vCur, pos); } - state.forceValue(v); + state.forceValue(v, pos); } else { - state.forceValue(*args[1]); + state.forceValue(*args[1], pos); v = *args[1]; } } @@ -1591,7 +1591,7 @@ static void prim_sort(EvalState & state, const Pos & pos, Value * * args, Value auto len = args[1]->listSize(); state.mkList(v, len); for (unsigned int n = 0; n < len; ++n) { - state.forceValue(*args[1]->listElems()[n]); + state.forceValue(*args[1]->listElems()[n], pos); v.listElems()[n] = args[1]->listElems()[n]; } @@ -1626,7 +1626,7 @@ static void prim_partition(EvalState & state, const Pos & pos, Value * * args, V for (unsigned int n = 0; n < len; ++n) { auto vElem = args[1]->listElems()[n]; - state.forceValue(*vElem); + state.forceValue(*vElem, pos); Value res; state.callFunction(*args[0], *vElem, res, pos); if (state.forceBool(res, pos)) @@ -1757,8 +1757,8 @@ static void prim_bitXor(EvalState & state, const Pos & pos, Value * * args, Valu static void prim_lessThan(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.forceValue(*args[0]); - state.forceValue(*args[1]); + state.forceValue(*args[0], pos); + state.forceValue(*args[1], pos); CompareValues comp; mkBool(v, comp(args[0], args[1])); } From 96262e744e4eef67d808a532b1704fceb62bca5b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 16 Apr 2020 09:55:38 -0600 Subject: [PATCH 41/46] switch to structs, which don't need public: --- src/libutil/error.hh | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 5658e6335..417a6ad95 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -17,9 +17,8 @@ typedef enum { elError } ErrLevel; -class ErrPos +struct ErrPos { -public: int lineNumber; int column; string nixFile; @@ -40,9 +39,8 @@ public: } }; -class NixCode +struct NixCode { -public: ErrPos errPos; std::optional prevLineOfCode; string errLineOfCode; @@ -54,9 +52,8 @@ public: // are always in yellow. template -class yellowify +struct yellowify { -public: yellowify(T &s) : value(s) {} T &value; }; @@ -104,9 +101,8 @@ inline hintformat hintfmt(const std::string & fs, const Args & ... args) // ------------------------------------------------- // ErrorInfo. -class ErrorInfo +struct ErrorInfo { -public: ErrLevel level; string name; string description; @@ -114,8 +110,6 @@ public: std::optional nixCode; static std::optional programName; - -private: }; // -------------------------------------------------------- From 12814806efca65a73aebf8d3109eb2fbf880e2b8 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 16 Apr 2020 10:48:15 -0600 Subject: [PATCH 42/46] iomanip no longer needed --- src/libutil/error.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 417a6ad95..f402b692e 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -5,8 +5,6 @@ #include #include #include -#include - #include "types.hh" namespace nix From c0d940978a66841df638038e3ca85501bcee5734 Mon Sep 17 00:00:00 2001 From: Dustin DeWeese Date: Mon, 20 Apr 2020 17:32:50 -0700 Subject: [PATCH 43/46] Replace select() with poll() to allow waiting on more than FD_SETSIZE fds --- src/libstore/build.cc | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/libstore/build.cc b/src/libstore/build.cc index b4207e1b8..572634765 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -43,6 +42,7 @@ #include #include #include +#include #include #include @@ -4789,8 +4789,7 @@ void Worker::waitForInput() terminated. */ bool useTimeout = false; - struct timeval timeout; - timeout.tv_usec = 0; + long timeout = 0; auto before = steady_time_point::clock::now(); /* If we're monitoring for silence on stdout/stderr, or if there @@ -4808,7 +4807,7 @@ void Worker::waitForInput() nearest = std::min(nearest, i.timeStarted + std::chrono::seconds(settings.buildTimeout)); } if (nearest != steady_time_point::max()) { - timeout.tv_sec = std::max(1L, (long) std::chrono::duration_cast(nearest - before).count()); + timeout = std::max(1L, (long) std::chrono::duration_cast(nearest - before).count()); useTimeout = true; } @@ -4819,30 +4818,28 @@ void Worker::waitForInput() if (lastWokenUp == steady_time_point::min()) printError("waiting for locks or build slots..."); if (lastWokenUp == steady_time_point::min() || lastWokenUp > before) lastWokenUp = before; - timeout.tv_sec = std::max(1L, + timeout = std::max(1L, (long) std::chrono::duration_cast( lastWokenUp + std::chrono::seconds(settings.pollInterval) - before).count()); } else lastWokenUp = steady_time_point::min(); if (useTimeout) - vomit("sleeping %d seconds", timeout.tv_sec); + vomit("sleeping %d seconds", timeout); /* Use select() to wait for the input side of any logger pipe to become `available'. Note that `available' (i.e., non-blocking) includes EOF. */ - fd_set fds; - FD_ZERO(&fds); - int fdMax = 0; + std::vector pollStatus; + std::map fdToPollStatus; for (auto & i : children) { for (auto & j : i.fds) { - if (j >= FD_SETSIZE) - throw Error("reached FD_SETSIZE limit"); - FD_SET(j, &fds); - if (j >= fdMax) fdMax = j + 1; + pollStatus.push_back((struct pollfd) { .fd = j, .events = POLLIN }); + fdToPollStatus[j] = pollStatus.size() - 1; } } - if (select(fdMax, &fds, 0, 0, useTimeout ? &timeout : 0) == -1) { + if (poll(pollStatus.data(), pollStatus.size(), + useTimeout ? timeout * 1000 : -1) == -1) { if (errno == EINTR) return; throw SysError("waiting for input"); } @@ -4863,7 +4860,7 @@ void Worker::waitForInput() set fds2(j->fds); std::vector buffer(4096); for (auto & k : fds2) { - if (FD_ISSET(k, &fds)) { + if (pollStatus.at(fdToPollStatus.at(k)).revents) { ssize_t rd = read(k, buffer.data(), buffer.size()); // FIXME: is there a cleaner way to handle pt close // than EIO? Is this even standard? From 2ea4d45449ea676e27cc678145ef39af7ac05ca8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Apr 2020 10:15:32 +0200 Subject: [PATCH 44/46] Path fetcher: Fix store path name (cherry picked from commit c7af247beacd418e6f2c4d33dffc35299101cd12) --- src/libfetchers/path.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc index 7c7e20f4e..ba2cc192e 100644 --- a/src/libfetchers/path.cc +++ b/src/libfetchers/path.cc @@ -72,7 +72,7 @@ struct PathInput : Input if (!storePath || storePath->name() != "source" || !store->isValidPath(*storePath)) // FIXME: try to substitute storePath. - storePath = store->addToStore("name", path); + storePath = store->addToStore("source", path); return { From 7114f088fceb366e9ff0fb60e2970a11861d11fd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Apr 2020 14:54:16 +0200 Subject: [PATCH 45/46] Don't install error-demo --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f6b4a3101..e3057c36c 100644 --- a/Makefile +++ b/Makefile @@ -16,8 +16,7 @@ makefiles = \ misc/upstart/local.mk \ doc/manual/local.mk \ tests/local.mk \ - tests/plugins/local.mk \ - src/error-demo/local.mk + tests/plugins/local.mk -include Makefile.config From c9d0cf7e02d4b3af3c027d7d74d5caa3c8963d26 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 22 Apr 2020 15:03:41 +0200 Subject: [PATCH 46/46] Don't include error.hh in util.hh to prevent header bloat --- src/libutil/util.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 8e24ef968..d7ee62bcc 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 #include