forked from lix-project/lix
Merge pull request #9925 from 9999years/fmt-cleanup
Cleanup `fmt.hh`
(cherry picked from commit 47a1dbb4b8e7913cbb9b4d604728b912e76e4ca0)
Change-Id: Id076a45cb39652f437fe3f8bda10c310a9894777
This commit is contained in:
parent
3d9c7fc1e7
commit
b221a14f0a
|
@ -202,7 +202,7 @@ static int main_build_remote(int argc, char * * argv)
|
||||||
else
|
else
|
||||||
drvstr = "<unknown>";
|
drvstr = "<unknown>";
|
||||||
|
|
||||||
auto error = hintformat(errorText);
|
auto error = HintFmt(errorText);
|
||||||
error
|
error
|
||||||
% drvstr
|
% drvstr
|
||||||
% neededSystem
|
% neededSystem
|
||||||
|
|
|
@ -28,7 +28,7 @@ template<class T>
|
||||||
EvalErrorBuilder<T> & EvalErrorBuilder<T>::withTrace(PosIdx pos, const std::string_view text)
|
EvalErrorBuilder<T> & EvalErrorBuilder<T>::withTrace(PosIdx pos, const std::string_view text)
|
||||||
{
|
{
|
||||||
error.err.traces.push_front(
|
error.err.traces.push_front(
|
||||||
Trace{.pos = error.state.positions[pos], .hint = hintfmt(std::string(text)), .frame = false});
|
Trace{.pos = error.state.positions[pos], .hint = HintFmt(std::string(text)), .frame = false});
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ template<class T>
|
||||||
EvalErrorBuilder<T> & EvalErrorBuilder<T>::withFrameTrace(PosIdx pos, const std::string_view text)
|
EvalErrorBuilder<T> & EvalErrorBuilder<T>::withFrameTrace(PosIdx pos, const std::string_view text)
|
||||||
{
|
{
|
||||||
error.err.traces.push_front(
|
error.err.traces.push_front(
|
||||||
Trace{.pos = error.state.positions[pos], .hint = hintformat(std::string(text)), .frame = true});
|
Trace{.pos = error.state.positions[pos], .hint = HintFmt(std::string(text)), .frame = true});
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,13 +57,13 @@ EvalErrorBuilder<T> & EvalErrorBuilder<T>::withFrame(const Env & env, const Expr
|
||||||
.pos = error.state.positions[expr.getPos()],
|
.pos = error.state.positions[expr.getPos()],
|
||||||
.expr = expr,
|
.expr = expr,
|
||||||
.env = env,
|
.env = env,
|
||||||
.hint = hintformat("Fake frame for debugging purposes"),
|
.hint = HintFmt("Fake frame for debugging purposes"),
|
||||||
.isError = true});
|
.isError = true});
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
EvalErrorBuilder<T> & EvalErrorBuilder<T>::addTrace(PosIdx pos, hintformat hint, bool frame)
|
EvalErrorBuilder<T> & EvalErrorBuilder<T>::addTrace(PosIdx pos, HintFmt hint, bool frame)
|
||||||
{
|
{
|
||||||
error.addTrace(error.state.positions[pos], hint, frame);
|
error.addTrace(error.state.positions[pos], hint, frame);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -75,7 +75,7 @@ EvalErrorBuilder<T> &
|
||||||
EvalErrorBuilder<T>::addTrace(PosIdx pos, std::string_view formatString, const Args &... formatArgs)
|
EvalErrorBuilder<T>::addTrace(PosIdx pos, std::string_view formatString, const Args &... formatArgs)
|
||||||
{
|
{
|
||||||
|
|
||||||
addTrace(error.state.positions[pos], hintfmt(std::string(formatString), formatArgs...));
|
addTrace(error.state.positions[pos], HintFmt(std::string(formatString), formatArgs...));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ public:
|
||||||
|
|
||||||
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withFrame(const Env & e, const Expr & ex);
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & withFrame(const Env & e, const Expr & ex);
|
||||||
|
|
||||||
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & addTrace(PosIdx pos, hintformat hint, bool frame = false);
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> & addTrace(PosIdx pos, HintFmt hint, bool frame = false);
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> &
|
[[nodiscard, gnu::noinline]] EvalErrorBuilder<T> &
|
||||||
|
|
|
@ -809,7 +809,7 @@ void EvalState::addErrorTrace(Error & e, const char * s, const std::string & s2)
|
||||||
|
|
||||||
void EvalState::addErrorTrace(Error & e, const PosIdx pos, const char * s, const std::string & s2, bool frame) const
|
void EvalState::addErrorTrace(Error & e, const PosIdx pos, const char * s, const std::string & s2, bool frame) const
|
||||||
{
|
{
|
||||||
e.addTrace(positions[pos], hintfmt(s, s2), frame);
|
e.addTrace(positions[pos], HintFmt(s, s2), frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
|
@ -825,7 +825,7 @@ static std::unique_ptr<DebugTraceStacker> makeDebugTraceStacker(
|
||||||
.pos = std::move(pos),
|
.pos = std::move(pos),
|
||||||
.expr = expr,
|
.expr = expr,
|
||||||
.env = env,
|
.env = env,
|
||||||
.hint = hintfmt(formatArgs...),
|
.hint = HintFmt(formatArgs...),
|
||||||
.isError = false
|
.isError = false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2782,7 +2782,7 @@ std::optional<std::string> EvalState::resolveSearchPathPath(const SearchPath::Pa
|
||||||
res = { store->toRealPath(storePath) };
|
res = { store->toRealPath(storePath) };
|
||||||
} catch (FileTransferError & e) {
|
} catch (FileTransferError & e) {
|
||||||
logWarning({
|
logWarning({
|
||||||
.msg = hintfmt("Nix search path entry '%1%' cannot be downloaded, ignoring", value)
|
.msg = HintFmt("Nix search path entry '%1%' cannot be downloaded, ignoring", value)
|
||||||
});
|
});
|
||||||
res = std::nullopt;
|
res = std::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -2802,7 +2802,7 @@ std::optional<std::string> EvalState::resolveSearchPathPath(const SearchPath::Pa
|
||||||
res = { path };
|
res = { path };
|
||||||
else {
|
else {
|
||||||
logWarning({
|
logWarning({
|
||||||
.msg = hintfmt("Nix search path entry '%1%' does not exist, ignoring", value)
|
.msg = HintFmt("Nix search path entry '%1%' does not exist, ignoring", value)
|
||||||
});
|
});
|
||||||
res = std::nullopt;
|
res = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ struct DebugTrace {
|
||||||
std::shared_ptr<Pos> pos;
|
std::shared_ptr<Pos> pos;
|
||||||
const Expr & expr;
|
const Expr & expr;
|
||||||
const Env & env;
|
const Env & env;
|
||||||
hintformat hint;
|
HintFmt hint;
|
||||||
bool isError;
|
bool isError;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ static FlakeInput parseFlakeInput(EvalState & state,
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(
|
e.addTrace(
|
||||||
state.positions[attr.pos],
|
state.positions[attr.pos],
|
||||||
hintfmt("while evaluating flake attribute '%s'", state.symbols[attr.name]));
|
HintFmt("while evaluating flake attribute '%s'", state.symbols[attr.name]));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ static FlakeInput parseFlakeInput(EvalState & state,
|
||||||
try {
|
try {
|
||||||
input.ref = FlakeRef::fromAttrs(attrs);
|
input.ref = FlakeRef::fromAttrs(attrs);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(state.positions[pos], hintfmt("while evaluating flake input"));
|
e.addTrace(state.positions[pos], HintFmt("while evaluating flake input"));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -153,7 +153,7 @@ or { return OR_KW; }
|
||||||
yylval->n = boost::lexical_cast<int64_t>(yytext);
|
yylval->n = boost::lexical_cast<int64_t>(yytext);
|
||||||
} catch (const boost::bad_lexical_cast &) {
|
} catch (const boost::bad_lexical_cast &) {
|
||||||
throw ParseError(ErrorInfo{
|
throw ParseError(ErrorInfo{
|
||||||
.msg = hintfmt("invalid integer '%1%'", yytext),
|
.msg = HintFmt("invalid integer '%1%'", yytext),
|
||||||
.pos = state->positions[CUR_POS],
|
.pos = state->positions[CUR_POS],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ or { return OR_KW; }
|
||||||
yylval->nf = strtod(yytext, 0);
|
yylval->nf = strtod(yytext, 0);
|
||||||
if (errno != 0)
|
if (errno != 0)
|
||||||
throw ParseError(ErrorInfo{
|
throw ParseError(ErrorInfo{
|
||||||
.msg = hintfmt("invalid float '%1%'", yytext),
|
.msg = HintFmt("invalid float '%1%'", yytext),
|
||||||
.pos = state->positions[CUR_POS],
|
.pos = state->positions[CUR_POS],
|
||||||
});
|
});
|
||||||
return FLOAT;
|
return FLOAT;
|
||||||
|
@ -292,7 +292,7 @@ or { return OR_KW; }
|
||||||
<INPATH_SLASH>{ANY} |
|
<INPATH_SLASH>{ANY} |
|
||||||
<INPATH_SLASH><<EOF>> {
|
<INPATH_SLASH><<EOF>> {
|
||||||
throw ParseError(ErrorInfo{
|
throw ParseError(ErrorInfo{
|
||||||
.msg = hintfmt("path has a trailing slash"),
|
.msg = HintFmt("path has a trailing slash"),
|
||||||
.pos = state->positions[CUR_POS],
|
.pos = state->positions[CUR_POS],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ struct ParserState
|
||||||
inline void ParserState::dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos)
|
inline void ParserState::dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos)
|
||||||
{
|
{
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = hintfmt("attribute '%1%' already defined at %2%",
|
.msg = HintFmt("attribute '%1%' already defined at %2%",
|
||||||
showAttrPath(symbols, attrPath), positions[prevPos]),
|
showAttrPath(symbols, attrPath), positions[prevPos]),
|
||||||
.pos = positions[pos]
|
.pos = positions[pos]
|
||||||
});
|
});
|
||||||
|
@ -72,7 +72,7 @@ inline void ParserState::dupAttr(const AttrPath & attrPath, const PosIdx pos, co
|
||||||
inline void ParserState::dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos)
|
inline void ParserState::dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos)
|
||||||
{
|
{
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = hintfmt("attribute '%1%' already defined at %2%", symbols[attr], positions[prevPos]),
|
.msg = HintFmt("attribute '%1%' already defined at %2%", symbols[attr], positions[prevPos]),
|
||||||
.pos = positions[pos]
|
.pos = positions[pos]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -153,13 +153,13 @@ inline Formals * ParserState::validateFormals(Formals * formals, PosIdx pos, Sym
|
||||||
}
|
}
|
||||||
if (duplicate)
|
if (duplicate)
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = hintfmt("duplicate formal function argument '%1%'", symbols[duplicate->first]),
|
.msg = HintFmt("duplicate formal function argument '%1%'", symbols[duplicate->first]),
|
||||||
.pos = positions[duplicate->second]
|
.pos = positions[duplicate->second]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (arg && formals->has(arg))
|
if (arg && formals->has(arg))
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = hintfmt("duplicate formal function argument '%1%'", symbols[arg]),
|
.msg = HintFmt("duplicate formal function argument '%1%'", symbols[arg]),
|
||||||
.pos = positions[pos]
|
.pos = positions[pos]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ using namespace nix;
|
||||||
void yyerror(YYLTYPE * loc, yyscan_t scanner, ParserState * state, const char * error)
|
void yyerror(YYLTYPE * loc, yyscan_t scanner, ParserState * state, const char * error)
|
||||||
{
|
{
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = hintfmt(error),
|
.msg = HintFmt(error),
|
||||||
.pos = state->positions[state->at(*loc)]
|
.pos = state->positions[state->at(*loc)]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ expr_function
|
||||||
| LET binds IN expr_function
|
| LET binds IN expr_function
|
||||||
{ if (!$2->dynamicAttrs.empty())
|
{ if (!$2->dynamicAttrs.empty())
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = hintfmt("dynamic attributes not allowed in let"),
|
.msg = HintFmt("dynamic attributes not allowed in let"),
|
||||||
.pos = state->positions[CUR_POS]
|
.pos = state->positions[CUR_POS]
|
||||||
});
|
});
|
||||||
$$ = new ExprLet($2, $4);
|
$$ = new ExprLet($2, $4);
|
||||||
|
@ -242,7 +242,7 @@ expr_simple
|
||||||
static bool noURLLiterals = experimentalFeatureSettings.isEnabled(Xp::NoUrlLiterals);
|
static bool noURLLiterals = experimentalFeatureSettings.isEnabled(Xp::NoUrlLiterals);
|
||||||
if (noURLLiterals)
|
if (noURLLiterals)
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = hintfmt("URL literals are disabled"),
|
.msg = HintFmt("URL literals are disabled"),
|
||||||
.pos = state->positions[CUR_POS]
|
.pos = state->positions[CUR_POS]
|
||||||
});
|
});
|
||||||
$$ = new ExprString(std::string($1));
|
$$ = new ExprString(std::string($1));
|
||||||
|
@ -338,7 +338,7 @@ attrs
|
||||||
delete str;
|
delete str;
|
||||||
} else
|
} else
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = hintfmt("dynamic attributes not allowed in inherit"),
|
.msg = HintFmt("dynamic attributes not allowed in inherit"),
|
||||||
.pos = state->positions[state->at(@2)]
|
.pos = state->positions[state->at(@2)]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -748,7 +748,7 @@ static RegisterPrimOp primop_break({
|
||||||
if (state.debugRepl && !state.debugTraces.empty()) {
|
if (state.debugRepl && !state.debugTraces.empty()) {
|
||||||
auto error = Error(ErrorInfo {
|
auto error = Error(ErrorInfo {
|
||||||
.level = lvlInfo,
|
.level = lvlInfo,
|
||||||
.msg = hintfmt("breakpoint reached"),
|
.msg = HintFmt("breakpoint reached"),
|
||||||
.pos = state.positions[pos],
|
.pos = state.positions[pos],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -759,7 +759,7 @@ static RegisterPrimOp primop_break({
|
||||||
// If the user elects to quit the repl, throw an exception.
|
// If the user elects to quit the repl, throw an exception.
|
||||||
throw Error(ErrorInfo{
|
throw Error(ErrorInfo{
|
||||||
.level = lvlInfo,
|
.level = lvlInfo,
|
||||||
.msg = hintfmt("quit the debugger"),
|
.msg = HintFmt("quit the debugger"),
|
||||||
.pos = nullptr,
|
.pos = nullptr,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -814,7 +814,7 @@ static void prim_addErrorContext(EvalState & state, const PosIdx pos, Value * *
|
||||||
auto message = state.coerceToString(pos, *args[0], context,
|
auto message = state.coerceToString(pos, *args[0], context,
|
||||||
"while evaluating the error message passed to builtins.addErrorContext",
|
"while evaluating the error message passed to builtins.addErrorContext",
|
||||||
false, false).toOwned();
|
false, false).toOwned();
|
||||||
e.addTrace(nullptr, hintfmt(message), true);
|
e.addTrace(nullptr, HintFmt(message), true);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1065,7 @@ static void prim_derivationStrict(EvalState & state, const PosIdx pos, Value * *
|
||||||
* often results from the composition of several functions
|
* often results from the composition of several functions
|
||||||
* (derivationStrict, derivation, mkDerivation, mkPythonModule, etc.)
|
* (derivationStrict, derivation, mkDerivation, mkPythonModule, etc.)
|
||||||
*/
|
*/
|
||||||
e.addTrace(nullptr, hintfmt(
|
e.addTrace(nullptr, HintFmt(
|
||||||
"while evaluating derivation '%s'\n"
|
"while evaluating derivation '%s'\n"
|
||||||
" whose name attribute is located at %s",
|
" whose name attribute is located at %s",
|
||||||
drvName, pos), true);
|
drvName, pos), true);
|
||||||
|
@ -1226,7 +1226,7 @@ drvName, Bindings * attrs, Value & v)
|
||||||
|
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(state.positions[i->pos],
|
e.addTrace(state.positions[i->pos],
|
||||||
hintfmt("while evaluating attribute '%1%' of derivation '%2%'", key, drvName),
|
HintFmt("while evaluating attribute '%1%' of derivation '%2%'", key, drvName),
|
||||||
true);
|
true);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ static void runFetchClosureWithRewrite(EvalState & state, const PosIdx pos, Stor
|
||||||
auto rewrittenPath = makeContentAddressed(fromStore, *state.store, fromPath);
|
auto rewrittenPath = makeContentAddressed(fromStore, *state.store, fromPath);
|
||||||
if (toPathMaybe && *toPathMaybe != rewrittenPath)
|
if (toPathMaybe && *toPathMaybe != rewrittenPath)
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt("rewriting '%s' to content-addressed form yielded '%s', while '%s' was expected",
|
.msg = HintFmt("rewriting '%s' to content-addressed form yielded '%s', while '%s' was expected",
|
||||||
state.store->printStorePath(fromPath),
|
state.store->printStorePath(fromPath),
|
||||||
state.store->printStorePath(rewrittenPath),
|
state.store->printStorePath(rewrittenPath),
|
||||||
state.store->printStorePath(*toPathMaybe)),
|
state.store->printStorePath(*toPathMaybe)),
|
||||||
|
@ -30,7 +30,7 @@ static void runFetchClosureWithRewrite(EvalState & state, const PosIdx pos, Stor
|
||||||
});
|
});
|
||||||
if (!toPathMaybe)
|
if (!toPathMaybe)
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt(
|
.msg = HintFmt(
|
||||||
"rewriting '%s' to content-addressed form yielded '%s'\n"
|
"rewriting '%s' to content-addressed form yielded '%s'\n"
|
||||||
"Use this value for the 'toPath' attribute passed to 'fetchClosure'",
|
"Use this value for the 'toPath' attribute passed to 'fetchClosure'",
|
||||||
state.store->printStorePath(fromPath),
|
state.store->printStorePath(fromPath),
|
||||||
|
@ -49,7 +49,7 @@ static void runFetchClosureWithRewrite(EvalState & state, const PosIdx pos, Stor
|
||||||
// We don't perform the rewriting when outPath already exists, as an optimisation.
|
// We don't perform the rewriting when outPath already exists, as an optimisation.
|
||||||
// However, we can quickly detect a mistake if the toPath is input addressed.
|
// However, we can quickly detect a mistake if the toPath is input addressed.
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt(
|
.msg = HintFmt(
|
||||||
"The 'toPath' value '%s' is input-addressed, so it can't possibly be the result of rewriting to a content-addressed path.\n\n"
|
"The 'toPath' value '%s' is input-addressed, so it can't possibly be the result of rewriting to a content-addressed path.\n\n"
|
||||||
"Set 'toPath' to an empty string to make Nix report the correct content-addressed path.",
|
"Set 'toPath' to an empty string to make Nix report the correct content-addressed path.",
|
||||||
state.store->printStorePath(toPath)),
|
state.store->printStorePath(toPath)),
|
||||||
|
@ -72,7 +72,7 @@ static void runFetchClosureWithContentAddressedPath(EvalState & state, const Pos
|
||||||
|
|
||||||
if (!info->isContentAddressed(*state.store)) {
|
if (!info->isContentAddressed(*state.store)) {
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt(
|
.msg = HintFmt(
|
||||||
"The 'fromPath' value '%s' is input-addressed, but 'inputAddressed' is set to 'false' (default).\n\n"
|
"The 'fromPath' value '%s' is input-addressed, but 'inputAddressed' is set to 'false' (default).\n\n"
|
||||||
"If you do intend to fetch an input-addressed store path, add\n\n"
|
"If you do intend to fetch an input-addressed store path, add\n\n"
|
||||||
" inputAddressed = true;\n\n"
|
" inputAddressed = true;\n\n"
|
||||||
|
@ -98,7 +98,7 @@ static void runFetchClosureWithInputAddressedPath(EvalState & state, const PosId
|
||||||
|
|
||||||
if (info->isContentAddressed(*state.store)) {
|
if (info->isContentAddressed(*state.store)) {
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt(
|
.msg = HintFmt(
|
||||||
"The store object referred to by 'fromPath' at '%s' is not input-addressed, but 'inputAddressed' is set to 'true'.\n\n"
|
"The store object referred to by 'fromPath' at '%s' is not input-addressed, but 'inputAddressed' is set to 'true'.\n\n"
|
||||||
"Remove the 'inputAddressed' attribute (it defaults to 'false') to expect 'fromPath' to be content-addressed",
|
"Remove the 'inputAddressed' attribute (it defaults to 'false') to expect 'fromPath' to be content-addressed",
|
||||||
state.store->printStorePath(fromPath)),
|
state.store->printStorePath(fromPath)),
|
||||||
|
@ -152,14 +152,14 @@ static void prim_fetchClosure(EvalState & state, const PosIdx pos, Value * * arg
|
||||||
|
|
||||||
else
|
else
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt("attribute '%s' isn't supported in call to 'fetchClosure'", attrName),
|
.msg = HintFmt("attribute '%s' isn't supported in call to 'fetchClosure'", attrName),
|
||||||
.pos = state.positions[pos]
|
.pos = state.positions[pos]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fromPath)
|
if (!fromPath)
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt("attribute '%s' is missing in call to 'fetchClosure'", "fromPath"),
|
.msg = HintFmt("attribute '%s' is missing in call to 'fetchClosure'", "fromPath"),
|
||||||
.pos = state.positions[pos]
|
.pos = state.positions[pos]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ static void prim_fetchClosure(EvalState & state, const PosIdx pos, Value * * arg
|
||||||
if (inputAddressed) {
|
if (inputAddressed) {
|
||||||
if (toPath)
|
if (toPath)
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt("attribute '%s' is set to true, but '%s' is also set. Please remove one of them",
|
.msg = HintFmt("attribute '%s' is set to true, but '%s' is also set. Please remove one of them",
|
||||||
"inputAddressed",
|
"inputAddressed",
|
||||||
"toPath"),
|
"toPath"),
|
||||||
.pos = state.positions[pos]
|
.pos = state.positions[pos]
|
||||||
|
@ -177,7 +177,7 @@ static void prim_fetchClosure(EvalState & state, const PosIdx pos, Value * * arg
|
||||||
|
|
||||||
if (!fromStoreUrl)
|
if (!fromStoreUrl)
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt("attribute '%s' is missing in call to 'fetchClosure'", "fromStore"),
|
.msg = HintFmt("attribute '%s' is missing in call to 'fetchClosure'", "fromStore"),
|
||||||
.pos = state.positions[pos]
|
.pos = state.positions[pos]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -187,13 +187,13 @@ static void prim_fetchClosure(EvalState & state, const PosIdx pos, Value * * arg
|
||||||
parsedURL.scheme != "https" &&
|
parsedURL.scheme != "https" &&
|
||||||
!(getEnv("_NIX_IN_TEST").has_value() && parsedURL.scheme == "file"))
|
!(getEnv("_NIX_IN_TEST").has_value() && parsedURL.scheme == "file"))
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt("'fetchClosure' only supports http:// and https:// stores"),
|
.msg = HintFmt("'fetchClosure' only supports http:// and https:// stores"),
|
||||||
.pos = state.positions[pos]
|
.pos = state.positions[pos]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!parsedURL.query.empty())
|
if (!parsedURL.query.empty())
|
||||||
throw Error({
|
throw Error({
|
||||||
.msg = hintfmt("'fetchClosure' does not support URL query parameters (in '%s')", *fromStoreUrl),
|
.msg = HintFmt("'fetchClosure' does not support URL query parameters (in '%s')", *fromStoreUrl),
|
||||||
.pos = state.positions[pos]
|
.pos = state.positions[pos]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -510,7 +510,7 @@ std::ostream & operator<<(std::ostream & output, const ValuePrinter & printer)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
hintformat & hintformat::operator%(const ValuePrinter & value)
|
HintFmt & HintFmt::operator%(const ValuePrinter & value)
|
||||||
{
|
{
|
||||||
fmt % value;
|
fmt % value;
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -86,6 +86,6 @@ std::ostream & operator<<(std::ostream & output, const ValuePrinter & printer);
|
||||||
* magenta.
|
* magenta.
|
||||||
*/
|
*/
|
||||||
template<>
|
template<>
|
||||||
hintformat & hintformat::operator%(const ValuePrinter & value);
|
HintFmt & HintFmt::operator%(const ValuePrinter & value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ json printValueAsJSON(EvalState & state, bool strict,
|
||||||
out[j] = printValueAsJSON(state, strict, *a.value, a.pos, context, copyToStore);
|
out[j] = printValueAsJSON(state, strict, *a.value, a.pos, context, copyToStore);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(state.positions[a.pos],
|
e.addTrace(state.positions[a.pos],
|
||||||
hintfmt("while evaluating attribute '%1%'", j));
|
HintFmt("while evaluating attribute '%1%'", j));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ json printValueAsJSON(EvalState & state, bool strict,
|
||||||
out.push_back(printValueAsJSON(state, strict, *elem, pos, context, copyToStore));
|
out.push_back(printValueAsJSON(state, strict, *elem, pos, context, copyToStore));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(state.positions[pos],
|
e.addTrace(state.positions[pos],
|
||||||
hintfmt("while evaluating list element at index %1%", i));
|
HintFmt("while evaluating list element at index %1%", i));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -20,8 +20,8 @@ public:
|
||||||
: Error("")
|
: Error("")
|
||||||
{
|
{
|
||||||
raw = raw_;
|
raw = raw_;
|
||||||
auto hf = hintfmt(args...);
|
auto hf = HintFmt(args...);
|
||||||
err.msg = hintfmt("Bad String Context element: %1%: %2%", normaltxt(hf.str()), raw);
|
err.msg = HintFmt("Bad String Context element: %1%: %2%", Uncolored(hf.str()), raw);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -708,7 +708,7 @@ void DerivationGoal::tryToBuild()
|
||||||
if (!outputLocks.lockPaths(lockFiles, "", false)) {
|
if (!outputLocks.lockPaths(lockFiles, "", false)) {
|
||||||
if (!actLock)
|
if (!actLock)
|
||||||
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
|
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
|
||||||
fmt("waiting for lock on %s", magentatxt(showPaths(lockFiles))));
|
fmt("waiting for lock on %s", Magenta(showPaths(lockFiles))));
|
||||||
worker.waitForAWhile(shared_from_this());
|
worker.waitForAWhile(shared_from_this());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -762,7 +762,7 @@ void DerivationGoal::tryToBuild()
|
||||||
the wake-up timeout expires. */
|
the wake-up timeout expires. */
|
||||||
if (!actLock)
|
if (!actLock)
|
||||||
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
|
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
|
||||||
fmt("waiting for a machine to build '%s'", magentatxt(worker.store.printStorePath(drvPath))));
|
fmt("waiting for a machine to build '%s'", Magenta(worker.store.printStorePath(drvPath))));
|
||||||
worker.waitForAWhile(shared_from_this());
|
worker.waitForAWhile(shared_from_this());
|
||||||
outputLocks.unlock();
|
outputLocks.unlock();
|
||||||
return;
|
return;
|
||||||
|
@ -987,7 +987,7 @@ void DerivationGoal::buildDone()
|
||||||
diskFull |= cleanupDecideWhetherDiskFull();
|
diskFull |= cleanupDecideWhetherDiskFull();
|
||||||
|
|
||||||
auto msg = fmt("builder for '%s' %s",
|
auto msg = fmt("builder for '%s' %s",
|
||||||
magentatxt(worker.store.printStorePath(drvPath)),
|
Magenta(worker.store.printStorePath(drvPath)),
|
||||||
statusToString(status));
|
statusToString(status));
|
||||||
|
|
||||||
if (!logger->isVerbose() && !logTail.empty()) {
|
if (!logger->isVerbose() && !logTail.empty()) {
|
||||||
|
@ -1523,7 +1523,7 @@ void DerivationGoal::done(
|
||||||
outputLocks.unlock();
|
outputLocks.unlock();
|
||||||
buildResult.status = status;
|
buildResult.status = status;
|
||||||
if (ex)
|
if (ex)
|
||||||
buildResult.errorMsg = fmt("%s", normaltxt(ex->info().msg));
|
buildResult.errorMsg = fmt("%s", Uncolored(ex->info().msg));
|
||||||
if (buildResult.status == BuildResult::TimedOut)
|
if (buildResult.status == BuildResult::TimedOut)
|
||||||
worker.timedOut = true;
|
worker.timedOut = true;
|
||||||
if (buildResult.status == BuildResult::PermanentFailure)
|
if (buildResult.status == BuildResult::PermanentFailure)
|
||||||
|
|
|
@ -87,7 +87,7 @@ void handleDiffHook(
|
||||||
} catch (Error & error) {
|
} catch (Error & error) {
|
||||||
ErrorInfo ei = error.info();
|
ErrorInfo ei = error.info();
|
||||||
// FIXME: wrap errors.
|
// FIXME: wrap errors.
|
||||||
ei.msg = hintfmt("diff hook execution failed: %s", ei.msg.str());
|
ei.msg = HintFmt("diff hook execution failed: %s", ei.msg.str());
|
||||||
logError(ei);
|
logError(ei);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ void LocalDerivationGoal::tryLocalBuild()
|
||||||
if (!buildUser) {
|
if (!buildUser) {
|
||||||
if (!actLock)
|
if (!actLock)
|
||||||
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
|
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
|
||||||
fmt("waiting for a free build user ID for '%s'", magentatxt(worker.store.printStorePath(drvPath))));
|
fmt("waiting for a free build user ID for '%s'", Magenta(worker.store.printStorePath(drvPath))));
|
||||||
worker.waitForAWhile(shared_from_this());
|
worker.waitForAWhile(shared_from_this());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -881,12 +881,12 @@ template<typename... Args>
|
||||||
FileTransferError::FileTransferError(FileTransfer::Error error, std::optional<std::string> response, const Args & ... args)
|
FileTransferError::FileTransferError(FileTransfer::Error error, std::optional<std::string> response, const Args & ... args)
|
||||||
: Error(args...), error(error), response(response)
|
: Error(args...), error(error), response(response)
|
||||||
{
|
{
|
||||||
const auto hf = hintfmt(args...);
|
const auto hf = HintFmt(args...);
|
||||||
// FIXME: Due to https://github.com/NixOS/nix/issues/3841 we don't know how
|
// FIXME: Due to https://github.com/NixOS/nix/issues/3841 we don't know how
|
||||||
// to print different messages for different verbosity levels. For now
|
// to print different messages for different verbosity levels. For now
|
||||||
// we add some heuristics for detecting when we want to show the response.
|
// we add some heuristics for detecting when we want to show the response.
|
||||||
if (response && (response->size() < 1024 || response->find("<html>") != std::string::npos))
|
if (response && (response->size() < 1024 || response->find("<html>") != std::string::npos))
|
||||||
err.msg = hintfmt("%1%\n\nresponse body:\n\n%2%", normaltxt(hf.str()), chomp(*response));
|
err.msg = HintFmt("%1%\n\nresponse body:\n\n%2%", Uncolored(hf.str()), chomp(*response));
|
||||||
else
|
else
|
||||||
err.msg = hf;
|
err.msg = hf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,19 +9,19 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
SQLiteError::SQLiteError(const char *path, const char *errMsg, int errNo, int extendedErrNo, int offset, hintformat && hf)
|
SQLiteError::SQLiteError(const char *path, const char *errMsg, int errNo, int extendedErrNo, int offset, HintFmt && hf)
|
||||||
: Error(""), path(path), errMsg(errMsg), errNo(errNo), extendedErrNo(extendedErrNo), offset(offset)
|
: Error(""), path(path), errMsg(errMsg), errNo(errNo), extendedErrNo(extendedErrNo), offset(offset)
|
||||||
{
|
{
|
||||||
auto offsetStr = (offset == -1) ? "" : "at offset " + std::to_string(offset) + ": ";
|
auto offsetStr = (offset == -1) ? "" : "at offset " + std::to_string(offset) + ": ";
|
||||||
err.msg = hintfmt("%s: %s%s, %s (in '%s')",
|
err.msg = HintFmt("%s: %s%s, %s (in '%s')",
|
||||||
normaltxt(hf.str()),
|
Uncolored(hf.str()),
|
||||||
offsetStr,
|
offsetStr,
|
||||||
sqlite3_errstr(extendedErrNo),
|
sqlite3_errstr(extendedErrNo),
|
||||||
errMsg,
|
errMsg,
|
||||||
path ? path : "(in-memory)");
|
path ? path : "(in-memory)");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void SQLiteError::throw_(sqlite3 * db, hintformat && hf)
|
[[noreturn]] void SQLiteError::throw_(sqlite3 * db, HintFmt && hf)
|
||||||
{
|
{
|
||||||
int err = sqlite3_errcode(db);
|
int err = sqlite3_errcode(db);
|
||||||
int exterr = sqlite3_extended_errcode(db);
|
int exterr = sqlite3_extended_errcode(db);
|
||||||
|
@ -32,7 +32,7 @@ SQLiteError::SQLiteError(const char *path, const char *errMsg, int errNo, int ex
|
||||||
|
|
||||||
if (err == SQLITE_BUSY || err == SQLITE_PROTOCOL) {
|
if (err == SQLITE_BUSY || err == SQLITE_PROTOCOL) {
|
||||||
auto exp = SQLiteBusy(path, errMsg, err, exterr, offset, std::move(hf));
|
auto exp = SQLiteBusy(path, errMsg, err, exterr, offset, std::move(hf));
|
||||||
exp.err.msg = hintfmt(
|
exp.err.msg = HintFmt(
|
||||||
err == SQLITE_PROTOCOL
|
err == SQLITE_PROTOCOL
|
||||||
? "SQLite database '%s' is busy (SQLITE_PROTOCOL)"
|
? "SQLite database '%s' is busy (SQLITE_PROTOCOL)"
|
||||||
: "SQLite database '%s' is busy",
|
: "SQLite database '%s' is busy",
|
||||||
|
@ -248,7 +248,7 @@ void handleSQLiteBusy(const SQLiteBusy & e, time_t & nextWarning)
|
||||||
if (now > nextWarning) {
|
if (now > nextWarning) {
|
||||||
nextWarning = now + 10;
|
nextWarning = now + 10;
|
||||||
logWarning({
|
logWarning({
|
||||||
.msg = hintfmt(e.what())
|
.msg = HintFmt(e.what())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,19 +142,19 @@ struct SQLiteError : Error
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
[[noreturn]] static void throw_(sqlite3 * db, const std::string & fs, const Args & ... args) {
|
[[noreturn]] static void throw_(sqlite3 * db, const std::string & fs, const Args & ... args) {
|
||||||
throw_(db, hintfmt(fs, args...));
|
throw_(db, HintFmt(fs, args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLiteError(const char *path, const char *errMsg, int errNo, int extendedErrNo, int offset, hintformat && hf);
|
SQLiteError(const char *path, const char *errMsg, int errNo, int extendedErrNo, int offset, HintFmt && hf);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
SQLiteError(const char *path, const char *errMsg, int errNo, int extendedErrNo, int offset, const std::string & fs, const Args & ... args)
|
SQLiteError(const char *path, const char *errMsg, int errNo, int extendedErrNo, int offset, const std::string & fs, const Args & ... args)
|
||||||
: SQLiteError(path, errNo, extendedErrNo, offset, hintfmt(fs, args...))
|
: SQLiteError(path, errMsg, errNo, extendedErrNo, offset, HintFmt(fs, args...))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
[[noreturn]] static void throw_(sqlite3 * db, hintformat && hf);
|
[[noreturn]] static void throw_(sqlite3 * db, HintFmt && hf);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace nix {
|
||||||
|
|
||||||
const std::string nativeSystem = SYSTEM;
|
const std::string nativeSystem = SYSTEM;
|
||||||
|
|
||||||
void BaseError::addTrace(std::shared_ptr<Pos> && e, hintformat hint, bool frame)
|
void BaseError::addTrace(std::shared_ptr<Pos> && e, HintFmt hint, bool frame)
|
||||||
{
|
{
|
||||||
err.traces.push_front(Trace { .pos = std::move(e), .hint = hint, .frame = frame });
|
err.traces.push_front(Trace { .pos = std::move(e), .hint = hint, .frame = frame });
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ const std::string & BaseError::calcWhat() const
|
||||||
|
|
||||||
std::optional<std::string> ErrorInfo::programName = std::nullopt;
|
std::optional<std::string> ErrorInfo::programName = std::nullopt;
|
||||||
|
|
||||||
std::ostream & operator <<(std::ostream & os, const hintformat & hf)
|
std::ostream & operator <<(std::ostream & os, const HintFmt & hf)
|
||||||
{
|
{
|
||||||
return os << hf.str();
|
return os << hf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ void printCodeLines(std::ostream & out,
|
||||||
|
|
||||||
struct Trace {
|
struct Trace {
|
||||||
std::shared_ptr<Pos> pos;
|
std::shared_ptr<Pos> pos;
|
||||||
hintformat hint;
|
HintFmt hint;
|
||||||
bool frame;
|
bool frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ inline bool operator>=(const Trace& lhs, const Trace& rhs);
|
||||||
|
|
||||||
struct ErrorInfo {
|
struct ErrorInfo {
|
||||||
Verbosity level;
|
Verbosity level;
|
||||||
hintformat msg;
|
HintFmt msg;
|
||||||
std::shared_ptr<Pos> pos;
|
std::shared_ptr<Pos> pos;
|
||||||
std::list<Trace> traces;
|
std::list<Trace> traces;
|
||||||
|
|
||||||
|
@ -113,20 +113,20 @@ public:
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
BaseError(unsigned int status, const Args & ... args)
|
BaseError(unsigned int status, const Args & ... args)
|
||||||
: err { .level = lvlError, .msg = hintfmt(args...), .status = status }
|
: err { .level = lvlError, .msg = HintFmt(args...), .status = status }
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
explicit BaseError(const std::string & fs, const Args & ... args)
|
explicit BaseError(const std::string & fs, const Args & ... args)
|
||||||
: err { .level = lvlError, .msg = hintfmt(fs, args...) }
|
: err { .level = lvlError, .msg = HintFmt(fs, args...) }
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
BaseError(const Suggestions & sug, const Args & ... args)
|
BaseError(const Suggestions & sug, const Args & ... args)
|
||||||
: err { .level = lvlError, .msg = hintfmt(args...), .suggestions = sug }
|
: err { .level = lvlError, .msg = HintFmt(args...), .suggestions = sug }
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
BaseError(hintformat hint)
|
BaseError(HintFmt hint)
|
||||||
: err { .level = lvlError, .msg = hint }
|
: err { .level = lvlError, .msg = hint }
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
@ -159,10 +159,10 @@ public:
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
void addTrace(std::shared_ptr<Pos> && e, std::string_view fs, const Args & ... args)
|
void addTrace(std::shared_ptr<Pos> && e, std::string_view fs, const Args & ... args)
|
||||||
{
|
{
|
||||||
addTrace(std::move(e), hintfmt(std::string(fs), args...));
|
addTrace(std::move(e), HintFmt(std::string(fs), args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTrace(std::shared_ptr<Pos> && e, hintformat hint, bool frame = false);
|
void addTrace(std::shared_ptr<Pos> && e, HintFmt hint, bool frame = false);
|
||||||
|
|
||||||
bool hasTrace() const { return !err.traces.empty(); }
|
bool hasTrace() const { return !err.traces.empty(); }
|
||||||
|
|
||||||
|
@ -190,8 +190,8 @@ public:
|
||||||
: Error("")
|
: Error("")
|
||||||
{
|
{
|
||||||
errNo = errNo_;
|
errNo = errNo_;
|
||||||
auto hf = hintfmt(args...);
|
auto hf = HintFmt(args...);
|
||||||
err.msg = hintfmt("%1%: %2%", normaltxt(hf.str()), strerror(errNo));
|
err.msg = HintFmt("%1%: %2%", Uncolored(hf.str()), strerror(errNo));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
|
|
|
@ -8,37 +8,64 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
namespace {
|
||||||
/**
|
/**
|
||||||
* Inherit some names from other namespaces for convenience.
|
* A helper for writing `boost::format` expressions.
|
||||||
*/
|
*
|
||||||
using boost::format;
|
* These are equivalent:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
/**
|
* formatHelper(formatter, a_0, ..., a_n)
|
||||||
* A variadic template that does nothing. Useful to call a function
|
* formatter % a_0 % ... % a_n
|
||||||
* for all variadic arguments but ignoring the result.
|
* ```
|
||||||
*/
|
*
|
||||||
struct nop { template<typename... T> nop(T...) {} };
|
* With a single argument, `formatHelper(s)` is a no-op.
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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).
|
|
||||||
*/
|
*/
|
||||||
template<class F>
|
template<class F>
|
||||||
inline void formatHelper(F & f)
|
inline void formatHelper(F & f)
|
||||||
{
|
{ }
|
||||||
}
|
|
||||||
|
|
||||||
template<class F, typename T, typename... Args>
|
template<class F, typename T, typename... Args>
|
||||||
inline void formatHelper(F & f, const T & x, const Args & ... args)
|
inline void formatHelper(F & f, const T & x, const Args & ... args)
|
||||||
{
|
{
|
||||||
|
// Interpolate one argument and then recurse.
|
||||||
formatHelper(f % x, args...);
|
formatHelper(f % x, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the correct exceptions for `fmt`.
|
||||||
|
*/
|
||||||
|
void setExceptions(boost::format & fmt)
|
||||||
|
{
|
||||||
|
fmt.exceptions(
|
||||||
|
boost::io::all_error_bits ^
|
||||||
|
boost::io::too_many_args_bit ^
|
||||||
|
boost::io::too_few_args_bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper for writing a `boost::format` expression to a string.
|
||||||
|
*
|
||||||
|
* These are (roughly) equivalent:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* fmt(formatString, a_0, ..., a_n)
|
||||||
|
* (boost::format(formatString) % a_0 % ... % a_n).str()
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* However, when called with a single argument, the string is returned
|
||||||
|
* unchanged.
|
||||||
|
*
|
||||||
|
* If you write code like this:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* std::cout << boost::format(stringFromUserInput) << std::endl;
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* And `stringFromUserInput` contains formatting placeholders like `%s`, then
|
||||||
|
* the code will crash at runtime. `fmt` helps you avoid this pitfall.
|
||||||
|
*/
|
||||||
inline std::string fmt(const std::string & s)
|
inline std::string fmt(const std::string & s)
|
||||||
{
|
{
|
||||||
return s;
|
return s;
|
||||||
|
@ -53,66 +80,96 @@ template<typename... Args>
|
||||||
inline std::string fmt(const std::string & fs, const Args & ... args)
|
inline std::string fmt(const std::string & fs, const Args & ... args)
|
||||||
{
|
{
|
||||||
boost::format f(fs);
|
boost::format f(fs);
|
||||||
f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
|
setExceptions(f);
|
||||||
formatHelper(f, args...);
|
formatHelper(f, args...);
|
||||||
return f.str();
|
return f.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// format function for hints in errors. same as fmt, except templated values
|
/**
|
||||||
// are always in magenta.
|
* Values wrapped in this struct are printed in magenta.
|
||||||
|
*
|
||||||
|
* By default, arguments to `HintFmt` are printed in magenta. To avoid this,
|
||||||
|
* either wrap the argument in `Uncolored` or add a specialization of
|
||||||
|
* `HintFmt::operator%`.
|
||||||
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
struct magentatxt
|
struct Magenta
|
||||||
{
|
{
|
||||||
magentatxt(const T &s) : value(s) {}
|
Magenta(const T &s) : value(s) {}
|
||||||
const T & value;
|
const T & value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
std::ostream & operator<<(std::ostream & out, const magentatxt<T> & y)
|
std::ostream & operator<<(std::ostream & out, const Magenta<T> & y)
|
||||||
{
|
{
|
||||||
return out << ANSI_WARNING << y.value << ANSI_NORMAL;
|
return out << ANSI_WARNING << y.value << ANSI_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Values wrapped in this class are printed without coloring.
|
||||||
|
*
|
||||||
|
* By default, arguments to `HintFmt` are printed in magenta (see `Magenta`).
|
||||||
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
struct normaltxt
|
struct Uncolored
|
||||||
{
|
{
|
||||||
normaltxt(const T & s) : value(s) {}
|
Uncolored(const T & s) : value(s) {}
|
||||||
const T & value;
|
const T & value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
std::ostream & operator<<(std::ostream & out, const normaltxt<T> & y)
|
std::ostream & operator<<(std::ostream & out, const Uncolored<T> & y)
|
||||||
{
|
{
|
||||||
return out << ANSI_NORMAL << y.value;
|
return out << ANSI_NORMAL << y.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
class hintformat
|
/**
|
||||||
|
* A wrapper around `boost::format` which colors interpolated arguments in
|
||||||
|
* magenta by default.
|
||||||
|
*/
|
||||||
|
class HintFmt
|
||||||
{
|
{
|
||||||
public:
|
private:
|
||||||
hintformat(const std::string & format) : fmt(format)
|
boost::format fmt;
|
||||||
{
|
|
||||||
fmt.exceptions(boost::io::all_error_bits ^
|
|
||||||
boost::io::too_many_args_bit ^
|
|
||||||
boost::io::too_few_args_bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
hintformat(const hintformat & hf)
|
public:
|
||||||
|
/**
|
||||||
|
* Format the given string literally, without interpolating format
|
||||||
|
* placeholders.
|
||||||
|
*/
|
||||||
|
HintFmt(const std::string & literal)
|
||||||
|
: HintFmt("%s", Uncolored(literal))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interpolate the given arguments into the format string.
|
||||||
|
*/
|
||||||
|
template<typename... Args>
|
||||||
|
HintFmt(const std::string & format, const Args & ... args)
|
||||||
|
: HintFmt(boost::format(format), args...)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
HintFmt(const HintFmt & hf)
|
||||||
: fmt(hf.fmt)
|
: fmt(hf.fmt)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
hintformat(format && fmt)
|
template<typename... Args>
|
||||||
|
HintFmt(boost::format && fmt, const Args & ... args)
|
||||||
: fmt(std::move(fmt))
|
: fmt(std::move(fmt))
|
||||||
{ }
|
{
|
||||||
|
setExceptions(fmt);
|
||||||
|
formatHelper(*this, args...);
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
hintformat & operator%(const T & value)
|
HintFmt & operator%(const T & value)
|
||||||
{
|
{
|
||||||
fmt % magentatxt(value);
|
fmt % Magenta(value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
hintformat & operator%(const normaltxt<T> & value)
|
HintFmt & operator%(const Uncolored<T> & value)
|
||||||
{
|
{
|
||||||
fmt % value.value;
|
fmt % value.value;
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -122,25 +179,8 @@ public:
|
||||||
{
|
{
|
||||||
return fmt.str();
|
return fmt.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
format fmt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & os, const hintformat & hf);
|
std::ostream & operator<<(std::ostream & os, const HintFmt & hf);
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
inline hintformat hintfmt(const std::string & fs, const Args & ... args)
|
|
||||||
{
|
|
||||||
hintformat f(fs);
|
|
||||||
formatHelper(f, args...);
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline hintformat hintfmt(const std::string & plain_string)
|
|
||||||
{
|
|
||||||
// we won't be receiving any args in this case, so just print the original string
|
|
||||||
return hintfmt("%s", normaltxt(plain_string));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,17 @@ public:
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A variadic template that does nothing.
|
||||||
|
*
|
||||||
|
* Useful to call a function with each argument in a parameter pack.
|
||||||
|
*/
|
||||||
|
struct nop
|
||||||
|
{
|
||||||
|
template<typename... T> nop(T...)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
ActivityId getCurActivity();
|
ActivityId getCurActivity();
|
||||||
void setCurActivity(const ActivityId activityId);
|
void setCurActivity(const ActivityId activityId);
|
||||||
|
|
||||||
|
|
|
@ -444,7 +444,7 @@ Error readError(Source & source)
|
||||||
auto msg = readString(source);
|
auto msg = readString(source);
|
||||||
ErrorInfo info {
|
ErrorInfo info {
|
||||||
.level = level,
|
.level = level,
|
||||||
.msg = hintfmt(msg),
|
.msg = HintFmt(msg),
|
||||||
};
|
};
|
||||||
auto havePos = readNum<size_t>(source);
|
auto havePos = readNum<size_t>(source);
|
||||||
assert(havePos == 0);
|
assert(havePos == 0);
|
||||||
|
@ -453,7 +453,7 @@ Error readError(Source & source)
|
||||||
havePos = readNum<size_t>(source);
|
havePos = readNum<size_t>(source);
|
||||||
assert(havePos == 0);
|
assert(havePos == 0);
|
||||||
info.traces.push_back(Trace {
|
info.traces.push_back(Trace {
|
||||||
.hint = hintfmt(readString(source))
|
.hint = HintFmt(readString(source))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return Error(std::move(info));
|
return Error(std::move(info));
|
||||||
|
|
|
@ -1872,7 +1872,7 @@ void setStackSize(rlim_t stackSize)
|
||||||
if (setrlimit(RLIMIT_STACK, &limit) != 0) {
|
if (setrlimit(RLIMIT_STACK, &limit) != 0) {
|
||||||
logger->log(
|
logger->log(
|
||||||
lvlError,
|
lvlError,
|
||||||
hintfmt(
|
HintFmt(
|
||||||
"Failed to increase stack size from %1% to %2% (maximum allowed stack size: %3%): %4%",
|
"Failed to increase stack size from %1% to %2% (maximum allowed stack size: %3%): %4%",
|
||||||
savedStackSize,
|
savedStackSize,
|
||||||
stackSize,
|
stackSize,
|
||||||
|
|
|
@ -376,7 +376,7 @@ static void daemonLoop(std::optional<TrustedFlag> forceTrustClientOpt)
|
||||||
} catch (Error & error) {
|
} catch (Error & error) {
|
||||||
auto ei = error.info();
|
auto ei = error.info();
|
||||||
// FIXME: add to trace?
|
// FIXME: add to trace?
|
||||||
ei.msg = hintfmt("error processing connection: %1%", ei.msg.str());
|
ei.msg = HintFmt("error processing connection: %1%", ei.msg.str());
|
||||||
logError(ei);
|
logError(ei);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ struct CmdEval : MixJSON, InstallableValueCommand, MixReadOnlyOption
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(
|
e.addTrace(
|
||||||
state->positions[attr.pos],
|
state->positions[attr.pos],
|
||||||
hintfmt("while evaluating the attribute '%s'", name));
|
HintFmt("while evaluating the attribute '%s'", name));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,7 +370,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
return storePath;
|
return storePath;
|
||||||
}
|
}
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(resolve(pos), hintfmt("while checking the derivation '%s'", attrPath));
|
e.addTrace(resolve(pos), HintFmt("while checking the derivation '%s'", attrPath));
|
||||||
reportError(e);
|
reportError(e);
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -389,7 +389,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(resolve(pos), hintfmt("while checking the app definition '%s'", attrPath));
|
e.addTrace(resolve(pos), HintFmt("while checking the app definition '%s'", attrPath));
|
||||||
reportError(e);
|
reportError(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -413,7 +413,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
// FIXME: if we have a 'nixpkgs' input, use it to
|
// FIXME: if we have a 'nixpkgs' input, use it to
|
||||||
// evaluate the overlay.
|
// evaluate the overlay.
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(resolve(pos), hintfmt("while checking the overlay '%s'", attrPath));
|
e.addTrace(resolve(pos), HintFmt("while checking the overlay '%s'", attrPath));
|
||||||
reportError(e);
|
reportError(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -424,7 +424,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
fmt("checking NixOS module '%s'", attrPath));
|
fmt("checking NixOS module '%s'", attrPath));
|
||||||
state->forceValue(v, pos);
|
state->forceValue(v, pos);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(resolve(pos), hintfmt("while checking the NixOS module '%s'", attrPath));
|
e.addTrace(resolve(pos), HintFmt("while checking the NixOS module '%s'", attrPath));
|
||||||
reportError(e);
|
reportError(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -452,7 +452,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(resolve(pos), hintfmt("while checking the Hydra jobset '%s'", attrPath));
|
e.addTrace(resolve(pos), HintFmt("while checking the Hydra jobset '%s'", attrPath));
|
||||||
reportError(e);
|
reportError(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -467,7 +467,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
if (!state->isDerivation(*vToplevel))
|
if (!state->isDerivation(*vToplevel))
|
||||||
throw Error("attribute 'config.system.build.toplevel' is not a derivation");
|
throw Error("attribute 'config.system.build.toplevel' is not a derivation");
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(resolve(pos), hintfmt("while checking the NixOS configuration '%s'", attrPath));
|
e.addTrace(resolve(pos), HintFmt("while checking the NixOS configuration '%s'", attrPath));
|
||||||
reportError(e);
|
reportError(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -501,7 +501,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
throw Error("template '%s' has unsupported attribute '%s'", attrPath, name);
|
throw Error("template '%s' has unsupported attribute '%s'", attrPath, name);
|
||||||
}
|
}
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(resolve(pos), hintfmt("while checking the template '%s'", attrPath));
|
e.addTrace(resolve(pos), HintFmt("while checking the template '%s'", attrPath));
|
||||||
reportError(e);
|
reportError(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -515,7 +515,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
throw Error("bundler must be a function");
|
throw Error("bundler must be a function");
|
||||||
// TODO: check types of inputs/outputs?
|
// TODO: check types of inputs/outputs?
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(resolve(pos), hintfmt("while checking the template '%s'", attrPath));
|
e.addTrace(resolve(pos), HintFmt("while checking the template '%s'", attrPath));
|
||||||
reportError(e);
|
reportError(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -735,7 +735,7 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
warn("unknown flake output '%s'", name);
|
warn("unknown flake output '%s'", name);
|
||||||
|
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(resolve(pos), hintfmt("while checking flake output '%s'", name));
|
e.addTrace(resolve(pos), HintFmt("while checking flake output '%s'", name));
|
||||||
reportError(e);
|
reportError(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -43,7 +43,7 @@ namespace nix {
|
||||||
|
|
||||||
makeJSONLogger(*logger)->logEI({
|
makeJSONLogger(*logger)->logEI({
|
||||||
.name = "error name",
|
.name = "error name",
|
||||||
.msg = hintfmt("this hint has %1% templated %2%!!",
|
.msg = HintFmt("this hint has %1% templated %2%!!",
|
||||||
"yellow",
|
"yellow",
|
||||||
"values"),
|
"values"),
|
||||||
.errPos = Pos(foFile, problem_file, 02, 13)
|
.errPos = Pos(foFile, problem_file, 02, 13)
|
||||||
|
@ -63,7 +63,7 @@ namespace nix {
|
||||||
throw TestError(e.info());
|
throw TestError(e.info());
|
||||||
} catch (Error &e) {
|
} catch (Error &e) {
|
||||||
ErrorInfo ei = e.info();
|
ErrorInfo ei = e.info();
|
||||||
ei.msg = hintfmt("%s; subsequent error message.", normaltxt(e.info().msg.str()));
|
ei.msg = HintFmt("%s; subsequent error message.", Uncolored(e.info().msg.str()));
|
||||||
|
|
||||||
testing::internal::CaptureStderr();
|
testing::internal::CaptureStderr();
|
||||||
logger->logEI(ei);
|
logger->logEI(ei);
|
||||||
|
@ -177,7 +177,7 @@ namespace nix {
|
||||||
|
|
||||||
logError({
|
logError({
|
||||||
.name = "error name",
|
.name = "error name",
|
||||||
.msg = hintfmt("this hint has %1% templated %2%!!",
|
.msg = HintFmt("this hint has %1% templated %2%!!",
|
||||||
"yellow",
|
"yellow",
|
||||||
"values"),
|
"values"),
|
||||||
.errPos = Pos(foString, problem_file, 02, 13),
|
.errPos = Pos(foString, problem_file, 02, 13),
|
||||||
|
@ -194,7 +194,7 @@ namespace nix {
|
||||||
|
|
||||||
logError({
|
logError({
|
||||||
.name = "error name",
|
.name = "error name",
|
||||||
.msg = hintfmt("this hint has %1% templated %2%!!",
|
.msg = HintFmt("this hint has %1% templated %2%!!",
|
||||||
"yellow",
|
"yellow",
|
||||||
"values"),
|
"values"),
|
||||||
.errPos = Pos(foFile, problem_file, 02, 13)
|
.errPos = Pos(foFile, problem_file, 02, 13)
|
||||||
|
@ -209,7 +209,7 @@ namespace nix {
|
||||||
|
|
||||||
logError({
|
logError({
|
||||||
.name = "error name",
|
.name = "error name",
|
||||||
.msg = hintfmt("hint %1%", "only"),
|
.msg = HintFmt("hint %1%", "only"),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto str = testing::internal::GetCapturedStderr();
|
auto str = testing::internal::GetCapturedStderr();
|
||||||
|
@ -226,7 +226,7 @@ namespace nix {
|
||||||
|
|
||||||
logWarning({
|
logWarning({
|
||||||
.name = "name",
|
.name = "name",
|
||||||
.msg = hintfmt("there was a %1%", "warning"),
|
.msg = HintFmt("there was a %1%", "warning"),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto str = testing::internal::GetCapturedStderr();
|
auto str = testing::internal::GetCapturedStderr();
|
||||||
|
@ -242,7 +242,7 @@ namespace nix {
|
||||||
|
|
||||||
logWarning({
|
logWarning({
|
||||||
.name = "warning name",
|
.name = "warning name",
|
||||||
.msg = hintfmt("this hint has %1% templated %2%!!",
|
.msg = HintFmt("this hint has %1% templated %2%!!",
|
||||||
"yellow",
|
"yellow",
|
||||||
"values"),
|
"values"),
|
||||||
.errPos = Pos(foStdin, problem_file, 2, 13),
|
.errPos = Pos(foStdin, problem_file, 2, 13),
|
||||||
|
@ -265,7 +265,7 @@ namespace nix {
|
||||||
|
|
||||||
auto e = AssertionError(ErrorInfo {
|
auto e = AssertionError(ErrorInfo {
|
||||||
.name = "wat",
|
.name = "wat",
|
||||||
.msg = hintfmt("it has been %1% days since our last error", "zero"),
|
.msg = HintFmt("it has been %1% days since our last error", "zero"),
|
||||||
.errPos = Pos(foString, problem_file, 2, 13),
|
.errPos = Pos(foString, problem_file, 2, 13),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ namespace nix {
|
||||||
|
|
||||||
auto e = AssertionError(ErrorInfo {
|
auto e = AssertionError(ErrorInfo {
|
||||||
.name = "wat",
|
.name = "wat",
|
||||||
.msg = hintfmt("it has been %1% days since our last error", "zero"),
|
.msg = HintFmt("it has been %1% days since our last error", "zero"),
|
||||||
.errPos = Pos(foString, problem_file, 2, 13),
|
.errPos = Pos(foString, problem_file, 2, 13),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -311,39 +311,39 @@ namespace nix {
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* hintfmt
|
* HintFmt
|
||||||
* --------------------------------------------------------------------------*/
|
* --------------------------------------------------------------------------*/
|
||||||
|
|
||||||
TEST(hintfmt, percentStringWithoutArgs) {
|
TEST(HintFmt, percentStringWithoutArgs) {
|
||||||
|
|
||||||
const char *teststr = "this is 100%s correct!";
|
const char *teststr = "this is 100%s correct!";
|
||||||
|
|
||||||
ASSERT_STREQ(
|
ASSERT_STREQ(
|
||||||
hintfmt(teststr).str().c_str(),
|
HintFmt(teststr).str().c_str(),
|
||||||
teststr);
|
teststr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(hintfmt, fmtToHintfmt) {
|
TEST(HintFmt, fmtToHintfmt) {
|
||||||
|
|
||||||
ASSERT_STREQ(
|
ASSERT_STREQ(
|
||||||
hintfmt(fmt("the color of this this text is %1%", "not yellow")).str().c_str(),
|
HintFmt(fmt("the color of this this text is %1%", "not yellow")).str().c_str(),
|
||||||
"the color of this this text is not yellow");
|
"the color of this this text is not yellow");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(hintfmt, tooFewArguments) {
|
TEST(HintFmt, tooFewArguments) {
|
||||||
|
|
||||||
ASSERT_STREQ(
|
ASSERT_STREQ(
|
||||||
hintfmt("only one arg %1% %2%", "fulfilled").str().c_str(),
|
HintFmt("only one arg %1% %2%", "fulfilled").str().c_str(),
|
||||||
"only one arg " ANSI_WARNING "fulfilled" ANSI_NORMAL " ");
|
"only one arg " ANSI_WARNING "fulfilled" ANSI_NORMAL " ");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(hintfmt, tooManyArguments) {
|
TEST(HintFmt, tooManyArguments) {
|
||||||
|
|
||||||
ASSERT_STREQ(
|
ASSERT_STREQ(
|
||||||
hintfmt("what about this %1% %2%", "%3%", "one", "two").str().c_str(),
|
HintFmt("what about this %1% %2%", "%3%", "one", "two").str().c_str(),
|
||||||
"what about this " ANSI_WARNING "%3%" ANSI_NORMAL " " ANSI_YELLOW "one" ANSI_NORMAL);
|
"what about this " ANSI_WARNING "%3%" ANSI_NORMAL " " ANSI_YELLOW "one" ANSI_NORMAL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue