guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

243/376: Add primop ‘catAttrs’


From: Ludovic Courtès
Subject: 243/376: Add primop ‘catAttrs’
Date: Wed, 28 Jan 2015 22:05:21 +0000

civodul pushed a commit to tag 1.8
in repository guix.

commit c3f0a489f9d58878c211467a84d7db9dae4e8b5a
Author: Eelco Dolstra <address@hidden>
Date:   Sat Oct 4 18:15:03 2014 +0200

    Add primop ‘catAttrs’
---
 src/libexpr/primops.cc            |   30 ++++++++++++++++++++++++++++++
 tests/lang/eval-okay-catattrs.exp |    1 +
 tests/lang/eval-okay-catattrs.nix |    1 +
 3 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index fb37e21..a1374a0 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -1123,6 +1123,35 @@ static void prim_intersectAttrs(EvalState & state, const 
Pos & pos, Value * * ar
 }
 
 
+/* Collect each attribute named `attr' from a list of attribute sets.
+   Sets that don't contain the named attribute are ignored.
+
+   Example:
+     catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
+     => [1 2]
+*/
+static void prim_catAttrs(EvalState & state, const Pos & pos, Value * * args, 
Value & v)
+{
+    Symbol attrName = state.symbols.create(state.forceStringNoCtx(*args[0], 
pos));
+    state.forceList(*args[1], pos);
+
+    Value * res[args[1]->list.length];
+    unsigned int found = 0;
+
+    for (unsigned int n = 0; n < args[1]->list.length; ++n) {
+        Value & v2(*args[1]->list.elems[n]);
+        state.forceAttrs(v2, pos);
+        Bindings::iterator i = v2.attrs->find(attrName);
+        if (i != v2.attrs->end())
+            res[found++] = i->value;
+    }
+
+    state.mkList(v, found);
+    for (unsigned int n = 0; n < found; ++n)
+        v.list.elems[n] = res[n];
+}
+
+
 /* Return a set containing the names of the formal arguments expected
    by the function `f'.  The value of each attribute is a Boolean
    denoting whether has a default value.  For instance,
@@ -1530,6 +1559,7 @@ void EvalState::createBaseEnv()
     addPrimOp("removeAttrs", 2, prim_removeAttrs);
     addPrimOp("__listToAttrs", 1, prim_listToAttrs);
     addPrimOp("__intersectAttrs", 2, prim_intersectAttrs);
+    addPrimOp("__catAttrs", 2, prim_catAttrs);
     addPrimOp("__functionArgs", 1, prim_functionArgs);
 
     // Lists
diff --git a/tests/lang/eval-okay-catattrs.exp 
b/tests/lang/eval-okay-catattrs.exp
new file mode 100644
index 0000000..b4a1e66
--- /dev/null
+++ b/tests/lang/eval-okay-catattrs.exp
@@ -0,0 +1 @@
+[ 1 2 ]
diff --git a/tests/lang/eval-okay-catattrs.nix 
b/tests/lang/eval-okay-catattrs.nix
new file mode 100644
index 0000000..2c3dc10
--- /dev/null
+++ b/tests/lang/eval-okay-catattrs.nix
@@ -0,0 +1 @@
+builtins.catAttrs "a" [ { a = 1; } { b = 0; } { a = 2; } ]



reply via email to

[Prev in Thread] Current Thread [Next in Thread]