aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval.cc8
-rw-r--r--src/libexpr/get-drvs.cc84
-rw-r--r--src/nix-env/main.cc76
3 files changed, 98 insertions, 70 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 045e5f632..eac13c3fd 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -383,7 +383,13 @@ Expr evalExpr(EvalState & state, Expr e)
/* Otherwise, evaluate and memoize. */
state.normalForms.set(e, state.blackHole);
- nf = evalExpr2(state, e);
+ try {
+ nf = evalExpr2(state, e);
+ } catch (Error & err) {
+ debug("removing black hole");
+ state.normalForms.remove(e);
+ throw;
+ }
state.normalForms.set(e, nf);
return nf;
}
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index fbcbb9014..d3ec6bf6c 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -5,40 +5,51 @@
typedef set<Expr> Exprs;
+/* Evaluate expression `e'. If it evaluates to an attribute set of
+ type `derivation', then put information about it in `drvs' (unless
+ it's already in `doneExprs'). The result boolean indicates whether
+ it makes sense for the caller to recursively search for derivations
+ in `e'. */
static bool getDerivation(EvalState & state, Expr e,
DrvInfos & drvs, Exprs & doneExprs)
{
- ATermList es;
- e = evalExpr(state, e);
- if (!matchAttrs(e, es)) return false;
-
- ATermMap attrs;
- queryAllAttrs(e, attrs, false);
+ try {
+
+ ATermList es;
+ e = evalExpr(state, e);
+ if (!matchAttrs(e, es)) return true;
+
+ ATermMap attrs;
+ queryAllAttrs(e, attrs, false);
- Expr a = attrs.get("type");
- if (!a || evalString(state, a) != "derivation") return false;
+ Expr a = attrs.get("type");
+ if (!a || evalString(state, a) != "derivation") return true;
- /* Remove spurious duplicates (e.g., an attribute set like `rec {
- x = derivation {...}; y = x;}'. */
- if (doneExprs.find(e) != doneExprs.end()) return true;
- doneExprs.insert(e);
+ /* Remove spurious duplicates (e.g., an attribute set like
+ `rec { x = derivation {...}; y = x;}'. */
+ if (doneExprs.find(e) != doneExprs.end()) return false;
+ doneExprs.insert(e);
- DrvInfo drv;
+ DrvInfo drv;
- a = attrs.get("name");
- if (!a) throw badTerm("derivation name missing", e);
- drv.name = evalString(state, a);
+ a = attrs.get("name");
+ if (!a) throw badTerm("derivation name missing", e);
+ drv.name = evalString(state, a);
- a = attrs.get("system");
- if (!a)
- drv.system = "unknown";
- else
- drv.system = evalString(state, a);
+ a = attrs.get("system");
+ if (!a)
+ drv.system = "unknown";
+ else
+ drv.system = evalString(state, a);
- drv.attrs = attrs;
+ drv.attrs = attrs;
- drvs.push_back(drv);
- return true;
+ drvs.push_back(drv);
+ return false;
+
+ } catch (AssertionError & e) {
+ return false;
+ }
}
@@ -46,9 +57,10 @@ bool getDerivation(EvalState & state, Expr e, DrvInfo & drv)
{
Exprs doneExprs;
DrvInfos drvs;
- bool result = getDerivation(state, e, drvs, doneExprs);
- if (result) drv = drvs.front();
- return result;
+ getDerivation(state, e, drvs, doneExprs);
+ if (drvs.size() != 1) return false;
+ drv = drvs.front();
+ return true;
}
@@ -101,26 +113,28 @@ static void getDerivations(EvalState & state, Expr e,
ATermList es;
DrvInfo drv;
- e = evalExpr(state, e);
-
- if (getDerivation(state, e, drvs, doneExprs)) {
+ if (!getDerivation(state, e, drvs, doneExprs)) {
if (apType != apNone) throw attrError;
return;
}
+ e = evalExpr(state, e);
+
if (matchAttrs(e, es)) {
if (apType != apNone && apType != apAttr) throw attrError;
ATermMap drvMap;
queryAllAttrs(e, drvMap);
if (apType == apNone) {
for (ATermIterator i(drvMap.keys()); i; ++i) {
- debug(format("evaluating attribute `%1%'") % aterm2String(*i));
+ startNest(nest, lvlDebug,
+ format("evaluating attribute `%1%'") % aterm2String(*i));
getDerivation(state, drvMap.get(*i), drvs, doneExprs);
}
} else {
Expr e2 = drvMap.get(attr);
if (!e2) throw Error(format("attribute `%1%' in selection path not found") % attr);
- debug(format("evaluating attribute `%1%'") % attr);
+ startNest(nest, lvlDebug,
+ format("evaluating attribute `%1%'") % attr);
getDerivation(state, e2, drvs, doneExprs);
if (!attrPath.empty())
getDerivations(state, e2, drvs, doneExprs, attrPathRest);
@@ -132,14 +146,16 @@ static void getDerivations(EvalState & state, Expr e,
if (apType != apNone && apType != apIndex) throw attrError;
if (apType == apNone) {
for (ATermIterator i(es); i; ++i) {
- debug(format("evaluating list element"));
+ startNest(nest, lvlDebug,
+ format("evaluating list element"));
if (!getDerivation(state, *i, drvs, doneExprs))
getDerivations(state, *i, drvs, doneExprs, attrPathRest);
}
} else {
Expr e2 = ATelementAt(es, attrIndex);
if (!e2) throw Error(format("list index %1% in selection path not found") % attrIndex);
- debug(format("evaluating list element"));
+ startNest(nest, lvlDebug,
+ format("evaluating list element"));
if (!getDerivation(state, e2, drvs, doneExprs))
getDerivations(state, e2, drvs, doneExprs, attrPathRest);
}
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index 8648e4f0f..1266c5011 100644
--- a/src/nix-env/main.cc
+++ b/src/nix-env/main.cc
@@ -762,47 +762,53 @@ static void opQuery(Globals & globals,
for (vector<DrvInfo>::iterator i = elems2.begin();
i != elems2.end(); ++i)
{
- Strings columns;
+ try {
+
+ Strings columns;
- if (printStatus) {
- Substitutes subs = querySubstitutes(noTxn, i->queryOutPath(globals.state));
- columns.push_back(
- (string) (installed.find(i->queryOutPath(globals.state))
- != installed.end() ? "I" : "-")
- + (isValidPath(i->queryOutPath(globals.state)) ? "P" : "-")
- + (subs.size() > 0 ? "S" : "-"));
- }
+ if (printStatus) {
+ Substitutes subs = querySubstitutes(noTxn, i->queryOutPath(globals.state));
+ columns.push_back(
+ (string) (installed.find(i->queryOutPath(globals.state))
+ != installed.end() ? "I" : "-")
+ + (isValidPath(i->queryOutPath(globals.state)) ? "P" : "-")
+ + (subs.size() > 0 ? "S" : "-"));
+ }
- if (printName) columns.push_back(i->name);
-
- if (compareVersions) {
- /* Compare this element against the versions of the same
- named packages in either the set of available elements,
- or the set of installed elements. !!! This is O(N *
- M), should be O(N * lg M). */
- string version;
- VersionDiff diff = compareVersionAgainstSet(*i, otherElems, version);
- char ch;
- switch (diff) {
- case cvLess: ch = '>'; break;
- case cvEqual: ch = '='; break;
- case cvGreater: ch = '<'; break;
- case cvUnavail: ch = '-'; break;
- default: abort();
+ if (printName) columns.push_back(i->name);
+
+ if (compareVersions) {
+ /* Compare this element against the versions of the
+ same named packages in either the set of available
+ elements, or the set of installed elements. !!!
+ This is O(N * M), should be O(N * lg M). */
+ string version;
+ VersionDiff diff = compareVersionAgainstSet(*i, otherElems, version);
+ char ch;
+ switch (diff) {
+ case cvLess: ch = '>'; break;
+ case cvEqual: ch = '='; break;
+ case cvGreater: ch = '<'; break;
+ case cvUnavail: ch = '-'; break;
+ default: abort();
+ }
+ string column = (string) "" + ch + " " + version;
+ if (diff == cvGreater) column = colorString(column);
+ columns.push_back(column);
}
- string column = (string) "" + ch + " " + version;
- if (diff == cvGreater) column = colorString(column);
- columns.push_back(column);
- }
- if (printSystem) columns.push_back(i->system);
+ if (printSystem) columns.push_back(i->system);
- if (printDrvPath) columns.push_back(
- i->queryDrvPath(globals.state) == ""
- ? "-" : i->queryDrvPath(globals.state));
+ if (printDrvPath) columns.push_back(
+ i->queryDrvPath(globals.state) == ""
+ ? "-" : i->queryDrvPath(globals.state));
- if (printOutPath) columns.push_back(i->queryOutPath(globals.state));
- table.push_back(columns);
+ if (printOutPath) columns.push_back(i->queryOutPath(globals.state));
+
+ table.push_back(columns);
+ }
+ catch (AssertionError & e) {
+ }
}
printTable(table);