Package: libdpkg-perl
Version: 1.17.9
Severity: normal

Hi.

Here's a patch to add a new function Dpkg::Deps::deps_iterate_flat().
This is a utility function to iterate through items in a Depends line.
This was needed for some new sbuild functionality I needed to add to
support some cross builds.


>From 8cae5ad7a2cbdb05eb09fb0840d0301da62dd10a Mon Sep 17 00:00:00 2001
From: Dima Kogan <[email protected]>
Date: Fri, 29 Aug 2014 15:10:13 -0700
Subject: [PATCH] added Dpkg::Deps::deps_iterate_flat

This is a utility function to iterate through items in a Depends line
---
 scripts/Dpkg/Deps.pm | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/scripts/Dpkg/Deps.pm b/scripts/Dpkg/Deps.pm
index fe25def..e6f841f 100644
--- a/scripts/Dpkg/Deps.pm
+++ b/scripts/Dpkg/Deps.pm
@@ -58,7 +58,7 @@ use Dpkg::ErrorHandling;
 use Dpkg::Gettext;
 
 use Exporter qw(import);
-our @EXPORT = qw(deps_concat deps_parse deps_eval_implication deps_compare);
+our @EXPORT = qw(deps_concat deps_parse deps_iterate_flat  deps_eval_implication deps_compare);
 
 =item deps_eval_implication($rel_p, $v_p, $rel_q, $v_q)
 
@@ -308,6 +308,73 @@ sub deps_parse {
     return $dep_and;
 }
 
+
+=item deps_iterate_flat( $deps, $callback )
+
+This function parses a dependency object (Dpkg::Deps::*), and invokes a callback
+for each package mentioned. For instance, to get a list of all
+explicitly-specified architectures:
+
+ my $deps = deps_parse( <<EOF );
+ a, b:armel, c | d:armhf, d:mips (>>1.2)
+ EOF
+
+ my %set;
+ deps_iterate_flat( $deps,
+                    sub {
+                        my $dep = shift;
+                        if( $dep->{archqual} )
+                        {
+                            $set{$dep->{archqual}} = 1;
+                        }
+                        return 1;
+                    } );
+ my @explicit_arches = keys %set;
+
+ show @explicit_arches;
+
+ =========> ["armhf", "mips", "armel"]
+
+=back
+
+=cut
+
+sub deps_iterate_flat
+{
+    my ($deps, $callback) = @_;
+
+
+    my %already_visited;
+
+    # returns true if we should continue. returns false if we should stop
+    # (something went wrong or the callback returned false)
+    my $iterate_level;
+    $iterate_level = sub
+    {
+        foreach my $dep (@_)
+        {
+            # I make sure to break any recursion in the deps data structure
+            return if !defined $dep;
+            my $id = ref($dep) ? refaddr($dep) : "str:$dep";
+            return 1 if $already_visited{$id};
+            $already_visited{$id} = 1;
+
+            if ( defined(ref $dep) && ref($dep) eq 'Dpkg::Deps::Simple' )
+            {
+                return undef unless &$callback($dep);
+            }
+            else
+            {
+                return undef unless &$iterate_level($dep->get_deps);
+            }
+        }
+        return 1;
+    };
+
+    return &$iterate_level($deps);
+}
+
+
 =item deps_compare($a, $b)
 
 Implements a comparison operator between two dependency objects.
-- 
2.0.0

Reply via email to