aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/primops.cc
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2014-10-01 10:17:50 -0400
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-10-03 22:32:11 +0200
commitc08c802bf31ce739e0de6d1fbfe4d58b808ae9bb (patch)
tree7b310664b2bead47f3de29d1663b251187344054 /src/libexpr/primops.cc
parent3fd2d2187efcb0d7c7fe7ebdc2baa14edfac6d0c (diff)
Add readDir primop
Diffstat (limited to 'src/libexpr/primops.cc')
-rw-r--r--src/libexpr/primops.cc37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 0ec39f553..ca4ccf449 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -800,6 +800,42 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va
mkPath(v, state.findFile(searchPath, path).c_str());
}
+/* Read a directory (without . or ..) */
+static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Value & v)
+{
+ PathSet ctx;
+ Path path = state.coerceToPath(pos, *args[0], ctx);
+ try {
+ realiseContext(ctx);
+ } catch (InvalidPathError & e) {
+ throw EvalError(format("cannot read ‘%1%’, since path ‘%2%’ is not valid, at %3%")
+ % path % e.path % pos);
+ }
+
+ DirEntries entries = readDirectory(path);
+ state.mkAttrs(v, entries.size());
+
+ for (const auto & ent : entries) {
+ Value * ent_val = state.allocAttr(v, state.symbols.create(ent.name));
+ if (ent.type == DT_UNKNOWN) {
+ struct stat st = lstat(path + "/" + ent.name);
+ mkString(*ent_val,
+ S_ISREG(st.st_mode) ? "regular" :
+ S_ISDIR(st.st_mode) ? "directory" :
+ S_ISLNK(st.st_mode) ? "symlink" :
+ "unknown");
+ } else {
+ mkString(*ent_val,
+ ent.type == DT_REG ? "regular" :
+ ent.type == DT_DIR ? "directory" :
+ ent.type == DT_LNK ? "symlink" :
+ "unknown");
+ }
+ }
+
+ v.attrs->sort();
+}
+
/*************************************************************
* Creating files
@@ -1460,6 +1496,7 @@ void EvalState::createBaseEnv()
addPrimOp("baseNameOf", 1, prim_baseNameOf);
addPrimOp("dirOf", 1, prim_dirOf);
addPrimOp("__readFile", 1, prim_readFile);
+ addPrimOp("__readDir", 1, prim_readDir);
addPrimOp("__findFile", 2, prim_findFile);
// Creating files