1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 19:01:16 +02:00

Some notational convenience for formatting strings

We can now write

  throw Error("file '%s' not found", path);

instead of

  throw Error(format("file '%s' not found") % path);

and similarly

  printError("file '%s' not found", path);

instead of

  printMsg(lvlError, format("file '%s' not found") % path);
This commit is contained in:
Eelco Dolstra 2016-09-21 16:00:03 +02:00
parent 3f8e620b19
commit 4036185cb4
6 changed files with 81 additions and 22 deletions

View file

@ -41,6 +41,45 @@ struct FormatOrString
};
/* A helper for formatting strings. fmt(format, a_0, ..., a_n) is
equivalent to boost::format(format) % a_0 % ... %
... a_n. However, fmt(s) is equivalent to s (so no %-expansion
takes place). */
inline void formatHelper(boost::format & f)
{
}
template<typename T, typename... Args>
inline void formatHelper(boost::format & f, T x, Args... args)
{
formatHelper(f % x, args...);
}
inline std::string fmt(const std::string & s)
{
return s;
}
inline std::string fmt(const char * s)
{
return s;
}
inline std::string fmt(const FormatOrString & fs)
{
return fs.s;
}
template<typename... Args>
inline std::string fmt(const std::string & fs, Args... args)
{
boost::format f(fs);
formatHelper(f, args...);
return f.str();
}
/* BaseError should generally not be caught, as it has Interrupted as
a subclass. Catch Error instead. */
class BaseError : public std::exception
@ -49,14 +88,28 @@ protected:
string prefix_; // used for location traces etc.
string err;
public:
unsigned int status; // exit status
BaseError(const FormatOrString & fs, unsigned int status = 1);
unsigned int status = 1; // exit status
template<typename... Args>
BaseError(unsigned int status, Args... args)
: err(fmt(args...))
, status(status)
{
}
template<typename... Args>
BaseError(Args... args)
: err(fmt(args...))
{
}
#ifdef EXCEPTION_NEEDS_THROW_SPEC
~BaseError() throw () { };
const char * what() const throw () { return err.c_str(); }
#else
const char * what() const noexcept { return err.c_str(); }
#endif
const string & msg() const { return err; }
const string & prefix() const { return prefix_; }
BaseError & addPrefix(const FormatOrString & fs);
@ -66,7 +119,7 @@ public:
class newClass : public superClass \
{ \
public: \
newClass(const FormatOrString & fs, unsigned int status = 1) : superClass(fs, status) { }; \
using superClass::superClass; \
};
MakeError(Error, BaseError)
@ -75,7 +128,15 @@ class SysError : public Error
{
public:
int errNo;
SysError(const FormatOrString & fs);
template<typename... Args>
SysError(Args... args)
: Error(addErrno(fmt(args...)))
{ }
private:
std::string addErrno(const std::string & s);
};