forceString: Show position info
This commit is contained in:
parent
27b44b8cf7
commit
a5fe730940
6 changed files with 46 additions and 30 deletions
|
@ -140,7 +140,8 @@ static void * oomHandler(size_t requested)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static Symbol getName(const AttrName & name, EvalState & state, Env & env) {
|
static Symbol getName(const AttrName & name, EvalState & state, Env & env)
|
||||||
|
{
|
||||||
if (name.symbol.set()) {
|
if (name.symbol.set()) {
|
||||||
return name.symbol;
|
return name.symbol;
|
||||||
} else {
|
} else {
|
||||||
|
@ -279,6 +280,11 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con
|
||||||
throw EvalError(format(s) % s2 % s3);
|
throw EvalError(format(s) % s2 % s3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, const Pos & pos))
|
||||||
|
{
|
||||||
|
throw EvalError(format(s) % s2 % s3 % pos);
|
||||||
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2))
|
LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2))
|
||||||
{
|
{
|
||||||
throw EvalError(format(s) % sym % p1 % p2);
|
throw EvalError(format(s) % sym % p1 % p2);
|
||||||
|
@ -1172,11 +1178,15 @@ void EvalState::forceFunction(Value & v, const Pos & pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string EvalState::forceString(Value & v)
|
string EvalState::forceString(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
forceValue(v);
|
forceValue(v);
|
||||||
if (v.type != tString)
|
if (v.type != tString) {
|
||||||
|
if (pos)
|
||||||
|
throwTypeError("value is %1% while a string was expected, at %2%", v, pos);
|
||||||
|
else
|
||||||
throwTypeError("value is %1% while a string was expected", v);
|
throwTypeError("value is %1% while a string was expected", v);
|
||||||
|
}
|
||||||
return string(v.string.s);
|
return string(v.string.s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,12 +1207,17 @@ string EvalState::forceString(Value & v, PathSet & context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string EvalState::forceStringNoCtx(Value & v)
|
string EvalState::forceStringNoCtx(Value & v, const Pos & pos)
|
||||||
{
|
{
|
||||||
string s = forceString(v);
|
string s = forceString(v, pos);
|
||||||
if (v.string.context)
|
if (v.string.context) {
|
||||||
|
if (pos)
|
||||||
|
throwEvalError("the string `%1%' is not allowed to refer to a store path (such as `%2%'), at %3%",
|
||||||
|
v.string.s, v.string.context[0], pos);
|
||||||
|
else
|
||||||
throwEvalError("the string `%1%' is not allowed to refer to a store path (such as `%2%')",
|
throwEvalError("the string `%1%' is not allowed to refer to a store path (such as `%2%')",
|
||||||
v.string.s, v.string.context[0]);
|
v.string.s, v.string.context[0]);
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,9 +165,9 @@ public:
|
||||||
inline void forceList(Value & v);
|
inline void forceList(Value & v);
|
||||||
inline void forceList(Value & v, const Pos & pos);
|
inline void forceList(Value & v, const Pos & pos);
|
||||||
void forceFunction(Value & v, const Pos & pos); // either lambda or primop
|
void forceFunction(Value & v, const Pos & pos); // either lambda or primop
|
||||||
string forceString(Value & v);
|
string forceString(Value & v, const Pos & pos = noPos);
|
||||||
string forceString(Value & v, PathSet & context);
|
string forceString(Value & v, PathSet & context);
|
||||||
string forceStringNoCtx(Value & v);
|
string forceStringNoCtx(Value & v, const Pos & pos = noPos);
|
||||||
|
|
||||||
/* Return true iff the value `v' denotes a derivation (i.e. a
|
/* Return true iff the value `v' denotes a derivation (i.e. a
|
||||||
set with attribute `type = "derivation"'). */
|
set with attribute `type = "derivation"'). */
|
||||||
|
|
|
@ -41,7 +41,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs()
|
||||||
/* For each output... */
|
/* For each output... */
|
||||||
for (unsigned int j = 0; j < i->value->list.length; ++j) {
|
for (unsigned int j = 0; j < i->value->list.length; ++j) {
|
||||||
/* Evaluate the corresponding set. */
|
/* Evaluate the corresponding set. */
|
||||||
string name = state->forceStringNoCtx(*i->value->list.elems[j]);
|
string name = state->forceStringNoCtx(*i->value->list.elems[j], *i->pos);
|
||||||
Bindings::iterator out = attrs->find(state->symbols.create(name));
|
Bindings::iterator out = attrs->find(state->symbols.create(name));
|
||||||
if (out == attrs->end()) continue; // FIXME: throw error?
|
if (out == attrs->end()) continue; // FIXME: throw error?
|
||||||
state->forceAttrs(*out->value);
|
state->forceAttrs(*out->value);
|
||||||
|
@ -199,11 +199,8 @@ static bool getDerivation(EvalState & state, Value & v,
|
||||||
|
|
||||||
Bindings::iterator i2 = v.attrs->find(state.sSystem);
|
Bindings::iterator i2 = v.attrs->find(state.sSystem);
|
||||||
|
|
||||||
DrvInfo drv(
|
DrvInfo drv(state, state.forceStringNoCtx(*i->value), attrPath,
|
||||||
state,
|
i2 == v.attrs->end() ? "unknown" : state.forceStringNoCtx(*i2->value, *i2->pos),
|
||||||
state.forceStringNoCtx(*i->value),
|
|
||||||
attrPath,
|
|
||||||
i2 == v.attrs->end() ? "unknown" : state.forceStringNoCtx(*i2->value),
|
|
||||||
v.attrs);
|
v.attrs);
|
||||||
|
|
||||||
drvs.push_back(drv);
|
drvs.push_back(drv);
|
||||||
|
|
|
@ -145,7 +145,7 @@ void ExprPos::show(std::ostream & str)
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & str, const Pos & pos)
|
std::ostream & operator << (std::ostream & str, const Pos & pos)
|
||||||
{
|
{
|
||||||
if (!pos.line)
|
if (!pos)
|
||||||
str << "undefined position";
|
str << "undefined position";
|
||||||
else
|
else
|
||||||
str << (format("%1%:%2%:%3%") % pos.file % pos.line % pos.column).str();
|
str << (format("%1%:%2%:%3%") % pos.file % pos.line % pos.column).str();
|
||||||
|
|
|
@ -28,6 +28,10 @@ struct Pos
|
||||||
Pos() : line(0), column(0) { };
|
Pos() : line(0), column(0) { };
|
||||||
Pos(const Symbol & file, unsigned int line, unsigned int column)
|
Pos(const Symbol & file, unsigned int line, unsigned int column)
|
||||||
: file(file), line(line), column(column) { };
|
: file(file), line(line), column(column) { };
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
return line != 0;
|
||||||
|
}
|
||||||
bool operator < (const Pos & p2) const
|
bool operator < (const Pos & p2) const
|
||||||
{
|
{
|
||||||
if (!line) return p2.line;
|
if (!line) return p2.line;
|
||||||
|
|
|
@ -299,7 +299,7 @@ static void prim_tryEval(EvalState & state, const Pos & pos, Value * * args, Val
|
||||||
/* Return an environment variable. Use with care. */
|
/* Return an environment variable. Use with care. */
|
||||||
static void prim_getEnv(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_getEnv(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string name = state.forceStringNoCtx(*args[0]);
|
string name = state.forceStringNoCtx(*args[0], pos);
|
||||||
mkString(v, getEnv(name));
|
mkString(v, getEnv(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
string drvName;
|
string drvName;
|
||||||
Pos & posDrvName(*attr->pos);
|
Pos & posDrvName(*attr->pos);
|
||||||
try {
|
try {
|
||||||
drvName = state.forceStringNoCtx(*attr->value);
|
drvName = state.forceStringNoCtx(*attr->value, pos);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addPrefix(format("while evaluating the derivation attribute `name' at %1%:\n") % posDrvName);
|
e.addPrefix(format("while evaluating the derivation attribute `name' at %1%:\n") % posDrvName);
|
||||||
throw;
|
throw;
|
||||||
|
@ -664,7 +664,7 @@ static void prim_toJSON(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
string name = state.forceStringNoCtx(*args[0]);
|
string name = state.forceStringNoCtx(*args[0], pos);
|
||||||
string contents = state.forceString(*args[1], context);
|
string contents = state.forceString(*args[1], context);
|
||||||
|
|
||||||
PathSet refs;
|
PathSet refs;
|
||||||
|
@ -775,7 +775,7 @@ static void prim_attrNames(EvalState & state, const Pos & pos, Value * * args, V
|
||||||
/* Dynamic version of the `.' operator. */
|
/* Dynamic version of the `.' operator. */
|
||||||
void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string attr = state.forceStringNoCtx(*args[0]);
|
string attr = state.forceStringNoCtx(*args[0], pos);
|
||||||
state.forceAttrs(*args[1], pos);
|
state.forceAttrs(*args[1], pos);
|
||||||
// !!! Should we create a symbol here or just do a lookup?
|
// !!! Should we create a symbol here or just do a lookup?
|
||||||
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
||||||
|
@ -791,7 +791,7 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
/* Return position information of the specified attribute. */
|
/* Return position information of the specified attribute. */
|
||||||
void prim_unsafeGetAttrPos(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
void prim_unsafeGetAttrPos(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string attr = state.forceStringNoCtx(*args[0]);
|
string attr = state.forceStringNoCtx(*args[0], pos);
|
||||||
state.forceAttrs(*args[1], pos);
|
state.forceAttrs(*args[1], pos);
|
||||||
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
||||||
if (i == args[1]->attrs->end())
|
if (i == args[1]->attrs->end())
|
||||||
|
@ -804,7 +804,7 @@ void prim_unsafeGetAttrPos(EvalState & state, const Pos & pos, Value * * args, V
|
||||||
/* Dynamic version of the `?' operator. */
|
/* Dynamic version of the `?' operator. */
|
||||||
static void prim_hasAttr(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_hasAttr(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string attr = state.forceStringNoCtx(*args[0]);
|
string attr = state.forceStringNoCtx(*args[0], pos);
|
||||||
state.forceAttrs(*args[1], pos);
|
state.forceAttrs(*args[1], pos);
|
||||||
mkBool(v, args[1]->attrs->find(state.symbols.create(attr)) != args[1]->attrs->end());
|
mkBool(v, args[1]->attrs->find(state.symbols.create(attr)) != args[1]->attrs->end());
|
||||||
}
|
}
|
||||||
|
@ -826,7 +826,7 @@ static void prim_removeAttrs(EvalState & state, const Pos & pos, Value * * args,
|
||||||
/* Get the attribute names to be removed. */
|
/* Get the attribute names to be removed. */
|
||||||
std::set<Symbol> names;
|
std::set<Symbol> names;
|
||||||
for (unsigned int i = 0; i < args[1]->list.length; ++i) {
|
for (unsigned int i = 0; i < args[1]->list.length; ++i) {
|
||||||
state.forceStringNoCtx(*args[1]->list.elems[i]);
|
state.forceStringNoCtx(*args[1]->list.elems[i], pos);
|
||||||
names.insert(state.symbols.create(args[1]->list.elems[i]->string.s));
|
names.insert(state.symbols.create(args[1]->list.elems[i]->string.s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,7 +861,7 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args,
|
||||||
Bindings::iterator j = v2.attrs->find(state.sName);
|
Bindings::iterator j = v2.attrs->find(state.sName);
|
||||||
if (j == v2.attrs->end())
|
if (j == v2.attrs->end())
|
||||||
throw TypeError(format("`name' attribute missing in a call to `listToAttrs', at %1%") % pos);
|
throw TypeError(format("`name' attribute missing in a call to `listToAttrs', at %1%") % pos);
|
||||||
string name = state.forceStringNoCtx(*j->value);
|
string name = state.forceStringNoCtx(*j->value, pos);
|
||||||
|
|
||||||
Symbol sym = state.symbols.create(name);
|
Symbol sym = state.symbols.create(name);
|
||||||
if (seen.find(sym) == seen.end()) {
|
if (seen.find(sym) == seen.end()) {
|
||||||
|
@ -1168,7 +1168,7 @@ static void prim_unsafeDiscardOutputDependency(EvalState & state, const Pos & po
|
||||||
/* Return the cryptographic hash of a string in base-16. */
|
/* Return the cryptographic hash of a string in base-16. */
|
||||||
static void prim_hashString(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_hashString(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string type = state.forceStringNoCtx(*args[0]);
|
string type = state.forceStringNoCtx(*args[0], pos);
|
||||||
HashType ht = parseHashType(type);
|
HashType ht = parseHashType(type);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw Error(format("unknown hash type `%1%', at %2%") % type % pos);
|
throw Error(format("unknown hash type `%1%', at %2%") % type % pos);
|
||||||
|
@ -1187,7 +1187,7 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args,
|
||||||
|
|
||||||
static void prim_parseDrvName(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_parseDrvName(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string name = state.forceStringNoCtx(*args[0]);
|
string name = state.forceStringNoCtx(*args[0], pos);
|
||||||
DrvName parsed(name);
|
DrvName parsed(name);
|
||||||
state.mkAttrs(v, 2);
|
state.mkAttrs(v, 2);
|
||||||
mkString(*state.allocAttr(v, state.sName), parsed.name);
|
mkString(*state.allocAttr(v, state.sName), parsed.name);
|
||||||
|
@ -1198,8 +1198,8 @@ static void prim_parseDrvName(EvalState & state, const Pos & pos, Value * * args
|
||||||
|
|
||||||
static void prim_compareVersions(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_compareVersions(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
string version1 = state.forceStringNoCtx(*args[0]);
|
string version1 = state.forceStringNoCtx(*args[0], pos);
|
||||||
string version2 = state.forceStringNoCtx(*args[1]);
|
string version2 = state.forceStringNoCtx(*args[1], pos);
|
||||||
mkInt(v, compareVersions(version1, version2));
|
mkInt(v, compareVersions(version1, version2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue