* Store Value nodes outside of attribute sets. I.e., Attr now stores
a pointer to a Value, rather than the Value directly. This improves the effectiveness of garbage collection a lot: if the Value is stored inside the set directly, then any live pointer to the Value causes all other attributes in the set to be live as well.
This commit is contained in:
parent
64c3325b0b
commit
41c45a9b31
15 changed files with 150 additions and 130 deletions
|
@ -11,7 +11,7 @@ pkginclude_HEADERS = \
|
||||||
names.hh symbol-table.hh
|
names.hh symbol-table.hh
|
||||||
|
|
||||||
libexpr_la_LIBADD = ../libutil/libutil.la ../libstore/libstore.la \
|
libexpr_la_LIBADD = ../libutil/libutil.la ../libstore/libstore.la \
|
||||||
../boost/format/libformat.la
|
../boost/format/libformat.la @boehmgc_lib@
|
||||||
|
|
||||||
BUILT_SOURCES = \
|
BUILT_SOURCES = \
|
||||||
parser-tab.hh lexer-tab.hh parser-tab.cc lexer-tab.cc
|
parser-tab.hh lexer-tab.hh parser-tab.cc lexer-tab.cc
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
// !!! Shouldn't we return a pointer to a Value?
|
||||||
void findAlongAttrPath(EvalState & state, const string & attrPath,
|
void findAlongAttrPath(EvalState & state, const string & attrPath,
|
||||||
const Bindings & autoArgs, Expr * e, Value & v)
|
Bindings & autoArgs, Expr * e, Value & v)
|
||||||
{
|
{
|
||||||
Strings tokens = tokenizeString(attrPath, ".");
|
Strings tokens = tokenizeString(attrPath, ".");
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ void findAlongAttrPath(EvalState & state, const string & attrPath,
|
||||||
Bindings::iterator a = v.attrs->find(state.symbols.create(attr));
|
Bindings::iterator a = v.attrs->find(state.symbols.create(attr));
|
||||||
if (a == v.attrs->end())
|
if (a == v.attrs->end())
|
||||||
throw Error(format("attribute `%1%' in selection path `%2%' not found") % attr % curPath);
|
throw Error(format("attribute `%1%' in selection path `%2%' not found") % attr % curPath);
|
||||||
v = a->second.value;
|
v = *a->second.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (apType == apIndex) {
|
else if (apType == apIndex) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace nix {
|
||||||
|
|
||||||
|
|
||||||
void findAlongAttrPath(EvalState & state, const string & attrPath,
|
void findAlongAttrPath(EvalState & state, const string & attrPath,
|
||||||
const Bindings & autoArgs, Expr * e, Value & v);
|
Bindings & autoArgs, Expr * e, Value & v);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,13 @@ bool parseOptionArg(const string & arg, Strings::iterator & i,
|
||||||
if (i == argsEnd) throw error;
|
if (i == argsEnd) throw error;
|
||||||
string value = *i++;
|
string value = *i++;
|
||||||
|
|
||||||
Value & v(autoArgs[state.symbols.create(name)].value);
|
Value * v = state.allocValue();
|
||||||
|
autoArgs[state.symbols.create(name)].value = v;
|
||||||
|
|
||||||
if (arg == "--arg")
|
if (arg == "--arg")
|
||||||
state.mkThunk_(v, parseExprFromString(state, value, absPath(".")));
|
state.mkThunk_(*v, parseExprFromString(state, value, absPath(".")));
|
||||||
else
|
else
|
||||||
mkString(v, value);
|
mkString(*v, value);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ std::ostream & operator << (std::ostream & str, const Value & v)
|
||||||
typedef std::map<string, Value *> Sorted;
|
typedef std::map<string, Value *> Sorted;
|
||||||
Sorted sorted;
|
Sorted sorted;
|
||||||
foreach (Bindings::iterator, i, *v.attrs)
|
foreach (Bindings::iterator, i, *v.attrs)
|
||||||
sorted[i->first] = &i->second.value;
|
sorted[i->first] = i->second.value;
|
||||||
foreach (Sorted::iterator, i, sorted)
|
foreach (Sorted::iterator, i, sorted)
|
||||||
str << i->first << " = " << *i->second << "; ";
|
str << i->first << " = " << *i->second << "; ";
|
||||||
str << "}";
|
str << "}";
|
||||||
|
@ -145,24 +145,26 @@ EvalState::~EvalState()
|
||||||
|
|
||||||
void EvalState::addConstant(const string & name, Value & v)
|
void EvalState::addConstant(const string & name, Value & v)
|
||||||
{
|
{
|
||||||
|
Value * v2 = allocValue();
|
||||||
|
*v2 = v;
|
||||||
staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
|
staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
|
||||||
baseEnv.values[baseEnvDispl++] = v;
|
baseEnv.values[baseEnvDispl++] = v;
|
||||||
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
|
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
|
||||||
(*baseEnv.values[0].attrs)[symbols.create(name2)].value = v;
|
(*baseEnv.values[0].attrs)[symbols.create(name2)].value = v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::addPrimOp(const string & name,
|
void EvalState::addPrimOp(const string & name,
|
||||||
unsigned int arity, PrimOp primOp)
|
unsigned int arity, PrimOp primOp)
|
||||||
{
|
{
|
||||||
Value v;
|
Value * v = allocValue();
|
||||||
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
|
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
|
||||||
v.type = tPrimOp;
|
v->type = tPrimOp;
|
||||||
v.primOp.arity = arity;
|
v->primOp.arity = arity;
|
||||||
v.primOp.fun = primOp;
|
v->primOp.fun = primOp;
|
||||||
v.primOp.name = GC_STRDUP(name2.c_str());
|
v->primOp.name = GC_STRDUP(name2.c_str());
|
||||||
staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
|
staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
|
||||||
baseEnv.values[baseEnvDispl++] = v;
|
baseEnv.values[baseEnvDispl++] = *v;
|
||||||
(*baseEnv.values[0].attrs)[symbols.create(name2)].value = v;
|
(*baseEnv.values[0].attrs)[symbols.create(name2)].value = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +267,7 @@ Value * EvalState::lookupVar(Env * env, const VarRef & var)
|
||||||
while (1) {
|
while (1) {
|
||||||
Bindings::iterator j = env->values[0].attrs->find(var.name);
|
Bindings::iterator j = env->values[0].attrs->find(var.name);
|
||||||
if (j != env->values[0].attrs->end())
|
if (j != env->values[0].attrs->end())
|
||||||
return &j->second.value;
|
return j->second.value;
|
||||||
if (env->prevWith == 0)
|
if (env->prevWith == 0)
|
||||||
throwEvalError("undefined variable `%1%'", var.name);
|
throwEvalError("undefined variable `%1%'", var.name);
|
||||||
for (unsigned int l = env->prevWith; l; --l, env = env->up) ;
|
for (unsigned int l = env->prevWith; l; --l, env = env->up) ;
|
||||||
|
@ -275,6 +277,13 @@ Value * EvalState::lookupVar(Env * env, const VarRef & var)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Value * EvalState::allocValue()
|
||||||
|
{
|
||||||
|
nrValues++;
|
||||||
|
return (Value *) GC_MALLOC(sizeof(Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Value * EvalState::allocValues(unsigned int count)
|
Value * EvalState::allocValues(unsigned int count)
|
||||||
{
|
{
|
||||||
nrValues += count;
|
nrValues += count;
|
||||||
|
@ -291,6 +300,14 @@ Env & EvalState::allocEnv(unsigned int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Value * EvalState::allocAttr(Value & vAttrs, const Symbol & name)
|
||||||
|
{
|
||||||
|
Attr & a = (*vAttrs.attrs)[name];
|
||||||
|
a.value = allocValue();
|
||||||
|
return a.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::mkList(Value & v, unsigned int length)
|
void EvalState::mkList(Value & v, unsigned int length)
|
||||||
{
|
{
|
||||||
v.type = tList;
|
v.type = tList;
|
||||||
|
@ -321,11 +338,8 @@ void EvalState::mkThunk_(Value & v, Expr * expr)
|
||||||
void EvalState::cloneAttrs(Value & src, Value & dst)
|
void EvalState::cloneAttrs(Value & src, Value & dst)
|
||||||
{
|
{
|
||||||
mkAttrs(dst);
|
mkAttrs(dst);
|
||||||
foreach (Bindings::iterator, i, *src.attrs) {
|
foreach (Bindings::iterator, i, *src.attrs)
|
||||||
Attr & a = (*dst.attrs)[i->first];
|
(*dst.attrs)[i->first] = i->second;
|
||||||
mkCopy(a.value, i->second.value);
|
|
||||||
a.pos = i->second.pos;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -449,8 +463,9 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
environment. */
|
environment. */
|
||||||
foreach (Attrs::iterator, i, attrs) {
|
foreach (Attrs::iterator, i, attrs) {
|
||||||
nix::Attr & a = (*v.attrs)[i->first];
|
nix::Attr & a = (*v.attrs)[i->first];
|
||||||
mkThunk(a.value, env2, i->second.first);
|
a.value = state.allocValue();
|
||||||
mkCopy(env2.values[displ++], a.value);
|
mkThunk(*a.value, env2, i->second.first);
|
||||||
|
mkCopy(env2.values[displ++], *a.value);
|
||||||
a.pos = &i->second.second;
|
a.pos = &i->second.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,7 +474,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
foreach (list<Inherited>::iterator, i, inherited) {
|
foreach (list<Inherited>::iterator, i, inherited) {
|
||||||
nix::Attr & a = (*v.attrs)[i->first.name];
|
nix::Attr & a = (*v.attrs)[i->first.name];
|
||||||
Value * v2 = state.lookupVar(&env, i->first);
|
Value * v2 = state.lookupVar(&env, i->first);
|
||||||
mkCopy(a.value, *v2);
|
a.value = v2;
|
||||||
mkCopy(env2.values[displ++], *v2);
|
mkCopy(env2.values[displ++], *v2);
|
||||||
a.pos = &i->second;
|
a.pos = &i->second;
|
||||||
}
|
}
|
||||||
|
@ -474,10 +489,12 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
Hence we need __overrides.) */
|
Hence we need __overrides.) */
|
||||||
Bindings::iterator overrides = v.attrs->find(state.sOverrides);
|
Bindings::iterator overrides = v.attrs->find(state.sOverrides);
|
||||||
if (overrides != v.attrs->end()) {
|
if (overrides != v.attrs->end()) {
|
||||||
state.forceAttrs(overrides->second.value);
|
state.forceAttrs(*overrides->second.value);
|
||||||
foreach (Bindings::iterator, i, *overrides->second.value.attrs) {
|
foreach (Bindings::iterator, i, *overrides->second.value->attrs) {
|
||||||
nix::Attr & a = (*v.attrs)[i->first];
|
nix::Attr & a = (*v.attrs)[i->first];
|
||||||
mkCopy(a.value, i->second.value);
|
if (a.value)
|
||||||
|
mkCopy(env2.values[displs[i->first]], *i->second.value);
|
||||||
|
a = i->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,13 +502,14 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
else {
|
else {
|
||||||
foreach (Attrs::iterator, i, attrs) {
|
foreach (Attrs::iterator, i, attrs) {
|
||||||
nix::Attr & a = (*v.attrs)[i->first];
|
nix::Attr & a = (*v.attrs)[i->first];
|
||||||
mkThunk(a.value, env, i->second.first);
|
a.value = state.allocValue();
|
||||||
|
mkThunk(*a.value, env, i->second.first);
|
||||||
a.pos = &i->second.second;
|
a.pos = &i->second.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (list<Inherited>::iterator, i, inherited) {
|
foreach (list<Inherited>::iterator, i, inherited) {
|
||||||
nix::Attr & a = (*v.attrs)[i->first.name];
|
nix::Attr & a = (*v.attrs)[i->first.name];
|
||||||
mkCopy(a.value, *state.lookupVar(&env, i->first));
|
a.value = state.lookupVar(&env, i->first);
|
||||||
a.pos = &i->second;
|
a.pos = &i->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,13 +566,13 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
if (i == v2.attrs->end())
|
if (i == v2.attrs->end())
|
||||||
throwEvalError("attribute `%1%' missing", name);
|
throwEvalError("attribute `%1%' missing", name);
|
||||||
try {
|
try {
|
||||||
state.forceValue(i->second.value);
|
state.forceValue(*i->second.value);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n",
|
addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n",
|
||||||
name, *i->second.pos);
|
name, *i->second.pos);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
v = i->second.value;
|
v = *i->second.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -578,9 +596,9 @@ void ExprApp::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
Value vFun;
|
Value vFun;
|
||||||
state.eval(env, e1, vFun);
|
state.eval(env, e1, vFun);
|
||||||
Value vArg;
|
Value * vArg = state.allocValue();
|
||||||
mkThunk(vArg, env, e2); // !!! should this be on the heap?
|
mkThunk(*vArg, env, e2);
|
||||||
state.callFunction(vFun, vArg, v);
|
state.callFunction(vFun, *vArg, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -656,7 +674,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
|
||||||
mkThunk(env2.values[displ++], env2, i->def);
|
mkThunk(env2.values[displ++], env2, i->def);
|
||||||
} else {
|
} else {
|
||||||
attrsUsed++;
|
attrsUsed++;
|
||||||
mkCopy(env2.values[displ++], j->second.value);
|
mkCopy(env2.values[displ++], *j->second.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,7 +695,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res)
|
void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
||||||
{
|
{
|
||||||
forceValue(fun);
|
forceValue(fun);
|
||||||
|
|
||||||
|
@ -690,7 +708,7 @@ void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res
|
||||||
mkAttrs(actualArgs);
|
mkAttrs(actualArgs);
|
||||||
|
|
||||||
foreach (Formals::Formals_::iterator, i, fun.lambda.fun->formals->formals) {
|
foreach (Formals::Formals_::iterator, i, fun.lambda.fun->formals->formals) {
|
||||||
Bindings::const_iterator j = args.find(i->name);
|
Bindings::iterator j = args.find(i->name);
|
||||||
if (j != args.end())
|
if (j != args.end())
|
||||||
(*actualArgs.attrs)[i->name] = j->second;
|
(*actualArgs.attrs)[i->name] = j->second;
|
||||||
else if (!i->def)
|
else if (!i->def)
|
||||||
|
@ -780,11 +798,8 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
state.cloneAttrs(v1, v);
|
state.cloneAttrs(v1, v);
|
||||||
|
|
||||||
foreach (Bindings::iterator, i, *v2.attrs) {
|
foreach (Bindings::iterator, i, *v2.attrs)
|
||||||
Attr & a = (*v.attrs)[i->first];
|
(*v.attrs)[i->first] = i->second;
|
||||||
mkCopy(a.value, i->second.value);
|
|
||||||
a.pos = i->second.pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.nrOpUpdateValuesCopied += v.attrs->size();
|
state.nrOpUpdateValuesCopied += v.attrs->size();
|
||||||
}
|
}
|
||||||
|
@ -866,7 +881,7 @@ void EvalState::strictForceValue(Value & v)
|
||||||
|
|
||||||
if (v.type == tAttrs) {
|
if (v.type == tAttrs) {
|
||||||
foreach (Bindings::iterator, i, *v.attrs)
|
foreach (Bindings::iterator, i, *v.attrs)
|
||||||
strictForceValue(i->second.value);
|
strictForceValue(*i->second.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (v.type == tList) {
|
else if (v.type == tList) {
|
||||||
|
@ -957,7 +972,7 @@ bool EvalState::isDerivation(Value & v)
|
||||||
{
|
{
|
||||||
if (v.type != tAttrs) return false;
|
if (v.type != tAttrs) return false;
|
||||||
Bindings::iterator i = v.attrs->find(sType);
|
Bindings::iterator i = v.attrs->find(sType);
|
||||||
return i != v.attrs->end() && forceStringNoCtx(i->second.value) == "derivation";
|
return i != v.attrs->end() && forceStringNoCtx(*i->second.value) == "derivation";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1001,7 +1016,7 @@ string EvalState::coerceToString(Value & v, PathSet & context,
|
||||||
Bindings::iterator i = v.attrs->find(sOutPath);
|
Bindings::iterator i = v.attrs->find(sOutPath);
|
||||||
if (i == v.attrs->end())
|
if (i == v.attrs->end())
|
||||||
throwTypeError("cannot coerce an attribute set (except a derivation) to a string");
|
throwTypeError("cannot coerce an attribute set (except a derivation) to a string");
|
||||||
return coerceToString(i->second.value, context, coerceMore, copyToStore);
|
return coerceToString(*i->second.value, context, coerceMore, copyToStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coerceMore) {
|
if (coerceMore) {
|
||||||
|
@ -1087,9 +1102,9 @@ bool EvalState::eqValues(Value & v1, Value & v2)
|
||||||
|
|
||||||
case tAttrs: {
|
case tAttrs: {
|
||||||
if (v1.attrs->size() != v2.attrs->size()) return false;
|
if (v1.attrs->size() != v2.attrs->size()) return false;
|
||||||
Bindings::iterator i, j;
|
Bindings::iterator i = v1.attrs->begin(), j = v2.attrs->begin();
|
||||||
for (i = v1.attrs->begin(), j = v2.attrs->begin(); i != v1.attrs->end(); ++i, ++j)
|
for ( ; i != v1.attrs->end(); ++i, ++j)
|
||||||
if (i->first != j->first || !eqValues(i->second.value, j->second.value))
|
if (i->first != j->first || !eqValues(*i->second.value, *j->second.value))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ struct Env
|
||||||
|
|
||||||
struct Attr
|
struct Attr
|
||||||
{
|
{
|
||||||
Value value;
|
Value * value;
|
||||||
Pos * pos;
|
Pos * pos;
|
||||||
Attr() : pos(&noPos) { };
|
Attr() : pos(&noPos) { };
|
||||||
};
|
};
|
||||||
|
@ -294,12 +294,15 @@ public:
|
||||||
|
|
||||||
/* Automatically call a function for which each argument has a
|
/* Automatically call a function for which each argument has a
|
||||||
default value or has a binding in the `args' map. */
|
default value or has a binding in the `args' map. */
|
||||||
void autoCallFunction(const Bindings & args, Value & fun, Value & res);
|
void autoCallFunction(Bindings & args, Value & fun, Value & res);
|
||||||
|
|
||||||
/* Allocation primitives. */
|
/* Allocation primitives. */
|
||||||
|
Value * allocValue();
|
||||||
Value * allocValues(unsigned int count);
|
Value * allocValues(unsigned int count);
|
||||||
Env & allocEnv(unsigned int size);
|
Env & allocEnv(unsigned int size);
|
||||||
|
|
||||||
|
Value * allocAttr(Value & vAttrs, const Symbol & name);
|
||||||
|
|
||||||
void mkList(Value & v, unsigned int length);
|
void mkList(Value & v, unsigned int length);
|
||||||
void mkAttrs(Value & v);
|
void mkAttrs(Value & v);
|
||||||
void mkThunk_(Value & v, Expr * expr);
|
void mkThunk_(Value & v, Expr * expr);
|
||||||
|
|
|
@ -10,7 +10,7 @@ string DrvInfo::queryDrvPath(EvalState & state) const
|
||||||
if (drvPath == "" && attrs) {
|
if (drvPath == "" && attrs) {
|
||||||
Bindings::iterator i = attrs->find(state.sDrvPath);
|
Bindings::iterator i = attrs->find(state.sDrvPath);
|
||||||
PathSet context;
|
PathSet context;
|
||||||
(string &) drvPath = i != attrs->end() ? state.coerceToPath(i->second.value, context) : "";
|
(string &) drvPath = i != attrs->end() ? state.coerceToPath(*i->second.value, context) : "";
|
||||||
}
|
}
|
||||||
return drvPath;
|
return drvPath;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ string DrvInfo::queryOutPath(EvalState & state) const
|
||||||
if (outPath == "" && attrs) {
|
if (outPath == "" && attrs) {
|
||||||
Bindings::iterator i = attrs->find(state.sOutPath);
|
Bindings::iterator i = attrs->find(state.sOutPath);
|
||||||
PathSet context;
|
PathSet context;
|
||||||
(string &) outPath = i != attrs->end() ? state.coerceToPath(i->second.value, context) : "";
|
(string &) outPath = i != attrs->end() ? state.coerceToPath(*i->second.value, context) : "";
|
||||||
}
|
}
|
||||||
return outPath;
|
return outPath;
|
||||||
}
|
}
|
||||||
|
@ -36,21 +36,21 @@ MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const
|
||||||
Bindings::iterator a = attrs->find(state.sMeta);
|
Bindings::iterator a = attrs->find(state.sMeta);
|
||||||
if (a == attrs->end()) return meta; /* fine, empty meta information */
|
if (a == attrs->end()) return meta; /* fine, empty meta information */
|
||||||
|
|
||||||
state.forceAttrs(a->second.value);
|
state.forceAttrs(*a->second.value);
|
||||||
|
|
||||||
foreach (Bindings::iterator, i, *a->second.value.attrs) {
|
foreach (Bindings::iterator, i, *a->second.value->attrs) {
|
||||||
MetaValue value;
|
MetaValue value;
|
||||||
state.forceValue(i->second.value);
|
state.forceValue(*i->second.value);
|
||||||
if (i->second.value.type == tString) {
|
if (i->second.value->type == tString) {
|
||||||
value.type = MetaValue::tpString;
|
value.type = MetaValue::tpString;
|
||||||
value.stringValue = i->second.value.string.s;
|
value.stringValue = i->second.value->string.s;
|
||||||
} else if (i->second.value.type == tInt) {
|
} else if (i->second.value->type == tInt) {
|
||||||
value.type = MetaValue::tpInt;
|
value.type = MetaValue::tpInt;
|
||||||
value.intValue = i->second.value.integer;
|
value.intValue = i->second.value->integer;
|
||||||
} else if (i->second.value.type == tList) {
|
} else if (i->second.value->type == tList) {
|
||||||
value.type = MetaValue::tpStrings;
|
value.type = MetaValue::tpStrings;
|
||||||
for (unsigned int j = 0; j < i->second.value.list.length; ++j)
|
for (unsigned int j = 0; j < i->second.value->list.length; ++j)
|
||||||
value.stringValues.push_back(state.forceStringNoCtx(*i->second.value.list.elems[j]));
|
value.stringValues.push_back(state.forceStringNoCtx(*i->second.value->list.elems[j]));
|
||||||
} else continue;
|
} else continue;
|
||||||
((MetaInfo &) meta)[i->first] = value;
|
((MetaInfo &) meta)[i->first] = value;
|
||||||
}
|
}
|
||||||
|
@ -99,13 +99,13 @@ static bool getDerivation(EvalState & state, Value & v,
|
||||||
Bindings::iterator i = v.attrs->find(state.sName);
|
Bindings::iterator i = v.attrs->find(state.sName);
|
||||||
/* !!! We really would like to have a decent back trace here. */
|
/* !!! We really would like to have a decent back trace here. */
|
||||||
if (i == v.attrs->end()) throw TypeError("derivation name missing");
|
if (i == v.attrs->end()) throw TypeError("derivation name missing");
|
||||||
drv.name = state.forceStringNoCtx(i->second.value);
|
drv.name = state.forceStringNoCtx(*i->second.value);
|
||||||
|
|
||||||
i = v.attrs->find(state.sSystem);
|
Bindings::iterator i2 = v.attrs->find(state.sSystem);
|
||||||
if (i == v.attrs->end())
|
if (i2 == v.attrs->end())
|
||||||
drv.system = "unknown";
|
drv.system = "unknown";
|
||||||
else
|
else
|
||||||
drv.system = state.forceStringNoCtx(i->second.value);
|
drv.system = state.forceStringNoCtx(*i2->second.value);
|
||||||
|
|
||||||
drv.attrs = v.attrs;
|
drv.attrs = v.attrs;
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ static string addToPath(const string & s1, const string & s2)
|
||||||
|
|
||||||
|
|
||||||
static void getDerivations(EvalState & state, Value & vIn,
|
static void getDerivations(EvalState & state, Value & vIn,
|
||||||
const string & pathPrefix, const Bindings & autoArgs,
|
const string & pathPrefix, Bindings & autoArgs,
|
||||||
DrvInfos & drvs, Done & done)
|
DrvInfos & drvs, Done & done)
|
||||||
{
|
{
|
||||||
Value v;
|
Value v;
|
||||||
|
@ -168,7 +168,7 @@ static void getDerivations(EvalState & state, Value & vIn,
|
||||||
foreach (SortedSymbols::iterator, i, attrs) {
|
foreach (SortedSymbols::iterator, i, attrs) {
|
||||||
startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % i->first);
|
startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % i->first);
|
||||||
string pathPrefix2 = addToPath(pathPrefix, i->first);
|
string pathPrefix2 = addToPath(pathPrefix, i->first);
|
||||||
Value & v2((*v.attrs)[i->second].value);
|
Value & v2(*(*v.attrs)[i->second].value);
|
||||||
if (combineChannels)
|
if (combineChannels)
|
||||||
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
|
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
|
||||||
else if (getDerivation(state, v2, pathPrefix2, drvs, done)) {
|
else if (getDerivation(state, v2, pathPrefix2, drvs, done)) {
|
||||||
|
@ -178,7 +178,7 @@ static void getDerivations(EvalState & state, Value & vIn,
|
||||||
attribute. */
|
attribute. */
|
||||||
if (v2.type == tAttrs) {
|
if (v2.type == tAttrs) {
|
||||||
Bindings::iterator j = v2.attrs->find(state.symbols.create("recurseForDerivations"));
|
Bindings::iterator j = v2.attrs->find(state.symbols.create("recurseForDerivations"));
|
||||||
if (j != v2.attrs->end() && state.forceBool(j->second.value))
|
if (j != v2.attrs->end() && state.forceBool(*j->second.value))
|
||||||
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
|
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ static void getDerivations(EvalState & state, Value & vIn,
|
||||||
|
|
||||||
|
|
||||||
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
|
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
|
||||||
const Bindings & autoArgs, DrvInfos & drvs)
|
Bindings & autoArgs, DrvInfos & drvs)
|
||||||
{
|
{
|
||||||
Done done;
|
Done done;
|
||||||
getDerivations(state, v, pathPrefix, autoArgs, drvs, done);
|
getDerivations(state, v, pathPrefix, autoArgs, drvs, done);
|
||||||
|
|
|
@ -70,7 +70,7 @@ typedef list<DrvInfo> DrvInfos;
|
||||||
bool getDerivation(EvalState & state, Value & v, DrvInfo & drv);
|
bool getDerivation(EvalState & state, Value & v, DrvInfo & drv);
|
||||||
|
|
||||||
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
|
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
|
||||||
const Bindings & autoArgs, DrvInfos & drvs);
|
Bindings & autoArgs, DrvInfos & drvs);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,10 +213,10 @@ void ExprAttrs::bindVars(const StaticEnv & env)
|
||||||
unsigned int displ = 0;
|
unsigned int displ = 0;
|
||||||
|
|
||||||
foreach (ExprAttrs::Attrs::iterator, i, attrs)
|
foreach (ExprAttrs::Attrs::iterator, i, attrs)
|
||||||
newEnv.vars[i->first] = displ++;
|
displs[i->first] = newEnv.vars[i->first] = displ++;
|
||||||
|
|
||||||
foreach (list<Inherited>::iterator, i, inherited) {
|
foreach (list<Inherited>::iterator, i, inherited) {
|
||||||
newEnv.vars[i->first.name] = displ++;
|
displs[i->first.name] = newEnv.vars[i->first.name] = displ++;
|
||||||
i->first.bind(env);
|
i->first.bind(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,7 @@ struct ExprAttrs : Expr
|
||||||
Attrs attrs;
|
Attrs attrs;
|
||||||
list<Inherited> inherited;
|
list<Inherited> inherited;
|
||||||
std::map<Symbol, Pos> attrNames; // used during parsing
|
std::map<Symbol, Pos> attrNames; // used during parsing
|
||||||
|
std::map<Symbol, unsigned int> displs;
|
||||||
ExprAttrs() : recursive(false) { };
|
ExprAttrs() : recursive(false) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
|
@ -119,24 +119,24 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
|
||||||
args[0]->attrs->find(state.symbols.create("startSet"));
|
args[0]->attrs->find(state.symbols.create("startSet"));
|
||||||
if (startSet == args[0]->attrs->end())
|
if (startSet == args[0]->attrs->end())
|
||||||
throw EvalError("attribute `startSet' required");
|
throw EvalError("attribute `startSet' required");
|
||||||
state.forceList(startSet->second.value);
|
state.forceList(*startSet->second.value);
|
||||||
|
|
||||||
list<Value *> workSet;
|
list<Value *> workSet;
|
||||||
for (unsigned int n = 0; n < startSet->second.value.list.length; ++n)
|
for (unsigned int n = 0; n < startSet->second.value->list.length; ++n)
|
||||||
workSet.push_back(startSet->second.value.list.elems[n]);
|
workSet.push_back(startSet->second.value->list.elems[n]);
|
||||||
|
|
||||||
/* Get the operator. */
|
/* Get the operator. */
|
||||||
Bindings::iterator op =
|
Bindings::iterator op =
|
||||||
args[0]->attrs->find(state.symbols.create("operator"));
|
args[0]->attrs->find(state.symbols.create("operator"));
|
||||||
if (op == args[0]->attrs->end())
|
if (op == args[0]->attrs->end())
|
||||||
throw EvalError("attribute `operator' required");
|
throw EvalError("attribute `operator' required");
|
||||||
state.forceValue(op->second.value);
|
state.forceValue(*op->second.value);
|
||||||
|
|
||||||
/* Construct the closure by applying the operator to element of
|
/* Construct the closure by applying the operator to element of
|
||||||
`workSet', adding the result to `workSet', continuing until
|
`workSet', adding the result to `workSet', continuing until
|
||||||
no new elements are found. */
|
no new elements are found. */
|
||||||
list<Value> res;
|
list<Value> res;
|
||||||
set<Value, CompareValues> doneKeys;
|
set<Value, CompareValues> doneKeys; // !!! use Value *?
|
||||||
while (!workSet.empty()) {
|
while (!workSet.empty()) {
|
||||||
Value * e = *(workSet.begin());
|
Value * e = *(workSet.begin());
|
||||||
workSet.pop_front();
|
workSet.pop_front();
|
||||||
|
@ -147,15 +147,15 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
|
||||||
e->attrs->find(state.symbols.create("key"));
|
e->attrs->find(state.symbols.create("key"));
|
||||||
if (key == e->attrs->end())
|
if (key == e->attrs->end())
|
||||||
throw EvalError("attribute `key' required");
|
throw EvalError("attribute `key' required");
|
||||||
state.forceValue(key->second.value);
|
state.forceValue(*key->second.value);
|
||||||
|
|
||||||
if (doneKeys.find(key->second.value) != doneKeys.end()) continue;
|
if (doneKeys.find(*key->second.value) != doneKeys.end()) continue;
|
||||||
doneKeys.insert(key->second.value);
|
doneKeys.insert(*key->second.value);
|
||||||
res.push_back(*e);
|
res.push_back(*e);
|
||||||
|
|
||||||
/* Call the `operator' function with `e' as argument. */
|
/* Call the `operator' function with `e' as argument. */
|
||||||
Value call;
|
Value call;
|
||||||
mkApp(call, op->second.value, *e);
|
mkApp(call, *op->second.value, *e);
|
||||||
state.forceList(call);
|
state.forceList(call);
|
||||||
|
|
||||||
/* Add the values returned by the operator to the work set. */
|
/* Add the values returned by the operator to the work set. */
|
||||||
|
@ -213,11 +213,13 @@ static void prim_tryEval(EvalState & state, Value * * args, Value & v)
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v);
|
||||||
try {
|
try {
|
||||||
state.forceValue(*args[0]);
|
state.forceValue(*args[0]);
|
||||||
(*v.attrs)[state.symbols.create("value")].value = *args[0];
|
printMsg(lvlError, format("%1%") % *args[0]);
|
||||||
mkBool((*v.attrs)[state.symbols.create("success")].value, true);
|
(*v.attrs)[state.symbols.create("value")].value = args[0];
|
||||||
|
mkBool(*state.allocAttr(v, state.symbols.create("success")), true);
|
||||||
|
printMsg(lvlError, format("%1%") % v);
|
||||||
} catch (AssertionError & e) {
|
} catch (AssertionError & e) {
|
||||||
mkBool((*v.attrs)[state.symbols.create("value")].value, false);
|
mkBool(*state.allocAttr(v, state.symbols.create("value")), false);
|
||||||
mkBool((*v.attrs)[state.symbols.create("success")].value, false);
|
mkBool(*state.allocAttr(v, state.symbols.create("success")), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +328,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
string drvName;
|
string drvName;
|
||||||
Pos & posDrvName(*attr->second.pos);
|
Pos & posDrvName(*attr->second.pos);
|
||||||
try {
|
try {
|
||||||
drvName = state.forceStringNoCtx(attr->second.value);
|
drvName = state.forceStringNoCtx(*attr->second.value);
|
||||||
} 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;
|
||||||
|
@ -349,9 +351,9 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
/* The `args' attribute is special: it supplies the
|
/* The `args' attribute is special: it supplies the
|
||||||
command-line arguments to the builder. */
|
command-line arguments to the builder. */
|
||||||
if (key == "args") {
|
if (key == "args") {
|
||||||
state.forceList(i->second.value);
|
state.forceList(*i->second.value);
|
||||||
for (unsigned int n = 0; n < i->second.value.list.length; ++n) {
|
for (unsigned int n = 0; n < i->second.value->list.length; ++n) {
|
||||||
string s = state.coerceToString(*i->second.value.list.elems[n], context, true);
|
string s = state.coerceToString(*i->second.value->list.elems[n], context, true);
|
||||||
drv.args.push_back(s);
|
drv.args.push_back(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,7 +361,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
/* All other attributes are passed to the builder through
|
/* All other attributes are passed to the builder through
|
||||||
the environment. */
|
the environment. */
|
||||||
else {
|
else {
|
||||||
string s = state.coerceToString(i->second.value, context, true);
|
string s = state.coerceToString(*i->second.value, context, true);
|
||||||
drv.env[key] = s;
|
drv.env[key] = s;
|
||||||
if (key == "builder") drv.builder = s;
|
if (key == "builder") drv.builder = s;
|
||||||
else if (i->first == state.sSystem) drv.platform = s;
|
else if (i->first == state.sSystem) drv.platform = s;
|
||||||
|
@ -488,8 +490,8 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
|
||||||
|
|
||||||
/* !!! assumes a single output */
|
/* !!! assumes a single output */
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v);
|
||||||
mkString((*v.attrs)[state.sOutPath].value, outPath, singleton<PathSet>(drvPath));
|
mkString(*state.allocAttr(v, state.sOutPath), outPath, singleton<PathSet>(drvPath));
|
||||||
mkString((*v.attrs)[state.sDrvPath].value, drvPath, singleton<PathSet>("=" + drvPath));
|
mkString(*state.allocAttr(v, state.sDrvPath), drvPath, singleton<PathSet>("=" + drvPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -713,8 +715,8 @@ static void prim_getAttr(EvalState & state, Value * * args, Value & v)
|
||||||
if (i == args[1]->attrs->end())
|
if (i == args[1]->attrs->end())
|
||||||
throw EvalError(format("attribute `%1%' missing") % attr);
|
throw EvalError(format("attribute `%1%' missing") % attr);
|
||||||
// !!! add to stack trace?
|
// !!! add to stack trace?
|
||||||
state.forceValue(i->second.value);
|
state.forceValue(*i->second.value);
|
||||||
v = i->second.value;
|
v = *i->second.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -766,15 +768,13 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
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("`name' attribute missing in a call to `listToAttrs'");
|
throw TypeError("`name' attribute missing in a call to `listToAttrs'");
|
||||||
string name = state.forceStringNoCtx(j->second.value);
|
string name = state.forceStringNoCtx(*j->second.value);
|
||||||
|
|
||||||
j = v2.attrs->find(state.symbols.create("value"));
|
Bindings::iterator j2 = v2.attrs->find(state.symbols.create("value"));
|
||||||
if (j == v2.attrs->end())
|
if (j2 == v2.attrs->end())
|
||||||
throw TypeError("`value' attribute missing in a call to `listToAttrs'");
|
throw TypeError("`value' attribute missing in a call to `listToAttrs'");
|
||||||
|
|
||||||
Attr & a = (*v.attrs)[state.symbols.create(name)];
|
(*v.attrs)[state.symbols.create(name)] = j2->second;
|
||||||
mkCopy(a.value, j->second.value);
|
|
||||||
a.pos = j->second.pos;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,11 +791,8 @@ static void prim_intersectAttrs(EvalState & state, Value * * args, Value & v)
|
||||||
|
|
||||||
foreach (Bindings::iterator, i, *args[0]->attrs) {
|
foreach (Bindings::iterator, i, *args[0]->attrs) {
|
||||||
Bindings::iterator j = args[1]->attrs->find(i->first);
|
Bindings::iterator j = args[1]->attrs->find(i->first);
|
||||||
if (j != args[1]->attrs->end()) {
|
if (j != args[1]->attrs->end())
|
||||||
Attr & a = (*v.attrs)[j->first];
|
(*v.attrs)[j->first] = j->second;
|
||||||
mkCopy(a.value, j->second.value);
|
|
||||||
a.pos = j->second.pos;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,7 +821,8 @@ static void prim_functionArgs(EvalState & state, Value * * args, Value & v)
|
||||||
if (!args[0]->lambda.fun->matchAttrs) return;
|
if (!args[0]->lambda.fun->matchAttrs) return;
|
||||||
|
|
||||||
foreach (Formals::Formals_::iterator, i, args[0]->lambda.fun->formals->formals)
|
foreach (Formals::Formals_::iterator, i, args[0]->lambda.fun->formals->formals)
|
||||||
mkBool((*v.attrs)[i->name].value, i->def);
|
// !!! should optimise booleans (allocate only once)
|
||||||
|
mkBool(*state.allocAttr(v, i->name), i->def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1007,8 +1005,8 @@ static void prim_parseDrvName(EvalState & state, Value * * args, Value & v)
|
||||||
string name = state.forceStringNoCtx(*args[0]);
|
string name = state.forceStringNoCtx(*args[0]);
|
||||||
DrvName parsed(name);
|
DrvName parsed(name);
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v);
|
||||||
mkString((*v.attrs)[state.sName].value, parsed.name);
|
mkString(*state.allocAttr(v, state.sName), parsed.name);
|
||||||
mkString((*v.attrs)[state.symbols.create("version")].value, parsed.version);
|
mkString(*state.allocAttr(v, state.symbols.create("version")), parsed.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ static void showAttrs(EvalState & state, bool strict, bool location,
|
||||||
|
|
||||||
XMLOpenElement _(doc, "attr", xmlAttrs);
|
XMLOpenElement _(doc, "attr", xmlAttrs);
|
||||||
printValueAsXML(state, strict, location,
|
printValueAsXML(state, strict, location,
|
||||||
a.value, doc, context, drvsSeen);
|
*a.value, doc, context, drvsSeen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,16 +90,16 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
|
||||||
Path drvPath;
|
Path drvPath;
|
||||||
a = v.attrs->find(state.sDrvPath);
|
a = v.attrs->find(state.sDrvPath);
|
||||||
if (a != v.attrs->end()) {
|
if (a != v.attrs->end()) {
|
||||||
if (strict) state.forceValue(a->second.value);
|
if (strict) state.forceValue(*a->second.value);
|
||||||
if (a->second.value.type == tString)
|
if (a->second.value->type == tString)
|
||||||
xmlAttrs["drvPath"] = drvPath = a->second.value.string.s;
|
xmlAttrs["drvPath"] = drvPath = a->second.value->string.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
a = v.attrs->find(state.sOutPath);
|
a = v.attrs->find(state.sOutPath);
|
||||||
if (a != v.attrs->end()) {
|
if (a != v.attrs->end()) {
|
||||||
if (strict) state.forceValue(a->second.value);
|
if (strict) state.forceValue(*a->second.value);
|
||||||
if (a->second.value.type == tString)
|
if (a->second.value->type == tString)
|
||||||
xmlAttrs["outPath"] = a->second.value.string.s;
|
xmlAttrs["outPath"] = a->second.value->string.s;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLOpenElement _(doc, "derivation", xmlAttrs);
|
XMLOpenElement _(doc, "derivation", xmlAttrs);
|
||||||
|
|
|
@ -161,7 +161,7 @@ static Expr * loadSourceExpr(EvalState & state, const Path & path)
|
||||||
|
|
||||||
|
|
||||||
static void loadDerivations(EvalState & state, Path nixExprPath,
|
static void loadDerivations(EvalState & state, Path nixExprPath,
|
||||||
string systemFilter, const Bindings & autoArgs,
|
string systemFilter, Bindings & autoArgs,
|
||||||
const string & pathPrefix, DrvInfos & elems)
|
const string & pathPrefix, DrvInfos & elems)
|
||||||
{
|
{
|
||||||
Value v;
|
Value v;
|
||||||
|
@ -321,7 +321,7 @@ static bool isPath(const string & s)
|
||||||
|
|
||||||
|
|
||||||
static void queryInstSources(EvalState & state,
|
static void queryInstSources(EvalState & state,
|
||||||
const InstallSourceInfo & instSource, const Strings & args,
|
InstallSourceInfo & instSource, const Strings & args,
|
||||||
DrvInfos & elems, bool newestOnly)
|
DrvInfos & elems, bool newestOnly)
|
||||||
{
|
{
|
||||||
InstallSourceType type = instSource.type;
|
InstallSourceType type = instSource.type;
|
||||||
|
|
|
@ -25,7 +25,8 @@ DrvInfos queryInstalled(EvalState & state, const Path & userEnv)
|
||||||
if (pathExists(manifestFile)) {
|
if (pathExists(manifestFile)) {
|
||||||
Value v;
|
Value v;
|
||||||
state.eval(parseExprFromFile(state, manifestFile), v);
|
state.eval(parseExprFromFile(state, manifestFile), v);
|
||||||
getDerivations(state, v, "", Bindings(), elems);
|
Bindings bindings;
|
||||||
|
getDerivations(state, v, "", bindings, elems);
|
||||||
} else if (pathExists(oldManifestFile))
|
} else if (pathExists(oldManifestFile))
|
||||||
readLegacyManifest(oldManifestFile, elems);
|
readLegacyManifest(oldManifestFile, elems);
|
||||||
|
|
||||||
|
@ -62,19 +63,19 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||||
manifest.list.elems[n++] = &v;
|
manifest.list.elems[n++] = &v;
|
||||||
state.mkAttrs(v);
|
state.mkAttrs(v);
|
||||||
|
|
||||||
mkString((*v.attrs)[state.sType].value, "derivation");
|
mkString(*state.allocAttr(v, state.sType), "derivation");
|
||||||
mkString((*v.attrs)[state.sName].value, i->name);
|
mkString(*state.allocAttr(v, state.sName), i->name);
|
||||||
mkString((*v.attrs)[state.sSystem].value, i->system);
|
mkString(*state.allocAttr(v, state.sSystem), i->system);
|
||||||
mkString((*v.attrs)[state.sOutPath].value, i->queryOutPath(state));
|
mkString(*state.allocAttr(v, state.sOutPath), i->queryOutPath(state));
|
||||||
if (drvPath != "")
|
if (drvPath != "")
|
||||||
mkString((*v.attrs)[state.sDrvPath].value, i->queryDrvPath(state));
|
mkString(*state.allocAttr(v, state.sDrvPath), i->queryDrvPath(state));
|
||||||
|
|
||||||
state.mkAttrs((*v.attrs)[state.sMeta].value);
|
state.mkAttrs(*state.allocAttr(v, state.sMeta));
|
||||||
|
|
||||||
MetaInfo meta = i->queryMetaInfo(state);
|
MetaInfo meta = i->queryMetaInfo(state);
|
||||||
|
|
||||||
foreach (MetaInfo::const_iterator, j, meta) {
|
foreach (MetaInfo::const_iterator, j, meta) {
|
||||||
Value & v2((*(*v.attrs)[state.sMeta].value.attrs)[state.symbols.create(j->first)].value);
|
Value & v2(*state.allocAttr(*(*v.attrs)[state.sMeta].value, state.symbols.create(j->first)));
|
||||||
switch (j->second.type) {
|
switch (j->second.type) {
|
||||||
case MetaValue::tpInt: mkInt(v2, j->second.intValue); break;
|
case MetaValue::tpInt: mkInt(v2, j->second.intValue); break;
|
||||||
case MetaValue::tpString: mkString(v2, j->second.stringValue); break;
|
case MetaValue::tpString: mkString(v2, j->second.stringValue); break;
|
||||||
|
@ -114,10 +115,10 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||||
builder with the manifest as argument. */
|
builder with the manifest as argument. */
|
||||||
Value args, topLevel;
|
Value args, topLevel;
|
||||||
state.mkAttrs(args);
|
state.mkAttrs(args);
|
||||||
mkString((*args.attrs)[state.sSystem].value, thisSystem);
|
mkString(*state.allocAttr(args, state.sSystem), thisSystem);
|
||||||
mkString((*args.attrs)[state.symbols.create("manifest")].value,
|
mkString(*state.allocAttr(args, state.symbols.create("manifest")),
|
||||||
manifestFile, singleton<PathSet>(manifestFile));
|
manifestFile, singleton<PathSet>(manifestFile));
|
||||||
(*args.attrs)[state.symbols.create("derivations")].value = manifest;
|
(*args.attrs)[state.symbols.create("derivations")].value = &manifest;
|
||||||
mkApp(topLevel, envBuilder, args);
|
mkApp(topLevel, envBuilder, args);
|
||||||
|
|
||||||
/* Evaluate it. */
|
/* Evaluate it. */
|
||||||
|
|
|
@ -38,7 +38,7 @@ static bool indirectRoot = false;
|
||||||
|
|
||||||
|
|
||||||
void processExpr(EvalState & state, const Strings & attrPaths,
|
void processExpr(EvalState & state, const Strings & attrPaths,
|
||||||
bool parseOnly, bool strict, const Bindings & autoArgs,
|
bool parseOnly, bool strict, Bindings & autoArgs,
|
||||||
bool evalOnly, bool xmlOutput, bool location, Expr * e)
|
bool evalOnly, bool xmlOutput, bool location, Expr * e)
|
||||||
{
|
{
|
||||||
if (parseOnly)
|
if (parseOnly)
|
||||||
|
|
Loading…
Reference in a new issue