about summary refs log tree commit diff
path: root/src/libstore/misc.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2012-01-04T16·22+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2012-01-04T16·22+0000
commitadaf64a99b0a882249e35768c3f4fe3de104cbb2 (patch)
tree89b3becb5f9197f3d453355262549ea8bf08b9d2 /src/libstore/misc.cc
parent63227d434cefaa9faeb14afe28ebeb9b2d449ee2 (diff)
parent9936da6b546d1ce643eca21ac76c6e7d568de1c2 (diff)
* Merge the multiple-outputs-sandbox branch (svn merge --reintegrate
  ^/nix/branches/multiple-outputs-sandbox).  Multiple output support
  still isn't complete, but it wasn't complete in the trunk either, so
  it doesn't hurt.

Diffstat (limited to 'src/libstore/misc.cc')
-rw-r--r--src/libstore/misc.cc36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index d4bbccd111ba..4ac0afe844b6 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -97,4 +97,40 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
 }
 
  
+static void dfsVisit(StoreAPI & store, const PathSet & paths,
+    const Path & path, PathSet & visited, Paths & sorted,
+    PathSet & parents)
+{
+    if (parents.find(path) != parents.end())
+        throw BuildError(format("cycle detected in the references of `%1%'") % path);
+    
+    if (visited.find(path) != visited.end()) return;
+    visited.insert(path);
+    parents.insert(path);
+    
+    PathSet references;
+    if (store.isValidPath(path))
+        store.queryReferences(path, references);
+    
+    foreach (PathSet::iterator, i, references)
+        /* Don't traverse into paths that don't exist.  That can
+           happen due to substitutes for non-existent paths. */
+        if (*i != path && paths.find(*i) != paths.end())
+            dfsVisit(store, paths, *i, visited, sorted, parents);
+
+    sorted.push_front(path);
+    parents.erase(path);
+}
+
+
+Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
+{
+    Paths sorted;
+    PathSet visited, parents;
+    foreach (PathSet::const_iterator, i, paths)
+        dfsVisit(store, paths, *i, visited, sorted, parents);
+    return sorted;
+}
+
+
 }