--- /dev/null
+#!/usr/bin/perl
+
+use POSIX;
+use Config::IniFiles;
+use File::FnMatch;
+use Data::Dumper;
+use solv;
+use strict;
+
+package Repo::generic;
+
+sub new {
+ my ($class, $attr) = @_;
+ my $r = { %$attr };
+ return bless $r, $class;
+}
+
+sub cachepath {
+ my ($self, $ext) = @_;
+ my $path = $self->{'alias'};
+ $path =~ s/^\./_/s;
+ $path .= $ext ? "_$ext.solvx" : '.solv';
+ $path =~ s/\//_/gs;
+ return "/var/cache/solv/$path";
+}
+
+sub load {
+ my ($self, $pool) = @_;
+ $self->{'handle'} = $pool->add_repo($self->{'alias'});
+ $self->{'handle'}->{'appdata'} = $self;
+ $self->{'handle'}->{'priority'} = 99 - $self->{'priority'};
+ $self->{'cookie'} = '';
+ $self->usecachedrepo();
+}
+
+sub usecachedrepo {
+ my ($self, $ext, $mark) = @_;
+ my $cookie = $ext ? $self->{'extcookie'} : $self->{'cookie'};
+ my $handle = $self->{'handle'};
+ my $cachepath = $self->cachepath();
+ if (sysopen(my $f, $cachepath, POSIX::O_RDONLY)) {
+ $f = solv::xfopen_fd('', POSIX::dup(fileno($f)));
+ my $flags = $ext ? $solv::Repo::REPO_USE_LOADING|$solv::Repo::REPO_EXTEND_SOLVABLES : 0;
+ $flags |= $solv::Repo::REPO_LOCALPOOL if $ext && $ext ne 'DL';
+ if (!$self->{'handle'}->add_solv($f, $flags)) {
+ solv::xfclose($f);
+ return undef;
+ }
+ return 1;
+ }
+ return undef;
+}
+
+package Repo::rpmmd;
+
+our @ISA = ('Repo::generic');
+
+package Repo::system;
+
+our @ISA = ('Repo::generic');
+
+sub calc_cookie_file {
+ my ($self, $filename) = @_;
+ my $chksum = solv::Chksum->new($solv::REPOKEY_TYPE_SHA256);
+ $chksum->add("1.1");
+ $chksum->add_stat($filename);
+ return $chksum->raw();
+}
+
+sub load {
+ my ($self, $pool) = @_;
+
+ $self->{'handle'} = $pool->add_repo($self->{'alias'});
+ $self->{'handle'}->{'appdata'} = $self;
+ $pool->{'installed'} = $self->{'handle'};
+ print "rpm database: ";
+ $self->{'cookie'} = $self->calc_cookie_file('/var/lib/rpm/Packages');
+ if ($self->usecachedrepo()) {
+ print "cached\n";
+ return 1;
+ }
+ return undef;
+}
+
+package main;
+
+sub validarch {
+ my ($pool, $arch) = @_;
+ return undef unless $arch;
+ my $id = $pool->str2id($arch, 0);
+ return $id && $pool->isknownarch($id) ? 1 : undef;
+}
+
+sub depglob {
+ my ($pool, $name, $globname, $globdep) = @_;
+ my $id = $pool->str2id($name, 0);
+ if ($id) {
+ my $match;
+ for my $s ($pool->providers($id)) {
+ return $pool->Job($solv::Job::SOLVER_SOLVABLE_NAME, $id) if $globname && $s->{'nameid'} == $id;
+ $match = 1;
+ }
+ if ($match) {
+ print "[using capability match for '$name']\n" if $globname && $globdep;
+ my @j = $pool->Job($solv::Job::SOLVER_SOLVABLE_PROVIDES, $id);
+ return $pool->Job($solv::Job::SOLVER_SOLVABLE_PROVIDES, $id);
+ }
+ }
+ return unless $name =~ /[[*?]/;
+ if ($globname) {
+ my %idmatches;
+ for my $s (@{$pool->{'solvables_iter'}}) {
+ $idmatches{$s->{'nameid'}} = 1 if $s->installable() && File::FnMatch::fnmatch($name, $s->{'name'}, 0);
+ }
+ if (%idmatches) {
+ return map {$pool->Job($solv::Job::SOLVER_SOLVABLE_NAME, $_)} sort(keys %idmatches);
+ }
+ }
+ if ($globdep) {
+ my %idmatches;
+ for $id (@{$pool->allprovidingids()}) {
+ $idmatches{$id} = 1 if File::FnMatch::fnmatch($name, $pool->id2str($id), 0);
+ }
+ if (%idmatches) {
+ print "[using capability match for '$name']\n";
+ return map {$pool->Job($solv::Job::SOLVER_SOLVABLE_PROVIDES, $_)} sort(keys %idmatches);
+ }
+ }
+ return;
+}
+
+sub limitjobs {
+ my ($pool, $jobs, $flags, $evr) = @_;
+ my @jobs;
+ for my $j (@$jobs) {
+ my $how = $j->{'how'};
+ my $sel = $how & $solv::Job::SOLVER_SELECTMASK;
+ my $what = $pool->rel2id($j->{'what'}, $evr, $flags);
+ if ($flags == $solv::REL_ARCH) {
+ $how |= $solv::Job::SOLVER_SETARCH;
+ } elsif ($flags == $solv::REL_EQ && $sel == $solv::Job::SOLVER_SOLVABLE_NAME) {
+ $how |= $pool->id2str($evr) =~ /-/ ? $solv::Job::SOLVER_SETEVR : $solv::Job::SOLVER_SETEV;
+ }
+ push @jobs, $pool->Job($how, $what);
+ }
+ return @jobs;
+}
+
+sub limitjobs_arch {
+ my ($pool, $jobs, $flags, $evrstr) = @_;
+ if ($evrstr =~ /^(.+)\.(.+?)$/ && validarch($pool, $2)) {
+ my $evr = $pool->str2id($1);
+ my @jobs = limitjobs($pool, $jobs, $solv::solv::REL_ARCH, $pool->str2id($2));
+ return limitjobs($pool, \@jobs, $flags, $evr);
+ }
+ return limitjobs($pool, $jobs, $flags, $pool->str2id($evrstr));
+}
+
+sub mkjobs_rel {
+ my ($pool, $cmd, $name, $rel, $evr) = @_;
+ my $flags = 0;
+ $flags |= $solv::REL_LT if $rel =~ /</;
+ $flags |= $solv::REL_EQ if $rel =~ /=/;
+ $flags |= $solv::REL_GT if $rel =~ />/;
+ my @jobs = depglob($pool, $name, 1, 1);
+ return limitjobs($pool, \@jobs, $flags, $pool->str2id($evr)) if @jobs;
+ if (($name =~ /^(.+)\.(.+?)$/s) && validarch($pool, $2)) {
+ my $arch = $2;
+ @jobs = depglob($pool, $1, 1, 1);
+ if (@jobs) {
+ @jobs = limitjobs($pool, \@jobs, $solv::solv::REL_ARCH, $pool->str2id($arch));
+ return limitjobs($pool, \@jobs, $flags, $pool->str2id($evr));
+ }
+ }
+ return ();
+}
+
+sub mkjobs_nevra {
+ my ($pool, $cmd, $arg) = @_;
+ my @jobs = depglob($pool, $arg, 1, 1);
+ return @jobs if @jobs;
+ if (($arg =~ /^(.+)\.(.+?)$/s) && validarch($pool, $2)) {
+ my $arch = $2;
+ @jobs = depglob($pool, $1, 1, 1);
+ return limitjobs($pool, \@jobs, $solv::REL_ARCH, $pool->str2id($arch)) if @jobs;
+ }
+ if ($arg =~ /^(.+)-(.+?)$/s) {
+ my $evr = $2;
+ @jobs = depglob($pool, $1, 1, 0);
+ return limitjobs_arch($pool, \@jobs, $solv::REL_EQ, $evr) if @jobs;
+ }
+ if ($arg =~ /^(.+)-(.+?-.+?)$/s) {
+ my $evr = $2;
+ @jobs = depglob($pool, $1, 1, 0);
+ return limitjobs_arch($pool, \@jobs, $solv::REL_EQ, $evr) if @jobs;
+ }
+ return ();
+}
+
+sub mkjobs_filelist {
+ my ($pool, $cmd, $arg) = @_;
+ my $type = ($arg =~ /[[*?]/) ? $solv::Dataiterator::SEARCH_GLOB : $solv::Dataiterator::SEARCH_STRING;
+ $type |= $solv::Dataiterator::SEARCH_FILES | $solv::Dataiterator::SEARCH_COMPLETE_FILELIST;
+ my $di;
+ if ($cmd eq 'erase') {
+ $di = $pool->{'installed'}->dataiterator_new(0, $solv::SOLVABLE_FILELIST, $arg, $type);
+ } else {
+ $di = $pool->dataiterator_new(0, $solv::SOLVABLE_FILELIST, $arg, $type);
+ }
+ my @matches;
+ for my $d (@$di) {
+ my $s = $d->{'solvable'};
+ next unless $s && $s->installable();
+ push @matches, $s->{'id'};
+ tied(@$di)->iter()->skip_solvable();
+ }
+ return () unless @matches;
+ print "[using file list match for '$arg']\n";
+ if (@matches > 1) {
+ return $pool->Job($solv::Job::SOLVER_SOLVABLE_ONE_OF, $pool->towhatprovides(\@matches));
+ } else {
+ return $pool->Job($solv::Job::SOLVER_SOLVABLE | $solv::Job::NOAUTOSET, $matches[0]);
+ }
+}
+
+sub mkjobs {
+ my ($pool, $cmd, $arg) = @_;
+ if ($arg && $arg =~ /^\//) {
+ my @jobs = mkjobs_filelist($pool, $cmd, $arg);
+ return @jobs if @jobs;
+ }
+ if ($arg =~ /^(.+?)\s*([<=>]+)\s*(.+?)$/s) {
+ return mkjobs_rel($pool, $cmd, $1, $2, $3);
+ } else {
+ return mkjobs_nevra($pool, $cmd, $arg);
+ }
+}
+
+die("Usage: p5solv COMMAND [ARGS]\n") unless @ARGV;
+my $cmd = shift @ARGV;
+$cmd = 'list' if $cmd eq 'li';
+$cmd = 'install' if $cmd eq 'in';
+$cmd = 'erase' if $cmd eq 'rm';
+$cmd = 'verify' if $cmd eq 've';
+$cmd = 'search' if $cmd eq 'se';
+
+my $pool = solv::Pool->new();
+$pool->setarch((POSIX::uname())[4]);
+my @repos;
+for my $reposdir ('/etc/zypp/repos.d') {
+ next unless -d $reposdir;
+ next unless opendir(DIR, $reposdir);
+ for my $reponame (sort(grep {/\.repo$/} readdir(DIR))) {
+ my $cfg = new Config::IniFiles('-file' => "$reposdir/$reponame");
+ for my $alias ($cfg->Sections()) {
+ my $repoattr = {'alias' => $alias, 'enabled' => 0, 'priority' => 99, 'autorefresh' => 1, 'type' => 'rpm-md', 'metadata_expire' => 900};
+ for my $p ($cfg->Parameters($alias)) {
+ $repoattr->{$p} = $cfg->val($alias, $p);
+ }
+ my $repo;
+ if ($repoattr->{'type'} == 'rpm-md') {
+ $repo = Repo::rpmmd->new($repoattr);
+ }
+ push @repos, $repo;
+ }
+ }
+}
+
+my $sysrepo = Repo::system->new({'alias' => '@System', 'type' => 'system'});
+$sysrepo->load($pool);
+for my $repo (@repos) {
+ $repo->load($pool) if $repo->{'enabled'};
+}
+
+if ($cmd eq 'search') {
+ my %matches;
+ my $di = $pool->dataiterator_new(0, $solv::SOLVABLE_NAME, $ARGV[0], $solv::Dataiterator::SEARCH_SUBSTRING | $solv::Dataiterator::SEARCH_NOCASE);
+ for my $d (@$di) {
+ $matches{$d->{'solvid'}} = 1;
+ }
+ for my $solvid (sort keys %matches) {
+ my $s = $pool->{'solvables'}->[$solvid];
+ print "- ".$s->str()." [$s->{'repo'}->{'name'}] ".$s->lookup_str($solv::SOLVABLE_SUMMARY)."\n";
+ }
+ exit(0);
+}
+
+my $addedprovides = $pool->addfileprovides_ids();
+$pool->createwhatprovides();
+
+my @jobs;
+for my $arg (@ARGV) {
+ my @njobs = mkjobs($pool, $cmd, $arg);
+ die("nothing matches '$arg'\n") unless @njobs;
+ push @jobs, @njobs;
+}
+
+if ($cmd eq 'list' || $cmd eq 'info') {
+ die("no package matched.\n") unless @jobs;
+ for my $job (@jobs) {
+ for my $s ($pool->jobsolvables($job)) {
+ if ($cmd eq 'info') {
+ printf "Name: %s\n", $s->str();
+ printf "Repo: %s\n", $s->{'repo'}->{'name'};
+ printf "Summary: %s\n", $s->lookup_str($solv::SOLVABLE_SUMMARY);
+ my $str = $s->lookup_str($solv::SOLVABLE_URL);
+ printf "Url: %s\n", $str if $str;
+ my $str = $s->lookup_str($solv::SOLVABLE_LICENSE);
+ printf "License: %s\n", $str if $str;
+ printf "Description:\n%s\n", $s->lookup_str($solv::SOLVABLE_DESCRIPTION);
+ } else {
+ printf " - %s [%s]\n", $s->str(), $s->{'repo'}->{'name'};
+ printf " %s\n", $s->lookup_str($solv::SOLVABLE_SUMMARY);
+ }
+ }
+ }
+ exit 0;
+}
+
+if ($cmd eq 'install' || $cmd eq 'erase' || $cmd eq 'up' || $cmd eq 'dup' || $cmd eq 'verify') {
+ if (!@jobs) {
+ if ($cmd eq 'up' || $cmd eq 'verify') {
+ push @jobs, $pool->Job($solv::Job::SOLVER_SOLVABLE_ALL, 0);
+ } elsif ($cmd ne 'dup') {
+ die("no package matched.\n");
+ }
+ }
+ for my $job (@jobs) {
+ if ($cmd eq 'up') {
+ if ($job->{'how'} == $solv::Job::SOLVER_SOLVABLE_ALL || grep {$_->isinstalled()} @{$pool->jobsolvables($job)}) {
+ $job->{'how'} |= $solv::Job::SOLVER_UPDATE;
+ } else {
+ $job->{'how'} |= $solv::Job::SOLVER_INSTALL;
+ }
+ } elsif ($cmd eq 'install') {
+ $job->{'how'} |= $solv::Job::SOLVER_INSTALL;
+ } elsif ($cmd eq 'erase') {
+ $job->{'how'} |= $solv::Job::SOLVER_ERASE;
+ } elsif ($cmd eq 'dup') {
+ $job->{'how'} |= $solv::Job::SOLVER_DISTUPGRADE;
+ } elsif ($cmd eq 'verify') {
+ $job->{'how'} |= $solv::Job::SOLVER_VERIFY;
+ }
+ }
+ my $solver;
+ while (1) {
+ $solver = $pool->create_solver();
+ $solver->{'ignorealreadyrecommended'} = 1;
+ $solver->{'allowuninstall'} = 1 if $cmd eq 'erase';
+ if ($cmd eq 'dup' && !@jobs) {
+ $solver->{'distupgrade'} = 1;
+ $solver->{'updatesystem'} = 1;
+ $solver->{'allowdowngrade'} = 1;
+ $solver->{'allowvendorchange'} = 1;
+ $solver->{'allowarchchange'} = 1;
+ $solver->{'dosplitprovides'} = 1;
+ } elsif ($cmd eq 'up' and @jobs == 1 and $jobs[0]->{'how'} == ($solv::Job::SOLVER_UPDATE | $solv::Job::SOLVER_SOLVABLE_ALL)) {
+ $solver->{'dosplitprovides'} = 1;
+ }
+ my @problems = $solver->solve(\@jobs);
+ last unless @problems;
+ for my $problem (@problems) {
+ print "Problem $problem->{'id'}:\n";
+ my $r = $problem->findproblemrule();
+ my ($type, $source, $target, $dep) = $r->info();
+ if ($type == $solv::Solver::SOLVER_RULE_RPM_PACKAGE_CONFLICT) {
+ printf "package %s conflicts with %s provided by %s\n", $source->str(), $pool->dep2str($dep), $target->str();
+ }
+ print "TYPE: $type\n";
+ printf "SOURCE: %s\n", $source->str() if $source;
+ printf "TARGET: %s\n", $target->str() if $target;
+ printf "DEP: %s\n", $pool->dep2str($dep) if $dep;
+ }
+ exit(0);
+ }
+}
+
+exit 0;
%module solv
+#if defined(SWIGPYTHON)
%typemap(in) Queue {
/* Check if is a list */
queue_init(&$1);
queue_free(&$1);
$result = o;
}
+#endif
+#if defined(SWIGPERL)
+%typemap(in) Queue {
+ AV *av;
+ int i, size;
+ queue_init(&$1);
+ if (!SvROK($input) || SvTYPE(SvRV($input)) != SVt_PVAV)
+ SWIG_croak("Argument $argnum is not an array reference.");
+ av = (AV*)SvRV($input);
+ size = av_len(av);
+ for (i = 0; i <= size; i++) {
+ SV **sv = av_fetch(av, i, 0);
+ int v;
+ int e = SWIG_AsVal_int(*sv, &v);
+ if (!SWIG_IsOK(e)) {
+ SWIG_croak("list must contain only integers");
+ }
+ queue_push(&$1, v);
+ }
+}
+%typemap(out) Queue {
+ int i;
+ AV *o = newAV();
+ for (i = 0; i < $1.count; i++)
+ av_push(o, SvREFCNT_inc(SWIG_From_int($1.elements[i])));
+ queue_free(&$1);
+ $result = newRV_noinc((SV*)o); argvi++;
+}
+#endif
%typemap(arginit) Queue {
queue_init(&$1);
}
queue_free(&$1);
}
+#if defined(SWIGPERL)
+%define perlmkarray(class,accessor,constructor)
+ %perlcode {
+ *solv::##class##::array::TIEARRAY = sub { bless $_[1], 'solv::class::array' };
+ *solv::##class##::array::FETCHSIZE = *solv::##class##::__len__;
+ *solv::##class##::array::FETCH = *solv::##class##::__getitem__;
+ undef *solv::##accessor##;
+ *solv::##accessor = sub { my @a; tie(@a, 'solv::class::array', ##constructor##(@_)); \@a };
+ }
+%enddef
+%define perlmkiter(class,accessor,constructor)
+ %perlcode {
+ *solv::##class##::iter::TIEARRAY = sub { bless [$_[1], 0], 'solv::class::iter' };
+ *solv::##class##::iter::FETCHSIZE = sub { ($_[0]->[2] = $_[0]->[0]->__next__()) ? ++$_[0]->[1] : 0 };
+ *solv::##class##::iter::FETCH = sub { $_[1] == $_[0]->[1] - 1 ? $_[0]->[2] : undef };
+ *solv::##class##::iter::iter = sub { return $_[0]->[0] };
+ undef *solv::##accessor##;
+ *solv::##accessor = sub { my @a; tie(@a, 'solv::class::iter', ##constructor##(@_)); \@a };
+ }
+%enddef
+#endif
+
+
+#if defined(SWIGPYTHON)
+typedef PyObject *AppObjectPtr;
+%typemap(out) AppObjectPtr {
+ $result = $1;
+ Py_INCREF($result);
+}
+#endif
+#if defined(SWIGPERL)
+typedef SV *AppObjectPtr;
+%typemap(out) AppObjectPtr {
+ $result = $1;
+ SvREFCNT_inc($result);
+}
+#endif
+#if defined(SWIGRUBY)
+typedef VALUE AppObjectPtr;
+#endif
%include "cdata.i"
+#ifndef SWIGPERL
%include "file.i"
+#endif
%include "typemaps.i"
%{
#define SOLVER_SOLUTION_REPLACE -101
typedef struct chksum Chksum;
typedef int bool;
+typedef void *AppObjectPtr;
typedef struct {
Pool* pool;
%nodefaultctor Pool;
%nodefaultdtor Pool;
typedef struct {
+ AppObjectPtr appdata;
} Pool;
%nodefaultctor Repo;
int priority;
int subpriority;
int const nsolvables;
-#if defined(SWIGRUBY)
- VALUE appdata;
-#endif
-#if defined(SWIGPERL)
- SV *appdata;
-#endif
+ AppObjectPtr appdata;
} Repo;
%nodefaultctor Pool_solvable_iterator;
const unsigned char *b = pool_lookup_bin_checksum($self, entry, keyname, &type);
return sat_chksum_create_from_bin(type, b);
}
+
+#ifdef SWIGPERL
+ perlmkiter(Dataiterator, Pool::dataiterator_new, solvc::Pool_dataiterator_new)
+#endif
%newobject dataiterator_new;
Dataiterator *dataiterator_new(Id p, Id key, const char *match, int flags) {
return new_Dataiterator($self, 0, p, key, match, flags);
void createwhatprovides() {
pool_createwhatprovides($self);
}
+
+
+#if defined(SWIGPERL)
+ perlmkarray(Pool_solvable_iterator, Pool::swig_solvables_get, solvc::Pool_solvables_get)
+ perlmkiter(Pool_solvable_iterator, Pool::swig_solvables_iter_get, solvc::Pool_solvables_get)
+#endif
+
%newobject solvables;
Pool_solvable_iterator * const solvables;
%{
return s;
}
%}
+
+#if defined(SWIGPERL)
+ perlmkarray(Pool_repo_iterator, Pool::swig_repos_get, solvc::Pool_repos_get)
+ perlmkiter(Pool_repo_iterator, Pool::swig_repos_iter_get, solvc::Pool_repos_get)
+#endif
+
%newobject repos;
Pool_repo_iterator * const repos;
%{
return s;
}
%}
+
Repo *installed;
%{
SWIGINTERN void Pool_installed_set(Pool *pool, Repo *installed) {
return [ self.solvables[id] for id in self.providerids(*args) ]
}
#endif
+#if defined(SWIGPERL)
+ %perlcode {
+ sub solv::Pool::jobsolvables {
+ my ($self, @args) = @_;
+ return map {$self->{'solvables'}->[$_]} @{$self->jobsolvids(@args)};
+ }
+ sub solv::Pool::providers {
+ my ($self, @args) = @_;
+ return map {$self->{'solvables'}->[$_]} @{$self->providerids(@args)};
+ }
+ }
+#endif
Id towhatprovides(Queue q) {
return pool_queuetowhatprovides($self, &q);
$self->nrepodata = oldnrepodata;
return 1;
}
+
+#ifdef SWIGPERL
+ perlmkiter(Dataiterator, Repo::dataiterator_new, solvc::Repo_dataiterator_new)
+#endif
+
%newobject dataiterator_new;
Dataiterator *dataiterator_new(Id p, Id key, const char *match, int flags) {
return new_Dataiterator($self->pool, $self, p, key, match, flags);
if (data->state != REPODATA_STUB)
repodata_create_stubs(data);
}
-#if defined(SWIGPYTHON)
- PyObject *appdata;
- %{
- SWIGINTERN void Repo_appdata_set(Repo *repo, PyObject *o) {
- repo->appdata = o;
- }
- SWIGINTERN PyObject *Repo_appdata_get(Repo *repo) {
- PyObject *o = repo->appdata;
- Py_INCREF(o);
- return o;
- }
- %}
-#endif
bool iscontiguous() {
int i;
for (i = $self->start; i < $self->end; i++)
dataiterator_free($self);
sat_free($self);
}
+#if defined(SWIGPYTHON)
%newobject __iter__;
Dataiterator *__iter__() {
Dataiterator *ndi;
dataiterator_init_clone(ndi, $self);
return ndi;
}
- %exception next {
+ %rename("next") __next__();
+ %exception __next__ {
$action
if (!result) {
PyErr_SetString(PyExc_StopIteration,"no more matches");
return NULL;
}
}
- %newobject next;
- Dataiterator *next() {
+#endif
+ %newobject __next__;
+ Dataiterator *__next__() {
Dataiterator *ndi;
if (!dataiterator_step($self)) {
return 0;
}
}
-
%extend Pool_solvable_iterator {
+#if defined(SWIGPYTHON)
%newobject __iter__;
Pool_solvable_iterator *__iter__() {
Pool_solvable_iterator *s;
*s = *$self;
return s;
}
- %exception next {
+ %rename("next") __next__();
+ %exception __next__ {
$action
if (!result) {
PyErr_SetString(PyExc_StopIteration,"no more matches");
return NULL;
}
}
- %newobject next;
- XSolvable *next() {
+#endif
+ %newobject __next__;
+ XSolvable *__next__() {
Pool *pool = $self->pool;
XSolvable *s;
if ($self->id >= pool->nsolvables)
return new_XSolvable(pool, key);
return 0;
}
+ int __len__() {
+ return $self->pool->nsolvables;
+ }
}
%extend Pool_repo_iterator {
+#if defined(SWIGPYTHON)
%newobject __iter__;
Pool_repo_iterator *__iter__() {
Pool_repo_iterator *s;
*s = *$self;
return s;
}
- %exception next {
+ %rename("next") __next__();
+ %exception __next__ {
$action
if (!result) {
PyErr_SetString(PyExc_StopIteration,"no more matches");
return NULL;
}
}
- Repo *next() {
+#endif
+ %newobject __next__;
+ Repo *__next__() {
Pool *pool = $self->pool;
if ($self->id >= pool->nrepos + 1)
return 0;
return pool_id2repo(pool, key);
return 0;
}
+ int __len__() {
+ return $self->pool->nrepos + 1;
+ }
}
%extend Repo_solvable_iterator {
+#if defined(SWIGPYTHON)
%newobject __iter__;
Repo_solvable_iterator *__iter__() {
Repo_solvable_iterator *s;
*s = *$self;
return s;
}
- %exception next {
+ %rename("next") __next__();
+ %exception __next__ {
$action
if (!result) {
PyErr_SetString(PyExc_StopIteration,"no more matches");
return NULL;
}
}
- %newobject next;
- XSolvable *next() {
+#endif
+ %newobject __next__;
+ XSolvable *__next__() {
Repo *repo = $self->repo;
Pool *pool = repo->pool;
XSolvable *s;
return new_XSolvable(pool, key);
return 0;
}
+ int __len__() {
+ return $self->repo->pool->nsolvables;
+ }
}
%extend XSolvable {
return [ Solution(self, i) for i in range(1, self.solution_count() + 1) ];
}
#endif
+#if defined(SWIGPERL)
+ %perlcode {
+ sub solv::Problem::findproblemrule {
+ my ($self) = @_;
+ return solv::XRule->new($self->{'solv'}, $self->findproblemrule_helper());
+ }
+ sub solv::Problem::findallproblemrule {
+ my ($self, $unfiltered) = @_;
+ return map {solv::XRule->new($self->{'solv'}, $_)} @{$self->findallproblemrule_helper($unfiltered)};
+ }
+ sub solv::Problem::solutions {
+ my ($self) = @_;
+ return map {solv::Solution->new($self, $_)} 1..($self->solution_count());
+ }
+ }
+#endif
}
%extend Solution {
return [ Solutionelement(self, i) for i in range(1, self.element_count() + 1) ];
}
#endif
+#if defined(SWIGPERL)
+ %perlcode {
+ sub solv::Solution::elements {
+ my ($self) = @_;
+ return map {solv::Solutionelement->new($self, $_)} 1..($self->element_count());
+ }
+ }
+#endif
}
%extend Solutionelement {
return [ Problem(self, pid) for pid in range(1, nprob + 1) ]
}
#endif
+#if defined(SWIGPERL)
+ %perlcode {
+ sub solv::Solver::solve {
+ my ($self, $jobs) = @_;
+ my @j = map {($_->{'how'}, $_->{'what'})} @$jobs;
+ my $nprob = $self->solve_helper(\@j);
+ return map {solv::Problem->new($self, $_)} 1..$nprob;
+ }
+ }
+#endif
int solve_helper(Queue jobs) {
solver_solve($self, &jobs);
return solver_problem_count($self);
return type, source, target, dep
}
#endif
+#if defined(SWIGPERL)
+ %perlcode {
+ sub solv::XRule::info {
+ my ($self) = @_;
+ my ($type, $source, $target, $dep) = $self->info_helper();
+ $source = $self->{'solv'}->{'pool'}->{'solvables'}->[$source] if $source;
+ $target = $self->{'solv'}->{'pool'}->{'solvables'}->[$target] if $target;
+ return ($type, $source, $target, $dep);
+ }
+ }
+#endif
}
repodata_extend_block(data, data->repo->start, data->repo->end - data->repo->start);
}
}
+