diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-07-26T15·05+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-07-26T15·05+0000 |
commit | ca2238cf818e27ebb663c83a9fe9ae7f58eb830f (patch) | |
tree | 7d8b058e7139c69666ee045f30070fc2500fafe5 /src/libexpr/attr-path.cc | |
parent | 2317d8f6712b2d4e249b8b1206f9e0a9c4269fc0 (diff) |
* Refactoring: get the selection path stuff out of getDerivations()
and put it into a separate function findAlongAttrPath().
Diffstat (limited to 'src/libexpr/attr-path.cc')
-rw-r--r-- | src/libexpr/attr-path.cc | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc new file mode 100644 index 000000000000..274f49ceab09 --- /dev/null +++ b/src/libexpr/attr-path.cc @@ -0,0 +1,74 @@ +#include "attr-path.hh" +#include "nixexpr-ast.hh" + + +bool isAttrs(EvalState & state, Expr e, ATermMap & attrs) +{ + e = evalExpr(state, e); + ATermList dummy; + if (!matchAttrs(e, dummy)) return false; + queryAllAttrs(e, attrs, false); + return true; +} + + +Expr findAlongAttrPath(EvalState & state, const string & attrPath, Expr e) +{ + Strings tokens = tokenizeString(attrPath, "."); + + Error attrError = + Error(format("attribute selection path `%1%' does not match expression") % attrPath); + + string curPath; + + for (Strings::iterator i = tokens.begin(); i != tokens.end(); ++i) { + + if (!curPath.empty()) curPath += "."; + curPath += *i; + + /* Is *i an index (integer) or a normal attribute name? */ + enum { apAttr, apIndex } apType = apAttr; + string attr = *i; + int attrIndex = -1; + if (string2Int(attr, attrIndex)) apType = apIndex; + + /* Evaluate the expression. */ + e = evalExpr(state, autoCallFunction(evalExpr(state, e))); + + /* It should evaluate to either an attribute set or an + expression, according to what is specified in the + attrPath. */ + + if (apType == apAttr) { + + ATermMap attrs(128); + + if (!isAttrs(state, e, attrs)) + throw TypeError( + format("the expression selected by the selection path `%1%' should be an attribute set but is %2%") + % curPath % showType(e)); + + e = attrs.get(toATerm(attr)); + if (!e) + throw Error(format("attribute `%1%' in selection path `%2%' not found") % attr % curPath); + + } + + else if (apType == apIndex) { + + ATermList es; + if (!matchList(e, es)) + throw TypeError( + format("the expression selected by the selection path `%1%' should be a list but is %2%") + % curPath % showType(e)); + + e = ATelementAt(es, attrIndex); + if (!e) + throw Error(format("list index %1% in selection path `%2%' not found") % attrIndex % curPath); + + } + + } + + return e; +} |