forked from lix-project/lix
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:
parent
3f8e620b19
commit
4036185cb4
|
@ -3768,7 +3768,7 @@ void LocalStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!failed.empty())
|
if (!failed.empty())
|
||||||
throw Error(format("build of %1% failed") % showPaths(failed), worker.exitStatus());
|
throw Error(worker.exitStatus(), "build of %s failed",showPaths(failed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3804,7 +3804,7 @@ void LocalStore::ensurePath(const Path & path)
|
||||||
worker.run(goals);
|
worker.run(goals);
|
||||||
|
|
||||||
if (goal->getExitCode() != Goal::ecSuccess)
|
if (goal->getExitCode() != Goal::ecSuccess)
|
||||||
throw Error(format("path ‘%1%’ does not exist and cannot be created") % path, worker.exitStatus());
|
throw Error(worker.exitStatus(), "path ‘%s’ does not exist and cannot be created", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3825,7 +3825,7 @@ void LocalStore::repairPath(const Path & path)
|
||||||
goals.insert(worker.makeDerivationGoal(deriver, StringSet(), bmRepair));
|
goals.insert(worker.makeDerivationGoal(deriver, StringSet(), bmRepair));
|
||||||
worker.run(goals);
|
worker.run(goals);
|
||||||
} else
|
} else
|
||||||
throw Error(format("cannot repair path ‘%1%’") % path, worker.exitStatus());
|
throw Error(worker.exitStatus(), "cannot repair path ‘%s’", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -564,7 +564,7 @@ void RemoteStore::Connection::processStderr(Sink * sink, Source * source)
|
||||||
if (msg == STDERR_ERROR) {
|
if (msg == STDERR_ERROR) {
|
||||||
string error = readString(from);
|
string error = readString(from);
|
||||||
unsigned int status = readInt(from);
|
unsigned int status = readInt(from);
|
||||||
throw Error(format("%1%") % error, status);
|
throw Error(status, error);
|
||||||
}
|
}
|
||||||
else if (msg != STDERR_LAST)
|
else if (msg != STDERR_LAST)
|
||||||
throw Error("protocol error processing standard error");
|
throw Error("protocol error processing standard error");
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
MakeError(UsageError, nix::Error);
|
MakeError(UsageError, Error);
|
||||||
|
|
||||||
enum HashType : char;
|
enum HashType : char;
|
||||||
|
|
||||||
|
|
|
@ -66,14 +66,19 @@ Logger * makeDefaultLogger();
|
||||||
|
|
||||||
extern Verbosity verbosity; /* suppress msgs > this */
|
extern Verbosity verbosity; /* suppress msgs > this */
|
||||||
|
|
||||||
#define printMsg(level, f) \
|
/* Print a message if the current log level is at least the specified
|
||||||
|
level. Note that this has to be implemented as a macro to ensure
|
||||||
|
that the arguments are evaluated lazily. */
|
||||||
|
#define printMsg(level, args...) \
|
||||||
do { \
|
do { \
|
||||||
if (level <= nix::verbosity) { \
|
if (level <= nix::verbosity) { \
|
||||||
logger->log(level, (f)); \
|
logger->log(level, fmt(args)); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define debug(f) printMsg(lvlDebug, f)
|
#define printError(args...) printMsg(lvlError, args)
|
||||||
|
#define printInfo(args...) printMsg(lvlInfo, args)
|
||||||
|
#define debug(args...) printMsg(lvlDebug, args)
|
||||||
|
|
||||||
void warnOnce(bool & haveWarned, const FormatOrString & fs);
|
void warnOnce(bool & haveWarned, const FormatOrString & fs);
|
||||||
|
|
||||||
|
|
|
@ -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
|
/* BaseError should generally not be caught, as it has Interrupted as
|
||||||
a subclass. Catch Error instead. */
|
a subclass. Catch Error instead. */
|
||||||
class BaseError : public std::exception
|
class BaseError : public std::exception
|
||||||
|
@ -49,14 +88,28 @@ protected:
|
||||||
string prefix_; // used for location traces etc.
|
string prefix_; // used for location traces etc.
|
||||||
string err;
|
string err;
|
||||||
public:
|
public:
|
||||||
unsigned int status; // exit status
|
unsigned int status = 1; // exit status
|
||||||
BaseError(const FormatOrString & fs, unsigned int status = 1);
|
|
||||||
|
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
|
#ifdef EXCEPTION_NEEDS_THROW_SPEC
|
||||||
~BaseError() throw () { };
|
~BaseError() throw () { };
|
||||||
const char * what() const throw () { return err.c_str(); }
|
const char * what() const throw () { return err.c_str(); }
|
||||||
#else
|
#else
|
||||||
const char * what() const noexcept { return err.c_str(); }
|
const char * what() const noexcept { return err.c_str(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const string & msg() const { return err; }
|
const string & msg() const { return err; }
|
||||||
const string & prefix() const { return prefix_; }
|
const string & prefix() const { return prefix_; }
|
||||||
BaseError & addPrefix(const FormatOrString & fs);
|
BaseError & addPrefix(const FormatOrString & fs);
|
||||||
|
@ -66,7 +119,7 @@ public:
|
||||||
class newClass : public superClass \
|
class newClass : public superClass \
|
||||||
{ \
|
{ \
|
||||||
public: \
|
public: \
|
||||||
newClass(const FormatOrString & fs, unsigned int status = 1) : superClass(fs, status) { }; \
|
using superClass::superClass; \
|
||||||
};
|
};
|
||||||
|
|
||||||
MakeError(Error, BaseError)
|
MakeError(Error, BaseError)
|
||||||
|
@ -75,7 +128,15 @@ class SysError : public Error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int errNo;
|
int errNo;
|
||||||
SysError(const FormatOrString & fs);
|
|
||||||
|
template<typename... Args>
|
||||||
|
SysError(Args... args)
|
||||||
|
: Error(addErrno(fmt(args...)))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::string addErrno(const std::string & s);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,13 +31,6 @@ extern char * * environ;
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
BaseError::BaseError(const FormatOrString & fs, unsigned int status)
|
|
||||||
: status(status)
|
|
||||||
{
|
|
||||||
err = fs.s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BaseError & BaseError::addPrefix(const FormatOrString & fs)
|
BaseError & BaseError::addPrefix(const FormatOrString & fs)
|
||||||
{
|
{
|
||||||
prefix_ = fs.s + prefix_;
|
prefix_ = fs.s + prefix_;
|
||||||
|
@ -45,10 +38,10 @@ BaseError & BaseError::addPrefix(const FormatOrString & fs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SysError::SysError(const FormatOrString & fs)
|
std::string SysError::addErrno(const std::string & s)
|
||||||
: Error(format("%1%: %2%") % fs.s % strerror(errno))
|
|
||||||
, errNo(errno)
|
|
||||||
{
|
{
|
||||||
|
errNo = errno;
|
||||||
|
return s + ": " + strerror(errNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue