From 7b7801d3f0e0e1cd32b1279979970ad71b66b879 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 3 Apr 2020 08:48:20 -0600 Subject: [PATCH] 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; }