+
+ my @source;
+ my @binaries = grep {defined $_} make_list(exists $param{binary}?$param{binary}:[]);
+ my @versions = grep {defined $_} make_list(exists $param{version}?$param{version}:[]);
+ my @archs = grep {defined $_} make_list(exists $param{arch}?$param{arch}:[]);
+ return () unless @binaries;
+ my $cache_key = join("\1",
+ join("\0",@binaries),
+ join("\0",@versions),
+ join("\0",@archs),
+ join("\0",@param{qw(source_only scalar_only)}));
+ if (exists $param{cache}{$cache_key}) {
+ return $param{scalar_only} ? $param{cache}{$cache_key}[0]:
+ @{$param{cache}{$cache_key}};
+ }
+ for my $binary (@binaries) {
+ if ($binary =~ m/^src:(.+)$/) {
+ push @source,[$1,''];
+ next;
+ }
+ if (not tied %_binarytosource) {
+ tie %_binarytosource, MLDBM => $config{binary_source_map}, O_RDONLY or
+ die "Unable to open $config{binary_source_map} for reading";
+ }
+ # avoid autovivification
+ my $bin = $_binarytosource{$binary};
+ next unless defined $bin;
+ if (not @versions) {
+ for my $ver (keys %{$bin}) {
+ for my $ar (keys %{$bin->{$ver}}) {
+ my $src = $bin->{$ver}{$ar};
+ next unless defined $src;
+ push @source,[$src->[0],$src->[1]];
+ }
+ }
+ }
+ else {
+ my $found_one_version = 0;
+ for my $version (@versions) {
+ next unless exists $bin->{$version};
+ if (exists $bin->{$version}{all}) {
+ push @source,dclone($bin->{$version}{all});
+ next;
+ }
+ my @t_archs;
+ if (@archs) {
+ @t_archs = @archs;
+ }
+ else {
+ @t_archs = keys %{$bin->{$version}};
+ }
+ for my $arch (@t_archs) {
+ push @source,dclone($bin->{$version}{$arch}) if
+ exists $bin->{$version}{$arch};
+ }
+ }
+ }