diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 3456a5f714..d0f836cab3 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -2,6 +2,7 @@ #include "store-api.hh" #include "aterm.hh" #include "globals.hh" +#include "util.hh" #include "derivations-ast.hh" #include "derivations-ast.cc" @@ -163,9 +164,7 @@ ATerm unparseDerivation(const Derivation & drv) bool isDerivation(const string & fileName) { - return - fileName.size() >= drvExtension.size() && - string(fileName, fileName.size() - drvExtension.size()) == drvExtension; + return hasSuffix(fileName, drvExtension); } diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index 70604a50a3..372826f31d 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -257,6 +257,7 @@ Hash hashString(HashType ht, const string & s) start(ht, ctx); update(ht, ctx, (const unsigned char *) s.c_str(), s.length()); finish(ht, ctx, hash.hash); + //printMsg(lvlError, format("hashString %1% --> %2%:\n%3%\n===========END======") % s.size() % printHash(hash) % s); return hash; } diff --git a/src/libutil/util.cc b/src/libutil/util.cc index c28f4e1bb7..e541887ee0 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1046,6 +1046,12 @@ bool string2Int(const string & s, long long & n) } +bool hasSuffix(const string & s, const string & suffix) +{ + return s.size() >= suffix.size() && string(s, s.size() - suffix.size()) == suffix; +} + + void ignoreException() { try { diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 6c67e450b5..1fd89f3a55 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -294,6 +294,10 @@ bool string2Int(const string & s, int & n); bool string2Int(const string & s, long long & n); +/* Return true iff `s' ends in `suffix'. */ +bool hasSuffix(const string & s, const string & suffix); + + /* Exception handling in destructors: print an error message, then ignore the exception. */ void ignoreException(); diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 6cbd06f8d2..4cc5484cc4 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -115,18 +115,29 @@ static void getAllExprs(EvalState & state, const Path & path, ATermMap & attrs) { Strings names = readDirectory(path); + StringSet namesSorted(names.begin(), names.end()); - for (Strings::iterator i = names.begin(); i != names.end(); ++i) { + foreach (StringSet::iterator, i, namesSorted) { Path path2 = path + "/" + *i; struct stat st; if (stat(path2.c_str(), &st) == -1) continue; // ignore dangling symlinks in ~/.nix-defexpr - if (isNixExpr(path2)) - attrs.set(toATerm(*i), makeAttrRHS( + if (isNixExpr(path2)) { + /* Strip off the `.nix' filename suffix (if applicable), + otherwise the attribute cannot be selected with the + `-A' option. Useful if you want to stick a Nix + expression directly in ~/.nix-defexpr. */ + string attrName = *i; + if (hasSuffix(attrName, ".nix")) + attrName = string(attrName, 0, attrName.size() - 4); + attrs.set(toATerm(attrName), makeAttrRHS( parseExprFromFile(state, absPath(path2)), makeNoPos())); + } else + /* `path2' is a directory (with no default.nix in it); + recurse into it. */ getAllExprs(state, path2, attrs); } }