aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc65
1 files changed, 37 insertions, 28 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 01cbf7a7c..20b839508 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -119,18 +119,18 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
args[0]->attrs->find(state.symbols.create("startSet"));
if (startSet == args[0]->attrs->end())
throw EvalError("attribute `startSet' required");
- state.forceList(*startSet->second.value);
+ state.forceList(*startSet->value);
list<Value *> workSet;
- for (unsigned int n = 0; n < startSet->second.value->list.length; ++n)
- workSet.push_back(startSet->second.value->list.elems[n]);
+ for (unsigned int n = 0; n < startSet->value->list.length; ++n)
+ workSet.push_back(startSet->value->list.elems[n]);
/* Get the operator. */
Bindings::iterator op =
args[0]->attrs->find(state.symbols.create("operator"));
if (op == args[0]->attrs->end())
throw EvalError("attribute `operator' required");
- state.forceValue(*op->second.value);
+ state.forceValue(*op->value);
/* Construct the closure by applying the operator to element of
`workSet', adding the result to `workSet', continuing until
@@ -147,15 +147,15 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v)
e->attrs->find(state.symbols.create("key"));
if (key == e->attrs->end())
throw EvalError("attribute `key' required");
- state.forceValue(*key->second.value);
+ state.forceValue(*key->value);
- if (doneKeys.find(*key->second.value) != doneKeys.end()) continue;
- doneKeys.insert(*key->second.value);
+ if (doneKeys.find(*key->value) != doneKeys.end()) continue;
+ doneKeys.insert(*key->value);
res.push_back(*e);
/* Call the `operator' function with `e' as argument. */
Value call;
- mkApp(call, *op->second.value, *e);
+ mkApp(call, *op->value, *e);
state.forceList(call);
/* Add the values returned by the operator to the work set. */
@@ -322,9 +322,9 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
if (attr == args[0]->attrs->end())
throw EvalError("required attribute `name' missing");
string drvName;
- Pos & posDrvName(*attr->second.pos);
+ Pos & posDrvName(*attr->pos);
try {
- drvName = state.forceStringNoCtx(*attr->second.value);
+ drvName = state.forceStringNoCtx(*attr->value);
} catch (Error & e) {
e.addPrefix(format("while evaluating the derivation attribute `name' at %1%:\n") % posDrvName);
throw;
@@ -339,7 +339,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
bool outputHashRecursive = false;
foreach (Bindings::iterator, i, *args[0]->attrs) {
- string key = i->first;
+ string key = i->name;
startNest(nest, lvlVomit, format("processing attribute `%1%'") % key);
try {
@@ -347,9 +347,9 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
/* The `args' attribute is special: it supplies the
command-line arguments to the builder. */
if (key == "args") {
- state.forceList(*i->second.value);
- for (unsigned int n = 0; n < i->second.value->list.length; ++n) {
- string s = state.coerceToString(*i->second.value->list.elems[n], context, true);
+ state.forceList(*i->value);
+ for (unsigned int n = 0; n < i->value->list.length; ++n) {
+ string s = state.coerceToString(*i->value->list.elems[n], context, true);
drv.args.push_back(s);
}
}
@@ -357,11 +357,11 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
/* All other attributes are passed to the builder through
the environment. */
else {
- string s = state.coerceToString(*i->second.value, context, true);
+ string s = state.coerceToString(*i->value, context, true);
drv.env[key] = s;
if (key == "builder") drv.builder = s;
- else if (i->first == state.sSystem) drv.platform = s;
- else if (i->first == state.sName) drvName = s;
+ else if (i->name == state.sSystem) drv.platform = s;
+ else if (i->name == state.sName) drvName = s;
else if (key == "outputHash") outputHash = s;
else if (key == "outputHashAlgo") outputHashAlgo = s;
else if (key == "outputHashMode") {
@@ -373,7 +373,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
} catch (Error & e) {
e.addPrefix(format("while evaluating the derivation attribute `%1%' at %2%:\n")
- % key % *i->second.pos);
+ % key % *i->pos);
e.addPrefix(format("while instantiating the derivation named `%1%' at %2%:\n")
% drvName % posDrvName);
throw;
@@ -690,7 +690,7 @@ static void prim_attrNames(EvalState & state, Value * * args, Value & v)
StringSet names;
foreach (Bindings::iterator, i, *args[0]->attrs)
- names.insert(i->first);
+ names.insert(i->name);
unsigned int n = 0;
foreach (StringSet::iterator, i, names)
@@ -708,8 +708,8 @@ static void prim_getAttr(EvalState & state, Value * * args, Value & v)
if (i == args[1]->attrs->end())
throw EvalError(format("attribute `%1%' missing") % attr);
// !!! add to stack trace?
- state.forceValue(*i->second.value);
- v = *i->second.value;
+ state.forceValue(*i->value);
+ v = *i->value;
}
@@ -735,11 +735,18 @@ static void prim_removeAttrs(EvalState & state, Value * * args, Value & v)
state.forceAttrs(*args[0]);
state.forceList(*args[1]);
- state.cloneAttrs(*args[0], v);
-
+ /* Get the attribute names to be removed. */
+ std::set<Symbol> names;
for (unsigned int i = 0; i < args[1]->list.length; ++i) {
state.forceStringNoCtx(*args[1]->list.elems[i]);
- v.attrs->erase(state.symbols.create(args[1]->list.elems[i]->string.s));
+ names.insert(state.symbols.create(args[1]->list.elems[i]->string.s));
+ }
+
+ /* Copy all attributes not in that set. */
+ state.mkAttrs(v);
+ foreach (Bindings::iterator, i, *args[0]->attrs) {
+ if (names.find(i->name) == names.end())
+ v.attrs->push_back(*i);
}
}
@@ -761,13 +768,15 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v)
Bindings::iterator j = v2.attrs->find(state.sName);
if (j == v2.attrs->end())
throw TypeError("`name' attribute missing in a call to `listToAttrs'");
- string name = state.forceStringNoCtx(*j->second.value);
+ string name = state.forceStringNoCtx(*j->value);
Bindings::iterator j2 = v2.attrs->find(state.symbols.create("value"));
if (j2 == v2.attrs->end())
throw TypeError("`value' attribute missing in a call to `listToAttrs'");
- (*v.attrs)[state.symbols.create(name)] = j2->second;
+ Attr & a = (*v.attrs)[state.symbols.create(name)];
+ a.value = j2->value;
+ a.pos = j2->pos;
}
}
@@ -783,9 +792,9 @@ static void prim_intersectAttrs(EvalState & state, Value * * args, Value & v)
state.mkAttrs(v);
foreach (Bindings::iterator, i, *args[0]->attrs) {
- Bindings::iterator j = args[1]->attrs->find(i->first);
+ Bindings::iterator j = args[1]->attrs->find(i->name);
if (j != args[1]->attrs->end())
- (*v.attrs)[j->first] = j->second;
+ v.attrs->push_back(*j);
}
}