.\" Title: libsolv-bindings
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" Date: 06/05/2013
+.\" Date: 06/06/2013
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "LIBSOLV\-BINDINGS" "3" "06/05/2013" "libsolv" "LIBSOLV"
+.TH "LIBSOLV\-BINDINGS" "3" "06/06/2013" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
libsolv-bindings \- access libsolv from perl/python/ruby
.SH "DESCRIPTION"
.sp
-bla bla bla
-.SH "THE POOL"
+Libsolv\(cqs language bindings offer an abstract, object orientated interface to the library\&. The supported languages are currently perl, python, and ruby\&. All example code (except in the specifics sections, of course) lists first the \(lqC\-ish\(rq interface, then the syntax for perl, python, and ruby (in that order)\&.
+.SH "PERL SPECIFICS"
+.sp
+Libsolv\(cqs perl bindings can be loaded with the following statement:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBuse solv\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Objects are either created by calling the new() method on a class or they are returned by calling methods on other objects\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+my \fI$pool\fR \fB= solv::Pool\->new()\fR;
+my \fI$repo\fR \fB=\fR \fI$pool\fR\fB\->add_repo("my_first_repo")\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Swig encapsulates all objects as tied hashes, thus the attributes can be accessed by treating the object as standard hash reference:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fI$pool\fR\fB\->{appdata} = 42\fR;
+\fBprintf "appdata is %d\en",\fR \fI$pool\fR\fB\->{appdata}\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+An special exception to this are iterator objects, they are encapsulated as tied arrays so that it is possible to iterate with a for() statement:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+my \fI$iter\fR \fB=\fR \fI$pool\fR\fB\->solvables_iter()\fR;
+\fBfor my\fR \fI$solvable\fR \fB(\fR\fI@$iter\fR\fB) { \&.\&.\&. }\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+As a downside of this approach, iterator objects can have no attributes\&.
+.sp
+If an array needs to be passwd to a method it is usually done by reference, if a method returns an array it returns it on the stack:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+my \fI@problems\fR \fB=\fR \fI$solver\fR\fB\->solve(\e\fR\fI@jobs\fR\fB)\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Due to a bug in swig, stringification does not work for libsolv\(cqs object\&. Instead you have to call the object\(cqs str() method\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBprint\fR \fI$dep\fR\fB\->str() \&. "\e\fR\fIn\fR\fB"\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Swig implements all constants as numeric variables (instead of the more natural constant subs), so don\(cqt forget the leading \(lq$\(rq when accessing a constant\&. Also do not forget to prepend the namespace of the constant:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fI$pool\fR\fB\->set_flag($solv::Pool::POOL_FLAG_OBSOLETEUSESCOLORS, 1)\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "PYTHON SPECIFICS"
+.sp
+The python bindings can be loaded with:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBimport solv\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Objects are either created by calling the constructor method for a class or they are returned by calling methods on other objects\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR \fB= solv\&.Pool()\fR
+\fIrepo\fR \fB=\fR \fIpool\fR\fB\&.add_repo("my_first_repo")\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Attributes can be accessed as usual:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR\fB\&.appdata = 42\fR
+\fBprint "appdata is %\fR\fId\fR\fB" % (\fR\fIpool\fR\fB\&.appdata)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Iterators also work as expected:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBfor\fR \fIsolvable\fR \fBin\fR \fIpool\fR\fB\&.solvables_iter():\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Arrays are passed an returned as list objects:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIjobs\fR \fB=\fR \fI[\fR\fB]\fR
+\fIproblems\fR \fB=\fR \fIsolver\fR\fB\&.solve(\fR\fIjobs\fR\fB)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The bindings define stringification for many classes, some also have a \fIrepr\fR method to ease debugging\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBprint\fR \fIdep\fR
+\fBprint repr(\fR\fIrepo\fR\fB)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Constants are attributes of the classes:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR\fB\&.set_flag(solv\&.Pool\&.POOL_FLAG_OBSOLETEUSESCOLORS, 1)\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "RUBY SPECIFICS"
+.sp
+The ruby bindings can be loaded with:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBrequire \*(Aqsolv\*(Aq\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Objects are either created by calling the new method on a class or they are returned by calling methods on other objects\&. Note that all classes start with an uppercase letter in ruby, so the class is called \(lqSolv\(rq\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR \fB= Solv::Pool\&.new\fR
+\fIrepo\fR \fB=\fR \fIpool\fR\fB\&.add_repo("my_first_repo")\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Attributes can be accessed as usual:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR\fB\&.appdata = 42\fR
+\fBputs "appdata is #{\fR\fIpool\fR\fB\&.appdata}"\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Iterators also work as expected:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBfor\fR \fIsolvable\fR \fBin\fR \fIpool\fR\fB\&.solvables_iter() do \&.\&.\&.\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Arrays are passed an returned as array objects:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIjobs\fR \fB=\fR \fI[\fR\fB]\fR
+\fIproblems\fR \fB=\fR \fIsolver\fR\fB\&.solve(\fR\fIjobs\fR\fB)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Most classes define a to_s method, so objects can be easily stringified\&. Many also define an inspect() method\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBputs\fR \fIdep\fR
+\fBputs\fR \fIrepo\fR\fB\&.inspect\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Constants live in the namespace of the class they belong to:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIpool\fR\fB\&.set_flag(Solv::Pool::POOL_FLAG_OBSOLETEUSESCOLORS, 1)\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note that boolean methods have an added trailing \(lq?\(rq, to be consistent with other ruby modules:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBputs "empty\fR \fIrepo\fR\fB" if\fR \fIrepo\fR\fB\&.isempty?\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "THE SOLV CLASS"
+.sp
+This is the main namespace of the library, you cannot create objects of this type but it contains some useful constants\&.
+.SS "CONSTANTS"
+.sp
+Relational flag constants, the first three can be or\-ed together
+.PP
+\fBREL_LT\fR
+.RS 4
+the \(lqless than\(rq bit
+.RE
+.PP
+\fBREL_EQ\fR
+.RS 4
+the \(lqequals to\(rq bit
+.RE
+.PP
+\fBREL_GT\fR
+.RS 4
+the \(lqgreater then\(rq bit
+.RE
+.PP
+\fBREL_ARCH\fR
+.RS 4
+used for relations that describe an extra architecture filter, the version part of the relation is interpreted as architecture\&.
+.RE
+.sp
+Special Solvable Ids
+.PP
+\fBSOLVID_META\fR
+.RS 4
+Access the meta section of a repository or repodata area\&. This is like an extra Solvable that has the Id SOLVID_META\&.
+.RE
+.PP
+\fBSOLVID_POS\fR
+.RS 4
+Use the data position stored inside of the pool instead of accessing some solvable by Id\&. The bindings have the Datapos objects as an abstraction mechanism, so you do not need this constant\&.
+.RE
+.sp
+Constant string Ids
+.PP
+\fBID_NULL\fR
+.RS 4
+Always zero
+.RE
+.PP
+\fBID_EMPTY\fR
+.RS 4
+Always one, describes the empty string
+.RE
+.PP
+\fBSOLVABLE_NAME\fR
+.RS 4
+The keyname Id of the name of the solvable\&.
+.RE
+.PP
+\fB\&...\fR
+.RS 4
+see the libsolv\-knownid manpage for a list of fixed Ids\&.
+.RE
+.SH "THE POOL CLASS"
.sp
The pool is libsolv\(cqs central resource manager\&. A pool consists of Solvables, Repositories, Dependencies, each indexed by Ids\&.
.SS "CLASS METHODS"
.RS 4
.\}
.nf
-\fBRepo *add_repo(const char *\fR\fIname\fR\fB)\fR
+\fBRepo add_repo(const char *\fR\fIname\fR\fB)\fR
\fI$repo\fR \fB=\fR \fI$pool\fR\fB\->add_repo(\fR\fI$name\fR\fB)\fR;
\fIrepo\fR \fB=\fR \fIpool\fR\fB\&.add_repo(\fR\fIname\fR\fB)\fR
\fIrepo\fR \fB=\fR \fIpool\fR\fB\&.add_repo(\fR\fIname\fR\fB)\fR
.RS 4
.\}
.nf
-\fBRepoiterator *repos_iter()\fR
+\fBRepoiterator repos_iter()\fR
\fBfor my\fR \fI$repo\fR \fB(\fR\fI@\fR\fB{\fR\fI$pool\fR\fB\->repos_iter()})\fR
\fBfor\fR \fIrepo\fR \fBin\fR \fIpool\fR\fB\&.repos_iter():\fR
\fBfor\fR \fIrepo\fR \fBin\fR \fIpool\fR\fB\&.repos_iter()\fR
.RS 4
.\}
.nf
-\fBSolvableiterator *solvables_iter()\fR
+\fBSolvableiterator solvables_iter()\fR
\fBfor my\fR \fI$solvable\fR \fB(\fR\fI@\fR\fB{\fR\fI$pool\fR\fB\->solvables_iter()})\fR
\fBfor\fR \fIsolvable\fR \fBin\fR \fIpool\fR\fB\&.solvables_iter():\fR
\fBfor\fR \fIsolvable\fR \fBin\fR \fIpool\fR\fB\&.solvables_iter()\fR
.RS 4
.\}
.nf
-\fBDep *Dep(const char *\fR\fIstr\fR\fB, bool\fR \fIcreate\fR\fB=1)\fR
+\fBDep Dep(const char *\fR\fIstr\fR\fB, bool\fR \fIcreate\fR \fB= 1)\fR
my \fI$dep\fR \fB=\fR \fI$pool\fR\fB\->Dep(\fR\fI$string\fR\fB)\fR;
\fIdep\fR \fB=\fR \fIpool\fR\fB\&.Dep(\fR\fIstring\fR\fB)\fR
\fIdep\fR \fB=\fR \fIpool\fR\fB\&.Dep(\fR\fIstring\fR\fB)\fR
.RS 4
.\}
.nf
-\fBQueue addfileprovides_queue()\fR
+\fBId *addfileprovides_queue()\fR
my \fI@ids\fR \fB=\fR \fI$pool\fR\fB\->addfileprovides_queue()\fR;
\fIids\fR \fB=\fR \fIpool\fR\fB\&.addfileprovides_queue()\fR
\fIids\fR \fB=\fR \fIpool\fR\fB\&.addfileprovides_queue()\fR
.RE
.\}
.sp
-Some package managers like rpm allow dependencies on files contained in other packages\&. To allow libsolv to deal with those dependencies in an efficient way, you need to call the addfileprovides method after creating and reading all repositories\&. This method will scan all dependency for file names and than scan all packages for matching files\&. If a filename has been matched, it will be added to the provides list of the corresponding package\&. The addfileprovides_queue variant works the same way but returns an array containing all file dependencies\&. This information can be stored with the repository to speed up the next usage of the repository\&.
+Some package managers like rpm allow dependencies on files contained in other packages\&. To allow libsolv to deal with those dependencies in an efficient way, you need to call the addfileprovides method after creating and reading all repositories\&. This method will scan all dependency for file names and than scan all packages for matching files\&. If a filename has been matched, it will be added to the provides list of the corresponding package\&. The addfileprovides_queue variant works the same way but returns an array containing all file dependencies\&. This information can be stored in the meta section of the repositories to speed up the next time the repository is loaded and addfileprovides is called\&.
.sp
.if n \{\
.RS 4
.RS 4
.\}
.nf
-\fBQueue whatprovides(DepId\fR \fIdep\fR\fB)\fR
+\fBSolvable *whatprovides(DepId\fR \fIdep\fR\fB)\fR
my \fI@solvables\fR \fB=\fR \fI$pool\fR\fB\->whatprovides(\fR\fI$dep\fR\fB)\fR;
\fIsolvables\fR \fB=\fR \fIpool\fR\fB\&.whatprovides(\fR\fIdep\fR\fB)\fR
\fIsolvables\fR \fB=\fR \fIpool\fR\fB\&.whatprovides(\fR\fIdep\fR\fB)\fR
.RS 4
.\}
.nf
-\fBQueue matchprovidingids(const char *\fR\fImatch\fR\fB, int\fR \fIflags\fR\fB)\fR
+\fBId *matchprovidingids(const char *\fR\fImatch\fR\fB, int\fR \fIflags\fR\fB)\fR
my \fI@ids\fR \fB=\fR \fI$pool\fR\fB\->matchprovidingids(\fR\fI$match\fR\fB,\fR \fI$flags\fR\fB)\fR;
\fIids\fR \fB=\fR \fIpool\fR\fB\&.matchprovidingids(\fR\fImatch\fR\fB,\fR \fIflags\fR\fB)\fR
\fIids\fR \fB=\fR \fIpool\fR\fB\&.matchprovidingids(\fR\fImatch\fR\fB,\fR \fIflags\fR\fB)\fR
.RS 4
.\}
.nf
-\fBId towhatprovides(Queue\fR \fIids\fR\fB)\fR
+\fBId towhatprovides(Id *\fR\fIids\fR\fB)\fR
my \fI$offset\fR \fB=\fR \fI$pool\fR\fB\->towhatprovides(\e\fR\fI@ids\fR\fB)\fR;
\fIoffset\fR \fB=\fR \fIpool\fR\fB\&.towhatprovides(\fR\fIids\fR\fB)\fR
\fIoffset\fR \fB=\fR \fIpool\fR\fB\&.towhatprovides(\fR\fIids\fR\fB)\fR
.RS 4
.\}
.nf
-\fBSolver *Solver()\fR
+\fBSolver Solver()\fR
my \fI$solver\fR \fB=\fR \fI$pool\fR\fB\->Solver()\fR;
\fIsolver\fR \fB=\fR \fIpool\fR\fB\&.Solver()\fR
\fIsolver\fR \fB=\fR \fIpool\fR\fB\&.Solver()\fR
.RS 4
.\}
.nf
-\fBSolver *Job(int\fR \fIhow\fR\fB, Id\fR \fIwhat\fR\fB)\fR
+\fBJob Job(int\fR \fIhow\fR\fB, Id\fR \fIwhat\fR\fB)\fR
my \fI$job\fR \fB=\fR \fI$pool\fR\fB\->Job(\fR\fI$how\fR\fB,\fR \fI$what\fR\fB)\fR;
\fIjob\fR \fB=\fR \fIpool\fR\fB\&.Job(\fR\fIhow\fR\fB,\fR \fIwhat\fR\fB)\fR
\fIjob\fR \fB=\fR \fIpool\fR\fB\&.Job(\fR\fIhow\fR\fB,\fR \fIwhat\fR\fB)\fR
.RS 4
.\}
.nf
-\fBSelection *Selection()\fR
+\fBSelection Selection()\fR
my \fI$sel\fR \fB=\fR \fI$pool\fR\fB\->Selection()\fR;
\fIsel\fR \fB=\fR \fIpool\fR\fB\&.Selection()\fR
\fIsel\fR \fB=\fR \fIpool\fR\fB\&.Selection()\fR
.RS 4
.\}
.nf
-\fBSelection *Selection_all()\fR
+\fBSelection Selection_all()\fR
my \fI$sel\fR \fB=\fR \fI$pool\fR\fB\->Selection_all()\fR;
\fIsel\fR \fB=\fR \fIpool\fR\fB\&.Selection_all()\fR
\fIsel\fR \fB=\fR \fIpool\fR\fB\&.Selection_all()\fR
.RS 4
.\}
.nf
-\fBSelection *select(const char *\fR\fIname\fR\fB, int\fR \fIflags\fR\fB)\fR
+\fBSelection select(const char *\fR\fIname\fR\fB, int\fR \fIflags\fR\fB)\fR
my \fI$sel\fR \fB=\fR \fI$pool\fR\fB\->select(\fR\fI$name\fR\fB,\fR \fI$flags\fR\fB)\fR;
\fIsel\fR \fB=\fR \fIpool\fR\fB\&.select(\fR\fIname\fR\fB,\fR \fIflags\fR\fB)\fR
\fIsel\fR \fB=\fR \fIpool\fR\fB\&.select(\fR\fIname\fR\fB,\fR \fIflags\fR\fB)\fR
.RS 4
.\}
.nf
-\fBJobs *getpooljobs()\fR
+\fBJob *getpooljobs()\fR
\fI@jobs\fR \fB=\fR \fI$pool\fR\fB\->getpooljobs()\fR;
\fIjobs\fR \fB=\fR \fIpool\fR\fB\&.getpooljobs()\fR
\fIjobs\fR \fB=\fR \fIpool\fR\fB\&.getpooljobs()\fR
.RS 4
.\}
.nf
-\fBQueue lookup_idarray(Id\fR \fIsolvid\fR\fB, Id\fR \fIkeyname\fR\fB)\fR
+\fBId *lookup_idarray(Id\fR \fIsolvid\fR\fB, Id\fR \fIkeyname\fR\fB)\fR
my \fI@ids\fR \fB=\fR \fI$pool\fR\fB\->lookup_idarray(\fR\fI$solvid\fR\fB,\fR \fI$keyname\fR\fB)\fR;
\fIids\fR \fB=\fR \fIpool\fR\fB\&.lookup_idarray(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB)\fR
\fIids\fR \fB=\fR \fIpool\fR\fB\&.lookup_idarray(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB)\fR
.RS 4
.\}
.nf
-\fBChksum *lookup_checksum(Id\fR \fIsolvid\fR\fB, Id\fR \fIkeyname\fR\fB)\fR
+\fBChksum lookup_checksum(Id\fR \fIsolvid\fR\fB, Id\fR \fIkeyname\fR\fB)\fR
my \fI$chksum\fR \fB=\fR \fI$pool\fR\fB\->lookup_checksum(\fR\fI$solvid\fR\fB,\fR \fI$keyname\fR\fB)\fR;
\fIchksum\fR \fB=\fR \fIpool\fR\fB\&.lookup_checksum(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB)\fR
\fIchksum\fR \fB=\fR \fIpool\fR\fB\&.lookup_checksum(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB)\fR
.RS 4
.\}
.nf
-\fBDataiterator *Dataiterator(Id\fR \fIsolvid\fR\fB, Id\fR \fIkeyname\fR\fB, const char *\fR\fImatch\fR\fB, int\fR \fIflags\fR\fB)\fR
+\fBDataiterator Dataiterator(Id\fR \fIsolvid\fR\fB, Id\fR \fIkeyname\fR\fB, const char *\fR\fImatch\fR\fB, int\fR \fIflags\fR\fB)\fR
my \fI$di\fR \fB=\fR \fI$pool\fR\fB\->Dataiterator(\fR\fI$solvid\fR\fB,\fR \fI$keyname\fR\fB,\fR \fI$match\fR\fB,\fR \fI$flags\fR\fB)\fR;
\fIdi\fR \fB=\fR \fIpool\fR\fB\&.Dataiterator(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB,\fR \fImatch\fR\fB,\fR \fIflags\fR\fB)\fR
\fIdi\fR \fB=\fR \fIpool\fR\fB\&.Dataiterator(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB,\fR \fImatch\fR\fB,\fR \fIflags\fR\fB)\fR
.RS 4
.\}
.nf
-\fBRepo *id2repo(Id\fR \fIid\fR\fB)\fR
+\fBRepo id2repo(Id\fR \fIid\fR\fB)\fR
\fI$repo\fR \fB=\fR \fI$pool\fR\fB\->id2repo(\fR\fI$id\fR\fB)\fR;
\fIrepo\fR \fB=\fR \fIpool\fR\fB\&.id2repo(\fR\fIid\fR\fB)\fR
\fIrepo\fR \fB=\fR \fIpool\fR\fB\&.id2repo(\fR\fIid\fR\fB)\fR
.RS 4
.\}
.nf
-\fBSolvable *id2solvable(Id\fR \fIid\fR\fB)\fR
+\fBSolvable id2solvable(Id\fR \fIid\fR\fB)\fR
\fI$solvable\fR \fB=\fR \fI$pool\fR\fB\->id2solvable(\fR\fI$id\fR\fB)\fR;
\fIsolvable\fR \fB=\fR \fIpool\fR\fB\&.id2solvable(\fR\fIid\fR\fB)\fR
\fIsolvable\fR \fB=\fR \fIpool\fR\fB\&.id2solvable(\fR\fIid\fR\fB)\fR
.RS 4
.\}
.nf
-\fBId str2id(const char *\fR\fIstr\fR\fB, bool\fR \fIcreate\fR\fB=1)\fR
+\fBId str2id(const char *\fR\fIstr\fR\fB, bool\fR \fIcreate\fR \fB= 1)\fR
my \fI$id\fR \fB=\fR \fIpool\fR\fB\->str2id(\fR\fI$string\fR\fB)\fR;
\fIid\fR \fB=\fR \fIpool\fR\fB\&.str2id(\fR\fIstring\fR\fB)\fR
\fIid\fR \fB=\fR \fIpool\fR\fB\&.str2id(\fR\fIstring\fR\fB)\fR
.RS 4
.\}
.nf
-\fBId rel2id(Id\fR \fIname\fR\fB, Id\fR \fIevr\fR\fB, int\fR \fIflags\fR\fB, bool\fR \fIcreate\fR\fB=1)\fR
+\fBId rel2id(Id\fR \fIname\fR\fB, Id\fR \fIevr\fR\fB, int\fR \fIflags\fR\fB, bool\fR \fIcreate\fR \fB= 1)\fR
my \fI$id\fR \fB=\fR \fIpool\fR\fB\->rel2id(\fR\fI$nameid\fR\fB,\fR \fI$evrid\fR\fB,\fR \fI$flags\fR\fB)\fR;
\fIid\fR \fB=\fR \fIpool\fR\fB\&.rel2id(\fR\fInameid\fR\fB,\fR \fIevrid\fR\fB,\fR \fIflags\fR\fB)\fR
\fIid\fR \fB=\fR \fIpool\fR\fB\&.rel2id(\fR\fInameid\fR\fB,\fR \fIevrid\fR\fB,\fR \fIflags\fR\fB)\fR
.RS 4
.\}
.nf
-\fBId id2langid(Id\fR \fIid\fR\fB, const char *\fR\fIlang\fR\fB, bool\fR \fIcreate\fR\fB=1)\fR
+\fBId id2langid(Id\fR \fIid\fR\fB, const char *\fR\fIlang\fR\fB, bool\fR \fIcreate\fR \fB= 1)\fR
my \fI$id\fR \fB=\fR \fI$pool\fR\fB\->id2langid(\fR\fI$id\fR\fB,\fR \fI$language\fR\fB)\fR;
\fIid\fR \fB=\fR \fIpool\fR\fB\&.id2langid(\fR\fIid\fR\fB,\fR \fIlanguage\fR\fB)\fR
\fIid\fR \fB=\fR \fIpool\fR\fB\&.id2langid(\fR\fIid\fR\fB,\fR \fIlanguage\fR\fB)\fR
.RS 4
.\}
.nf
-\fBDep *Rel(int\fR \fIflags\fR\fB, DepId\fR \fIevrid\fR\fB, bool\fR \fIcreate\fR\fB=1)\fR
+\fBDep Rel(int\fR \fIflags\fR\fB, DepId\fR \fIevrid\fR\fB, bool\fR \fIcreate\fR \fB= 1)\fR
my \fI$reldep\fR \fB=\fR \fI$dep\fR\fB\->Rel(\fR\fI$flags\fR\fB,\fR \fI$evrdep\fR\fB)\fR;
\fIreldep\fR \fB=\fR \fIdep\fR\fB\&.Rel(\fR\fIflags\fR\fB,\fR \fIevrdep\fR\fB)\fR
\fIreldep\fR \fB=\fR \fIdep\fR\fB\&.Rel(\fR\fIflags\fR\fB,\fR \fIevrdep\fR\fB)\fR
.RS 4
.\}
.nf
-\fBSelection *Selection_name(int\fR \fIsetflags\fR \fB= 0)\fR
+\fBSelection Selection_name(int\fR \fIsetflags\fR \fB= 0)\fR
my \fI$sel\fR \fB=\fR \fI$dep\fR\fB\->Selection_name()\fR;
\fIsel\fR \fB=\fR \fIdep\fR\fB\&.Selection_name()\fR
\fIsel\fR \fB=\fR \fIdep\fR\fB\&.Selection_name()\fR
.RS 4
.\}
.nf
-\fBSelection *Selection_provides(int\fR \fIsetflags\fR \fB= 0)\fR
+\fBSelection Selection_provides(int\fR \fIsetflags\fR \fB= 0)\fR
my \fI$sel\fR \fB=\fR \fI$dep\fR\fB\->Selection_provides()\fR;
\fIsel\fR \fB=\fR \fIdep\fR\fB\&.Selection_provides()\fR
\fIsel\fR \fB=\fR \fIdep\fR\fB\&.Selection_provides()\fR
.RS 4
.\}
.nf
-\fBSolvableiterator *solvables_iter()\fR
+\fBSolvableiterator solvables_iter()\fR
\fBfor my\fR \fI$solvable\fR \fB(\fR\fI@\fR\fB{\fR\fI$repo\fR\fB\->solvables_iter()})\fR
\fBfor\fR \fIsolvable\fR \fBin\fR \fIrepo\fR\fB\&.solvables_iter():\fR
\fBfor\fR \fIsolvable\fR \fBin\fR \fIrepo\fR\fB\&.solvables_iter()\fR
.RS 4
.\}
.nf
-\fBRepodata *add_repodata(int\fR \fIflags\fR \fB= 0)\fR
+\fBRepodata add_repodata(int\fR \fIflags\fR \fB= 0)\fR
my \fI$repodata\fR \fB=\fR \fI$repo\fR\fB\->add_repodata()\fR;
\fIrepodata\fR \fB=\fR \fIrepo\fR\fB\&.add_repodata()\fR
\fIrepodata\fR \fB=\fR \fIrepo\fR\fB\&.add_repodata()\fR
.RS 4
.\}
.nf
-\fBRepodata *first_repodata()\fR
+\fBRepodata first_repodata()\fR
my \fI$repodata\fR \fB=\fR \fI$repo\fR\fB\->first_repodata()\fR;
\fIrepodata\fR \fB=\fR \fIrepo\fR\fB\&.first_repodata()\fR
\fIrepodata\fR \fB=\fR \fIrepo\fR\fB\&.first_repodata()\fR
.RS 4
.\}
.nf
-\fBSelection *Selection(int\fR \fIsetflags\fR \fB= 0)\fR
+\fBSelection Selection(int\fR \fIsetflags\fR \fB= 0)\fR
my \fI$sel\fR \fB=\fR \fI$repo\fR\fB\->Selection()\fR;
\fIsel\fR \fB=\fR \fIrepo\fR\fB\&.Selection()\fR
\fIsel\fR \fB=\fR \fIrepo\fR\fB\&.Selection()\fR
.RS 4
.\}
.nf
-\fBDataiterator *Dataiterator(Id\fR \fIp\fR\fB, Id\fR \fIkey\fR\fB, const char *\fR\fImatch\fR\fB, int\fR \fIflags\fR\fB)\fR
+\fBDataiterator Dataiterator(Id\fR \fIp\fR\fB, Id\fR \fIkey\fR\fB, const char *\fR\fImatch\fR\fB, int\fR \fIflags\fR\fB)\fR
my \fI$di\fR \fB=\fR \fI$repo\fR\fB\->Dataiterator(\fR\fI$solvid\fR\fB,\fR \fI$keyname\fR\fB,\fR \fI$match\fR\fB,\fR \fI$flags\fR\fB)\fR;
\fIdi\fR \fB=\fR \fIrepo\fR\fB\&.Dataiterator(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB,\fR \fImatch\fR\fB,\fR \fIflags\fR\fB)\fR
\fIdi\fR \fB=\fR \fIrepo\fR\fB\&.Dataiterator(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB,\fR \fImatch\fR\fB,\fR \fIflags\fR\fB)\fR
.RS 4
.\}
.nf
-\fBSolvable *add_solvable()\fR
+\fBSolvable add_solvable()\fR
\fI$repo\fR\fB\->add_solvable()\fR;
\fIrepo\fR\fB\&.add_solvable()\fR
\fIrepo\fR\fB\&.add_solvable()\fR
.RS 4
.\}
.nf
-\fBChksum *lookup_checksum(Id\fR \fIkeyname\fR\fB)\fR
+\fBChksum lookup_checksum(Id\fR \fIkeyname\fR\fB)\fR
my \fI$chksum\fR \fB=\fR \fI$solvable\fR\fB\->lookup_checksum(\fR\fI$keyname\fR\fB)\fR;
\fIchksum\fR \fB=\fR \fIsolvable\fR\fB\&.lookup_checksum(\fR\fIkeyname\fR\fB)\fR
\fIchksum\fR \fB=\fR \fIsolvable\fR\fB\&.lookup_checksum(\fR\fIkeyname\fR\fB)\fR
.RS 4
.\}
.nf
-\fBQueue lookup_idarray(Id\fR \fIkeyname\fR\fB, Id\fR \fImarker\fR \fB= \-1)\fR
+\fBId *lookup_idarray(Id\fR \fIkeyname\fR\fB, Id\fR \fImarker\fR \fB= \-1)\fR
my \fI@ids\fR \fB=\fR \fI$solvable\fR\fB\->lookup_idarray(\fR\fI$keyname\fR\fB)\fR;
\fIids\fR \fB=\fR \fIsolvable\fR\fB\&.lookup_idarray(\fR\fIkeyname\fR\fB)\fR
\fIids\fR \fB=\fR \fIsolvable\fR\fB\&.lookup_idarray(\fR\fIkeyname\fR\fB)\fR
.RS 4
.\}
.nf
-\fBQueue lookup_deparray(Id\fR \fIkeyname\fR\fB, Id\fR \fImarker\fR \fB= \-1)\fR
+\fBDep *lookup_deparray(Id\fR \fIkeyname\fR\fB, Id\fR \fImarker\fR \fB= \-1)\fR
my \fI@deps\fR \fB=\fR \fI$solvable\fR\fB\->lookup_deparray(\fR\fI$keyname\fR\fB)\fR;
\fIdeps\fR \fB=\fR \fIsolvable\fR\fB\&.lookup_deparray(\fR\fIkeyname\fR\fB)\fR
\fIdeps\fR \fB=\fR \fIsolvable\fR\fB\&.lookup_deparray(\fR\fIkeyname\fR\fB)\fR
.RS 4
.\}
.nf
-\fBSelection *Selection(int\fR \fIsetflags\fR \fB= 0)\fR
+\fBSelection Selection(int\fR \fIsetflags\fR \fB= 0)\fR
my \fI$sel\fR \fB=\fR \fI$solvable\fR\fB\->Selection()\fR;
\fIsel\fR \fB=\fR \fIsolvable\fR\fB\&.Selection()\fR
\fIsel\fR \fB=\fR \fIsolvable\fR\fB\&.Selection()\fR
.RS 4
.\}
.nf
-\fBDatapos *pos()\fR;
+\fBDatapos pos()\fR;
my \fI$pos\fR \fB=\fR \fI$d\fR\fB\->pos()\fR;
\fIpos\fR \fB=\fR \fId\fR\fB\&.pos()\fR
\fIpos\fR \fB=\fR \fId\fR\fB\&.pos()\fR
.RS 4
.\}
.nf
-\fBDatapos *parentpos()\fR;
+\fBDatapos parentpos()\fR;
my \fI$pos\fR \fB=\fR \fI$d\fR\fB\->parentpos()\fR;
\fIpos\fR \fB=\fR \fId\fR\fB\&.parentpos()\fR
\fIpos\fR \fB=\fR \fId\fR\fB\&.parentpos()\fR
.RS 4
.\}
.nf
-\fBJob **jobs(int\fR \fIaction\fR\fB)\fR
+\fBJob *jobs(int\fR \fIaction\fR\fB)\fR
my \fI@jobs\fR \fB=\fR \fI$sel\fR\fB\->jobs(\fR\fI$action\fR\fB)\fR;
\fIjobs\fR \fB=\fR \fIsel\fR\fB\&.jobs(\fR\fIaction\fR\fB)\fR
\fIjobs\fR \fB=\fR \fIsel\fR\fB\&.jobs(\fR\fIaction\fR\fB)\fR
.RS 4
.\}
.nf
-\fBSolvable **solvables()\fR
+\fBSolvable *solvables()\fR
my \fI@solvables\fR \fB=\fR \fI$sel\fR\fB\->solvables()\fR;
\fIsolvables\fR \fB=\fR \fIsel\fR\fB\&.solvables()\fR
\fIsolvables\fR \fB=\fR \fIsel\fR\fB\&.solvables()\fR
.RS 4
.\}
.nf
-\fBSolvable **solvables()\fR
+\fBSolvable *solvables()\fR
my \fI@solvables\fR \fB=\fR \fI$job\fR\fB\->solvables()\fR;
\fIsolvables\fR \fB=\fR \fIjob\fR\fB\&.solvables()\fR
\fIsolvables\fR \fB=\fR \fIjob\fR\fB\&.solvables()\fR
.sp
So if a package "screen\-1\-1" is installed for the x86_64 architecture and version "2\-1" is only available for the i586 architecture, installing package "screen\-2\&.1" will ask the user for confirmation because of the different architecture\&. When using the Selection class to create jobs the set bits are automatically added, e\&.g\&. selecting \(lqscreen\&.i586\(rq will automatically add SOLVER_SETARCH, and thus no problem will be reported\&.
.SH "THE SOLVER CLASS"
+.sp
+Dependency solving is what this library is about\&. A solver object is needed for solving to store the result of the solver run\&. The solver object can be used multiple times for different jobs, reusing it allows the solver to re\-use the dependency rules it already computed\&.
.SS "CONSTANTS"
.sp
Flags to modify some of the solver\(cqs behaviour:
.RS 4
.\}
.nf
-\fBProblem **solve(Job *\fR\fIjobs\fR\fB)\fR
+\fBProblem *solve(Job *\fR\fIjobs\fR\fB)\fR
my \fI@problems\fR \fB=\fR \fI$solver\fR\fB\->solve(\e\fR\fI@jobs\fR\fB)\fR;
\fIproblems\fR \fB=\fR \fIsolver\fR\fB\&.solve(\fR\fIjobs\fR\fB)\fR
\fIproblems\fR \fB=\fR \fIsolver\fR\fB\&.solve(\fR\fIjobs\fR\fB)\fR
.RS 4
.\}
.nf
-\fBTransaction *transaction()\fR
+\fBTransaction transaction()\fR
my \fI$trans\fR \fB=\fR \fI$solver\fR\fB\->transaction()\fR;
\fItrans\fR \fB=\fR \fIsolver\fR\fB\&.transaction()\fR
\fItrans\fR \fB=\fR \fIsolver\fR\fB\&.transaction()\fR
.RS 4
.\}
.nf
-\fBRule *findproblemrule()\fR
+\fBRule findproblemrule()\fR
my \fI$probrule\fR \fB=\fR \fI$problem\fR\fB\->findproblemrule()\fR;
\fIprobrule\fR \fB=\fR \fIproblem\fR\fB\&.findproblemrule()\fR
\fIprobrule\fR \fB=\fR \fIproblem\fR\fB\&.findproblemrule()\fR
.RS 4
.\}
.nf
-\fBRule **findallproblemrules(bool\fR \fIunfiltered\fR \fB= 0)\fR
+\fBRule *findallproblemrules(bool\fR \fIunfiltered\fR \fB= 0)\fR
my \fI@probrules\fR \fB=\fR \fI$problem\fR\fB\->findallproblemrules()\fR;
\fIprobrules\fR \fB=\fR \fIproblem\fR\fB\&.findallproblemrule()\fR
\fIprobrules\fR \fB=\fR \fIproblem\fR\fB\&.findallproblemrule()\fR
.RS 4
.\}
.nf
-\fBSolutions **solutions()\fR
+\fBSolution *solutions()\fR
my \fI@solutions\fR \fB=\fR \fI$problem\fR\fB\->solutions()\fR;
\fIsolutions\fR \fB=\fR \fIproblem\fR\fB\&.solutions()\fR
\fIsolutions\fR \fB=\fR \fIproblem\fR\fB\&.solutions()\fR
.RS 4
.\}
.nf
-\fBRuleinfo *info()\fR
+\fBRuleinfo info()\fR
my \fI$ruleinfo\fR \fB=\fR \fI$rule\fR\fB\->info()\fR;
\fIruleinfo\fR \fB=\fR \fIrule\fR\fB\&.info()\fR
\fIruleinfo\fR \fB=\fR \fIrule\fR\fB\&.info()\fR
.RS 4
.\}
.nf
-\fBRuleinfo **allinfos()\fR
+\fBRuleinfo *allinfos()\fR
my \fI@ruleinfos\fR \fB=\fR \fI$rule\fR\fB\->allinfos()\fR;
\fIruleinfos\fR \fB=\fR \fIrule\fR\fB\&.allinfos()\fR
\fIruleinfos\fR \fB=\fR \fIrule\fR\fB\&.allinfos()\fR
.RS 4
.\}
.nf
-\fBSolutionelement **elements(bool\fR \fIexpandreplaces\fR \fB= 0)\fR
+\fBSolutionelement *elements(bool\fR \fIexpandreplaces\fR \fB= 0)\fR
my \fI@solutionelements\fR \fB=\fR \fI$solution\fR\fB\->elements()\fR;
\fIsolutionelements\fR \fB=\fR \fIsolution\fR\fB\&.elements()\fR
\fIsolutionelements\fR \fB=\fR \fIsolution\fR\fB\&.elements()\fR
.RS 4
.\}
.nf
-\fBSolutionelement **replaceelements()\fR
+\fBSolutionelement *replaceelements()\fR
my \fI@solutionelements\fR \fB=\fR \fI$solutionelement\fR\fB\->replaceelements()\fR;
\fIsolutionelements\fR \fB=\fR \fIsolutionelement\fR\fB\&.replaceelements()\fR
\fIsolutionelements\fR \fB=\fR \fIsolutionelement\fR\fB\&.replaceelements()\fR
.RS 4
.\}
.nf
-\fBJob *Job()\fR
+\fBJob Job()\fR
my \fI$job\fR \fB=\fR \fI$solutionelement\fR\fB\->Job()\fR;
\fIillegal\fR \fB=\fR \fIsolutionelement\fR\fB\&.Job()\fR
\fIillegal\fR \fB=\fR \fIsolutionelement\fR\fB\&.Job()\fR
.sp
A string describing the change the solution element consists of\&.
.SH "THE TRANSACTION CLASS"
+.sp
+Transactions describe the output of a solver run\&. A transaction contains a number of transaction elements, each either the installation of a new package or the removal of an already installed package\&. The Transaction class supports a classify() method that puts the elements into different groups so that a transaction can be presented to the user in a meaningful way\&.
.SS "CONSTANTS"
.sp
Transaction element types, both active and passive
.RS 4
.\}
.nf
-\fBSolvable **newpackages()\fR;
+\fBSolvable *newpackages()\fR;
my \fI@newsolvables\fR \fB=\fR \fI$trans\fR\fB\->newpackages()\fR;
\fInewsolvables\fR \fB=\fR \fItrans\fR\fB\&.newpackages()\fR
\fInewsolvables\fR \fB=\fR \fItrans\fR\fB\&.newpackages()\fR
.RS 4
.\}
.nf
-\fBSolvable **keptpackages()\fR;
+\fBSolvable *keptpackages()\fR;
my \fI@keptsolvables\fR \fB=\fR \fI$trans\fR\fB\->keptpackages()\fR;
\fIkeptsolvables\fR \fB=\fR \fItrans\fR\fB\&.keptpackages()\fR
\fIkeptsolvables\fR \fB=\fR \fItrans\fR\fB\&.keptpackages()\fR
.RS 4
.\}
.nf
-\fBSolvable **steps()\fR;
+\fBSolvable *steps()\fR;
my \fI@steps\fR \fB=\fR \fI$trans\fR\fB\->steps()\fR;
\fIsteps\fR \fB=\fR \fItrans\fR\fB\&.steps()\fR
\fIsteps\fR \fB=\fR \fItrans\fR\fB\&.steps()\fR
.RS 4
.\}
.nf
-\fBTransactionClass **classify(int\fR \fImode\fR \fB= 0)\fR
+\fBTransactionClass *classify(int\fR \fImode\fR \fB= 0)\fR
my \fI@classes\fR \fB=\fR \fI$trans\fR\fB\->classify()\fR;
\fIclasses\fR \fB=\fR \fItrans\fR\fB\&.classify()\fR
\fIclasses\fR \fB=\fR \fItrans\fR\fB\&.classify()\fR
.RS 4
.\}
.nf
-\fBSolvable *othersolvable(Solvable *\fR\fIsolvable\fR\fB)\fR;
+\fBSolvable othersolvable(Solvable *\fR\fIsolvable\fR\fB)\fR;
my \fI$other\fR \fB=\fR \fI$trans\fR\fB\->othersolvable(\fR\fI$solvable\fR\fB)\fR;
\fIother\fR \fB=\fR \fItrans\fR\fB\&.othersolvable(\fR\fIsolvable\fR\fB)\fR
\fIother\fR \fB=\fR \fItrans\fR\fB\&.othersolvable(\fR\fIsolvable\fR\fB)\fR
.RS 4
.\}
.nf
-\fBSolvable **allothersolvables(Solvable *\fR\fIsolvable\fR\fB)\fR;
+\fBSolvable *allothersolvables(Solvable *\fR\fIsolvable\fR\fB)\fR;
my \fI@others\fR \fB=\fR \fI$trans\fR\fB\->allothersolvables(\fR\fI$solvable\fR\fB)\fR;
\fIothers\fR \fB=\fR \fItrans\fR\fB\&.allothersolvables(\fR\fIsolvable\fR\fB)\fR
\fIothers\fR \fB=\fR \fItrans\fR\fB\&.allothersolvables(\fR\fIsolvable\fR\fB)\fR
.RS 4
.\}
.nf
-\fBChksum *Chksum(Id\fR \fItype\fR\fB)\fR
+\fBChksum Chksum(Id\fR \fItype\fR\fB)\fR
my \fI$chksum\fR \fB= solv::Chksum\->new(\fR\fI$type\fR\fB)\fR;
\fIchksum\fR \fB= solv\&.Chksum(\fR\fItype\fR\fB)\fR
\fIchksum\fR \fB= Solv::Chksum\&.new(\fR\fItype\fR\fB)\fR
.RS 4
.\}
.nf
-\fBChksum *Chksum(Id\fR \fItype\fR\fB, const char *\fR\fIhex\fR\fB)\fR
+\fBChksum Chksum(Id\fR \fItype\fR\fB, const char *\fR\fIhex\fR\fB)\fR
my \fI$chksum\fR \fB= solv::Chksum\->new(\fR\fI$type\fR\fB,\fR \fI$hex\fR\fB)\fR;
\fIchksum\fR \fB= solv\&.Chksum(\fR\fItype\fR\fB,\fR \fIhex\fR\fB)\fR
\fIchksum\fR \fB= Solv::Chksum\&.new(\fR\fItype\fR\fB,\fR \fIhex\fR\fB)\fR
.RS 4
.\}
.nf
-\fBChksum *lookup_checksum(Id\fR \fIsolvid\fR\fB, Id\fR \fIkeyname\fR\fB)\fR
+\fBChksum lookup_checksum(Id\fR \fIsolvid\fR\fB, Id\fR \fIkeyname\fR\fB)\fR
my \fI$chksum\fR \fB=\fR \fI$data\fR\fB\->lookup_checksum(\fR\fI$solvid\fR\fB,\fR \fI$keyname\fR\fB)\fR;
\fIchksum\fR \fB=\fR \fIdata\fR\fB\&.lookup_checksum(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB)\fR
\fIchksum\fR \fB=\fR \fIdata\fR\fB\&.lookup_checksum(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB)\fR
.RS 4
.\}
.nf
-\fBQueue lookup_idarray(Id\fR \fIkeyname\fR\fB)\fR
+\fBId *lookup_idarray(Id\fR \fIkeyname\fR\fB)\fR
my \fI@ids\fR \fB=\fR \fI$datapos\fR\fB\->lookup_idarray(\fR\fI$keyname\fR\fB)\fR;
\fIids\fR \fB=\fR \fIdatapos\fR\fB\&.lookup_idarray(\fR\fIkeyname\fR\fB)\fR
\fIids\fR \fB=\fR \fIdatapos\fR\fB\&.lookup_idarray(\fR\fIkeyname\fR\fB)\fR
.RS 4
.\}
.nf
-\fBChksum *lookup_checksum(Id\fR \fIkeyname\fR\fB)\fR
+\fBChksum lookup_checksum(Id\fR \fIkeyname\fR\fB)\fR
my \fI$chksum\fR \fB=\fR \fI$datapos\fR\fB\->lookup_checksum(\fR\fI$keyname\fR\fB)\fR;
\fIchksum\fR \fB=\fR \fIdatapos\fR\fB\&.lookup_checksum(\fR\fIkeyname\fR\fB)\fR
\fIchksum\fR \fB=\fR \fIdatapos\fR\fB\&.lookup_checksum(\fR\fIkeyname\fR\fB)\fR
----
libsolv-bindings - access libsolv from perl/python/ruby
+
DESCRIPTION
-----------
-bla bla bla
+Libsolv's language bindings offer an abstract, object orientated interface
+to the library. The supported languages are currently perl, python, and ruby.
+All example code (except in the specifics sections, of course) lists first
+the ``C-ish'' interface, then the syntax for perl, python, and ruby (in that
+order).
+
+
+PERL SPECIFICS
+--------------
+Libsolv's perl bindings can be loaded with the following statement:
+
+ use solv;
+
+Objects are either created by calling the new() method on a class or they
+are returned by calling methods on other objects.
+
+ my $pool = solv::Pool->new();
+ my $repo = $pool->add_repo("my_first_repo");
+
+Swig encapsulates all objects as tied hashes, thus the attributes can be
+accessed by treating the object as standard hash reference:
+
+ $pool->{appdata} = 42;
+ printf "appdata is %d\n", $pool->{appdata};
+
+An special exception to this are iterator objects, they are encapsulated as
+tied arrays so that it is possible to iterate with a for() statement:
+
+ my $iter = $pool->solvables_iter();
+ for my $solvable (@$iter) { ... };
+
+As a downside of this approach, iterator objects can have no attributes.
+
+If an array needs to be passwd to a method it is usually done by reference,
+if a method returns an array it returns it on the stack:
+
+ my @problems = $solver->solve(\@jobs);
+
+Due to a bug in swig, stringification does not work for libsolv's object.
+Instead you have to call the object's str() method.
+
+ print $dep->str() . "\n";
+
+Swig implements all constants as numeric variables (instead of the more
+natural constant subs), so don't forget the leading ``$'' when accessing a
+constant. Also do not forget to prepend the namespace of the constant:
+
+ $pool->set_flag($solv::Pool::POOL_FLAG_OBSOLETEUSESCOLORS, 1);
+
+
+PYTHON SPECIFICS
+----------------
+The python bindings can be loaded with:
+
+ import solv
+
+Objects are either created by calling the constructor method for a class or they
+are returned by calling methods on other objects.
+
+ pool = solv.Pool()
+ repo = pool.add_repo("my_first_repo")
+
+Attributes can be accessed as usual:
+
+ pool.appdata = 42
+ print "appdata is %d" % (pool.appdata)
+
+Iterators also work as expected:
+
+ for solvable in pool.solvables_iter():
+
+Arrays are passed an returned as list objects:
+
+ jobs = []
+ problems = solver.solve(jobs)
+
+The bindings define stringification for many classes, some also have a
+__repr__ method to ease debugging.
+
+ print dep
+ print repr(repo)
+
+Constants are attributes of the classes:
+
+ pool.set_flag(solv.Pool.POOL_FLAG_OBSOLETEUSESCOLORS, 1);
+
+
+RUBY SPECIFICS
+--------------
+The ruby bindings can be loaded with:
+
+ require 'solv'
+
+Objects are either created by calling the new method on a class or they
+are returned by calling methods on other objects. Note that all classes start
+with an uppercase letter in ruby, so the class is called ``Solv''.
-THE POOL
---------
+ pool = Solv::Pool.new
+ repo = pool.add_repo("my_first_repo")
+Attributes can be accessed as usual:
+
+ pool.appdata = 42
+ puts "appdata is #{pool.appdata}"
+
+Iterators also work as expected:
+
+ for solvable in pool.solvables_iter() do ...
+
+Arrays are passed an returned as array objects:
+
+ jobs = []
+ problems = solver.solve(jobs)
+
+Most classes define a to_s method, so objects can be easily stringified.
+Many also define an inspect() method.
+
+ puts dep
+ puts repo.inspect
+
+Constants live in the namespace of the class they belong to:
+
+ pool.set_flag(Solv::Pool::POOL_FLAG_OBSOLETEUSESCOLORS, 1);
+
+Note that boolean methods have an added trailing ``?'', to be consistent with
+other ruby modules:
+
+ puts "empty repo" if repo.isempty?
+
+
+THE SOLV CLASS
+--------------
+This is the main namespace of the library, you cannot create objects of this
+type but it contains some useful constants.
+
+=== CONSTANTS ===
+
+Relational flag constants, the first three can be or-ed together
+
+*REL_LT*::
+ the ``less than'' bit
+
+*REL_EQ*::
+ the ``equals to'' bit
+
+*REL_GT*::
+ the ``greater then'' bit
+
+*REL_ARCH*::
+ used for relations that describe an extra architecture filter, the
+ version part of the relation is interpreted as architecture.
+
+Special Solvable Ids
+
+*SOLVID_META*::
+ Access the meta section of a repository or repodata area. This is
+ like an extra Solvable that has the Id SOLVID_META.
+
+*SOLVID_POS*::
+ Use the data position stored inside of the pool instead of accessing
+ some solvable by Id. The bindings have the Datapos objects as an
+ abstraction mechanism, so you do not need this constant.
+
+Constant string Ids
+
+*ID_NULL*::
+ Always zero
+
+*ID_EMPTY*::
+ Always one, describes the empty string
+
+*SOLVABLE_NAME*::
+ The keyname Id of the name of the solvable.
+
+*...*::
+ see the libsolv-knownid manpage for a list of fixed Ids.
+
+
+THE POOL CLASS
+--------------
The pool is libsolv's central resource manager. A pool consists of Solvables,
Repositories, Dependencies, each indexed by Ids.
Set the architecture for your system. The architecture is used to determine
which packages are installable. It defaults to the result of ``uname -m''.
- Repo *add_repo(const char *name)
+ Repo add_repo(const char *name)
$repo = $pool->add_repo($name);
repo = pool.add_repo(name)
repo = pool.add_repo(name)
Add a Repository with the specified name to the pool. The reposiory is empty
on creation, use the repository methods to populate it with packages.
- Repoiterator *repos_iter()
+ Repoiterator repos_iter()
for my $repo (@{$pool->repos_iter()})
for repo in pool.repos_iter():
for repo in pool.repos_iter()
Iterate over the existing repositories.
- Solvableiterator *solvables_iter()
+ Solvableiterator solvables_iter()
for my $solvable (@{$pool->solvables_iter()})
for solvable in pool.solvables_iter():
for solvable in pool.solvables_iter()
Iterate over the existing solvables.
- Dep *Dep(const char *str, bool create=1)
+ Dep Dep(const char *str, bool create = 1)
my $dep = $pool->Dep($string);
dep = pool.Dep(string)
dep = pool.Dep(string)
pool.addfileprovides()
pool.addfileprovides()
- Queue addfileprovides_queue()
+ Id *addfileprovides_queue()
my @ids = $pool->addfileprovides_queue();
ids = pool.addfileprovides_queue()
ids = pool.addfileprovides_queue()
all packages for matching files. If a filename has been matched, it will be
added to the provides list of the corresponding package. The
addfileprovides_queue variant works the same way but returns an array
-containing all file dependencies. This information can be stored with the
-repository to speed up the next usage of the repository.
+containing all file dependencies. This information can be stored in the
+meta section of the repositories to speed up the next time the
+repository is loaded and addfileprovides is called.
void createwhatprovides()
$pool->createwhatprovides();
It's encuraged to do it right after all repos are set up, usually right after
the call to addfileprovides().
- Queue whatprovides(DepId dep)
+ Solvable *whatprovides(DepId dep)
my @solvables = $pool->whatprovides($dep);
solvables = pool.whatprovides(dep)
solvables = pool.whatprovides(dep)
Return all solvables that provide the specified dependency. You can use either
a Dep object or an simple Id as argument.
- Queue matchprovidingids(const char *match, int flags)
+ Id *matchprovidingids(const char *match, int flags)
my @ids = $pool->matchprovidingids($match, $flags);
ids = pool.matchprovidingids(match, flags)
ids = pool.matchprovidingids(match, flags)
Search the names of all provides and return the ones matching the specified
string. See the Dataiterator class for the allowed flags.
- Id towhatprovides(Queue ids)
+ Id towhatprovides(Id *ids)
my $offset = $pool->towhatprovides(\@ids);
offset = pool.towhatprovides(ids)
offset = pool.towhatprovides(ids)
Return true if the specified Id describs a known architecture.
- Solver *Solver()
+ Solver Solver()
my $solver = $pool->Solver();
solver = pool.Solver()
solver = pool.Solver()
Create a new solver object.
- Solver *Job(int how, Id what)
+ Job Job(int how, Id what)
my $job = $pool->Job($how, $what);
job = pool.Job(how, what)
job = pool.Job(how, what)
Create a new Job object. Kind of low level, in most cases you would use a
Selection or Dep job constructor instead.
- Selection *Selection()
+ Selection Selection()
my $sel = $pool->Selection();
sel = pool.Selection()
sel = pool.Selection()
Create an empty selection. Useful as a starting point for merging other
selections.
- Selection *Selection_all()
+ Selection Selection_all()
my $sel = $pool->Selection_all();
sel = pool.Selection_all()
sel = pool.Selection_all()
Create a selection containing all packages. Useful as starting point for
intersecting other selections or for update/distupgrade jobs.
- Selection *select(const char *name, int flags)
+ Selection select(const char *name, int flags)
my $sel = $pool->select($name, $flags);
sel = pool.select(name, flags)
sel = pool.select(name, flags)
pool.setpooljobs(jobs)
pool.setpooljobs(jobs)
- Jobs *getpooljobs()
+ Job *getpooljobs()
@jobs = $pool->getpooljobs();
jobs = pool.getpooljobs()
jobs = pool.getpooljobs()
bool = pool.lookup_void(solvid, keyname)
bool = pool.lookup_void(solvid, keyname)
- Queue lookup_idarray(Id solvid, Id keyname)
+ Id *lookup_idarray(Id solvid, Id keyname)
my @ids = $pool->lookup_idarray($solvid, $keyname);
ids = pool.lookup_idarray(solvid, keyname)
ids = pool.lookup_idarray(solvid, keyname)
- Chksum *lookup_checksum(Id solvid, Id keyname)
+ Chksum lookup_checksum(Id solvid, Id keyname)
my $chksum = $pool->lookup_checksum($solvid, $keyname);
chksum = pool.lookup_checksum(solvid, keyname)
chksum = pool.lookup_checksum(solvid, keyname)
Lookup functions. Return the data element stored in the specified solvable.
You should probably use the methods of the Solvable class instead.
- Dataiterator *Dataiterator(Id solvid, Id keyname, const char *match, int flags)
+ Dataiterator Dataiterator(Id solvid, Id keyname, const char *match, int flags)
my $di = $pool->Dataiterator($solvid, $keyname, $match, $flags);
di = pool.Dataiterator(solvid, keyname, match, flags)
di = pool.Dataiterator(solvid, keyname, match, flags)
pool. They are considered ``low level'', in most cases you would not use them
but instead the object orientated methods.
- Repo *id2repo(Id id)
+ Repo id2repo(Id id)
$repo = $pool->id2repo($id);
repo = pool.id2repo(id)
repo = pool.id2repo(id)
Lookup an existing Repository by id. You can also do this by using the *repos*
attribute.
- Solvable *id2solvable(Id id)
+ Solvable id2solvable(Id id)
$solvable = $pool->id2solvable($id);
solvable = pool.id2solvable(id)
solvable = pool.id2solvable(id)
Return a string describing the Solvable with the specified id. The string
consists of the name, version, and architecture of the Solvable.
- Id str2id(const char *str, bool create=1)
+ Id str2id(const char *str, bool create = 1)
my $id = pool->str2id($string);
id = pool.str2id(string)
id = pool.str2id(string)
Convert a string into an Id and back. If the string is currently not in the
pool and _create_ is false, zero is returned.
- Id rel2id(Id name, Id evr, int flags, bool create=1)
+ Id rel2id(Id name, Id evr, int flags, bool create = 1)
my $id = pool->rel2id($nameid, $evrid, $flags);
id = pool.rel2id(nameid, evrid, flags)
id = pool.rel2id(nameid, evrid, flags)
Thus, if you want a ``\<='' relation, you would use *REL_LT | REL_EQ*.
- Id id2langid(Id id, const char *lang, bool create=1)
+ Id id2langid(Id id, const char *lang, bool create = 1)
my $id = $pool->id2langid($id, $language);
id = pool.id2langid(id, language)
id = pool.id2langid(id, language)
== Methods ==
- Dep *Rel(int flags, DepId evrid, bool create=1)
+ Dep Rel(int flags, DepId evrid, bool create = 1)
my $reldep = $dep->Rel($flags, $evrdep);
reldep = dep.Rel(flags, evrdep)
reldep = dep.Rel(flags, evrdep)
Create a relational dependency from to string dependencies and a flags
argument. See the pool's rel2id method for a description of the flags.
- Selection *Selection_name(int setflags = 0)
+ Selection Selection_name(int setflags = 0)
my $sel = $dep->Selection_name();
sel = dep.Selection_name()
sel = dep.Selection_name()
that have a name equal to the dependency. If the dependency is of a relational
type, the packages version must also fulfill the dependency.
- Selection *Selection_provides(int setflags = 0)
+ Selection Selection_provides(int setflags = 0)
my $sel = $dep->Selection_provides();
sel = dep.Selection_provides()
sel = dep.Selection_provides()
The dependencies are equal if they are part of the same pool and have the same
ids.
+
THE REPOSITORY CLASS
--------------------
A Repository describes a group of packages, normally comming from the same
a good way to cache repository data. Returns false if there was some error
writing the file.
- Solvableiterator *solvables_iter()
+ Solvableiterator solvables_iter()
for my $solvable (@{$repo->solvables_iter()})
for solvable in repo.solvables_iter():
for solvable in repo.solvables_iter()
Iterate over all solvables in a repository.
- Repodata *add_repodata(int flags = 0)
+ Repodata add_repodata(int flags = 0)
my $repodata = $repo->add_repodata();
repodata = repo.add_repodata()
repodata = repo.add_repodata()
Return true if the solvables of this repository are all in a single block with
no holes, i.e. they have consecutive ids.
- Repodata *first_repodata()
+ Repodata first_repodata()
my $repodata = $repo->first_repodata();
repodata = repo.first_repodata()
repodata = repo.first_repodata()
this does not work if the rpository contains multiple non-extension repodata
areas.
- Selection *Selection(int setflags = 0)
+ Selection Selection(int setflags = 0)
my $sel = $repo->Selection();
sel = repo.Selection()
sel = repo.Selection()
Create a Selection consisting of all packages in the repository.
- Dataiterator *Dataiterator(Id p, Id key, const char *match, int flags)
+ Dataiterator Dataiterator(Id p, Id key, const char *match, int flags)
my $di = $repo->Dataiterator($solvid, $keyname, $match, $flags);
di = repo.Dataiterator(solvid, keyname, match, flags)
di = repo.Dataiterator(solvid, keyname, match, flags)
=== DATA ADD METHODS ===
- Solvable *add_solvable()
+ Solvable add_solvable()
$repo->add_solvable();
repo.add_solvable()
repo.add_solvable()
THE SOLVABLE CLASS
------------------
-A solvable describes all the information of one package. Each solvable belongs to
-one repository, it can be added and filled manually but in most cases solvables
-will get created by the repo_add methods.
+A solvable describes all the information of one package. Each solvable
+belongs to one repository, it can be added and filled manually but in
+most cases solvables will get created by the repo_add methods.
=== ATTRIBUTES ===
bool = solvable.lookup_void(keyname)
bool = solvable.lookup_void(keyname)
- Chksum *lookup_checksum(Id keyname)
+ Chksum lookup_checksum(Id keyname)
my $chksum = $solvable->lookup_checksum($keyname);
chksum = solvable.lookup_checksum(keyname)
chksum = solvable.lookup_checksum(keyname)
- Queue lookup_idarray(Id keyname, Id marker = -1)
+ Id *lookup_idarray(Id keyname, Id marker = -1)
my @ids = $solvable->lookup_idarray($keyname);
ids = solvable.lookup_idarray(keyname)
ids = solvable.lookup_idarray(keyname)
- Queue lookup_deparray(Id keyname, Id marker = -1)
+ Dep *lookup_deparray(Id keyname, Id marker = -1)
my @deps = $solvable->lookup_deparray($keyname);
deps = solvable.lookup_deparray(keyname)
deps = solvable.lookup_deparray(keyname)
Return true if the solvable is installed on the system.
- Selection *Selection(int setflags = 0)
+ Selection Selection(int setflags = 0)
my $sel = $solvable->Selection();
sel = solvable.Selection()
sel = solvable.Selection()
Two solvables are equal if they are part of the same pool and have the same
ids.
+
THE DATAITERATOR CLASS
----------------------
-
Dataiterators can be used to do complex string searches or
to iterate over arrays. They can be created via the
constructors in the Pool, Repo, and Solvable classes. The
The secondary numeric value that was matched (only valid for types
containing two values).
- Datapos *pos();
+ Datapos pos();
my $pos = $d->pos();
pos = d.pos()
pos = d.pos()
sub-searches starting at the match (if it is of an array type).
See the Datapos class for more information.
- Datapos *parentpos();
+ Datapos parentpos();
my $pos = $d->parentpos();
pos = d.parentpos()
pos = d.parentpos()
Add a raw element to the selection. Check the Job class for information about
the how and what parameters.
- Job **jobs(int action)
+ Job *jobs(int action)
my @jobs = $sel->jobs($action);
jobs = sel.jobs(action)
jobs = sel.jobs(action)
to the ``how'' part of the job, it describes the type of job (e.g. install,
erase). See the Job class for the action and action modifier constants.
- Solvable **solvables()
+ Solvable *solvables()
my @solvables = $sel->solvables();
solvables = sel.solvables()
solvables = sel.solvables()
=== METHODS ===
- Solvable **solvables()
+ Solvable *solvables()
my @solvables = $job->solvables();
solvables = job.solvables()
solvables = job.solvables()
THE SOLVER CLASS
----------------
+Dependency solving is what this library is about. A solver object is needed
+for solving to store the result of the solver run. The solver object can be
+used multiple times for different jobs, reusing it allows the solver to
+re-use the dependency rules it already computed.
=== CONSTANTS ===
Set/get a solver specific flag. The flags define the policies the solver has
to obey. The flags are explained in the CONSTANTS section of this class.
- Problem **solve(Job *jobs)
+ Problem *solve(Job *jobs)
my @problems = $solver->solve(\@jobs);
problems = solver.solve(jobs)
problems = solver.solve(jobs)
if no problems were encountered. See the Problem class on how to deal with
problems.
- Transaction *transaction()
+ Transaction transaction()
my $trans = $solver->transaction();
trans = solver.transaction()
trans = solver.transaction()
THE PROBLEM CLASS
-----------------
-
Problems are the way of the solver to interact with the user. You can simply list
all problems and terminate your program, but a better way is to present solutions to
the user and let him pick the ones he likes.
=== METHODS ===
- Rule *findproblemrule()
+ Rule findproblemrule()
my $probrule = $problem->findproblemrule();
probrule = problem.findproblemrule()
probrule = problem.findproblemrule()
problem. Nevertheless, the solver uses some heuristic approch to find a rule
that somewhat describes the problem best to the user.
- Rule **findallproblemrules(bool unfiltered = 0)
+ Rule *findallproblemrules(bool unfiltered = 0)
my @probrules = $problem->findallproblemrules();
probrules = problem.findallproblemrule()
probrules = problem.findallproblemrule()
them to the user in a sensible way. The default is to filter out all update and
job rules (unless the returned rules only consist of those types).
- Solutions **solutions()
+ Solution *solutions()
my @solutions = $problem->solutions();
solutions = problem.solutions()
solutions = problem.solutions()
THE RULE CLASS
--------------
-
Rules are the basic block of sat solving. Each package dependency gets translated
into one or multiple rules.
=== METHODS ===
- Ruleinfo *info()
+ Ruleinfo info()
my $ruleinfo = $rule->info();
ruleinfo = rule.info()
ruleinfo = rule.info()
Return a Ruleinfo object that contains information about why the rule was created. But
see the allinfos() method below.
- Ruleinfo **allinfos()
+ Ruleinfo *allinfos()
my @ruleinfos = $rule->allinfos();
ruleinfos = rule.allinfos()
ruleinfos = rule.allinfos()
THE RULEINFO CLASS
------------------
-
A Ruleinfo describes one reason why a rule was created.
=== ATTRIBUTES ===
THE SOLUTION CLASS
------------------
-
A solution solves one specific problem. It consists of multiple solution elements
that all need to be executed.
=== METHODS ===
- Solutionelement **elements(bool expandreplaces = 0)
+ Solutionelement *elements(bool expandreplaces = 0)
my @solutionelements = $solution->elements();
solutionelements = solution.elements()
solutionelements = solution.elements()
THE SOLUTIONELEMENT CLASS
-------------------------
-
A solution element describes a single action of a solution. The action is always
either to remove one specific job or to add a new job that installs or erases
a single specific package.
=== METHODS ===
- Solutionelement **replaceelements()
+ Solutionelement *replaceelements()
my @solutionelements = $solutionelement->replaceelements();
solutionelements = solutionelement.replaceelements()
solutionelements = solutionelement.replaceelements()
zero if there was no policy mismatch. See the policy error constants in
the solver class.
- Job *Job()
+ Job Job()
my $job = $solutionelement->Job();
illegal = solutionelement.Job()
illegal = solutionelement.Job()
THE TRANSACTION CLASS
---------------------
+Transactions describe the output of a solver run. A transaction contains
+a number of transaction elements, each either the installation of a new
+package or the removal of an already installed package. The Transaction
+class supports a classify() method that puts the elements into different
+groups so that a transaction can be presented to the user in a meaningful
+way.
=== CONSTANTS ===
Returns true if the transaction does not do anything, i.e. has no elements.
- Solvable **newpackages();
+ Solvable *newpackages();
my @newsolvables = $trans->newpackages();
newsolvables = trans.newpackages()
newsolvables = trans.newpackages()
Return all packages that are to be installed by the transaction. This are
the packages that need to be downloaded from the repositories.
- Solvable **keptpackages();
+ Solvable *keptpackages();
my @keptsolvables = $trans->keptpackages();
keptsolvables = trans.keptpackages()
keptsolvables = trans.keptpackages()
Return all installed packages that the transaction will keep installed.
- Solvable **steps();
+ Solvable *steps();
my @steps = $trans->steps();
steps = trans.steps()
steps = trans.steps()
Return the transaction type of the specified solvable. See the CONSTANTS
sections for the mode argument flags and the list of returned types.
- TransactionClass **classify(int mode = 0)
+ TransactionClass *classify(int mode = 0)
my @classes = $trans->classify();
classes = trans.classify()
classes = trans.classify()
the CONSTANTS section. See the TransactionClass class for how to deal
with the returned objects.
- Solvable *othersolvable(Solvable *solvable);
+ Solvable othersolvable(Solvable *solvable);
my $other = $trans->othersolvable($solvable);
other = trans.othersolvable(solvable)
other = trans.othersolvable(solvable)
Thus, the ``other'' solvable is normally the package that is also shown
for a given package.
- Solvable **allothersolvables(Solvable *solvable);
+ Solvable *allothersolvables(Solvable *solvable);
my @others = $trans->allothersolvables($solvable);
others = trans.allothersolvables(solvable)
others = trans.allothersolvables(solvable)
THE TRANSACTIONCLASS CLASS
--------------------------
-
Objects of this type are returned by the classify() Transaction method.
=== ATTRIBUTES ===
=== CLASS METHODS ===
- Chksum *Chksum(Id type)
+ Chksum Chksum(Id type)
my $chksum = solv::Chksum->new($type);
chksum = solv.Chksum(type)
chksum = Solv::Chksum.new(type)
These keys are constants in the *solv* class.
- Chksum *Chksum(Id type, const char *hex)
+ Chksum Chksum(Id type, const char *hex)
my $chksum = solv::Chksum->new($type, $hex);
chksum = solv.Chksum(type, hex)
chksum = Solv::Chksum.new(type, hex)
ids = data.lookup_idarray(solvid, keyname)
ids = data.lookup_idarray(solvid, keyname)
- Chksum *lookup_checksum(Id solvid, Id keyname)
+ Chksum lookup_checksum(Id solvid, Id keyname)
my $chksum = $data->lookup_checksum($solvid, $keyname);
chksum = data.lookup_checksum(solvid, keyname)
chksum = data.lookup_checksum(solvid, keyname)
THE DATAPOS CLASS
-----------------
-
Datapos objects describe a specific position in the repository data area.
Thus they are only valid until the repository is modified in some way.
Datapos objects can be created by the pos() and parentpos() methods of
bool = datapos.lookup_void(keyname)
bool = datapos.lookup_void(keyname)
- Queue lookup_idarray(Id keyname)
+ Id *lookup_idarray(Id keyname)
my @ids = $datapos->lookup_idarray($keyname);
ids = datapos.lookup_idarray(keyname)
ids = datapos.lookup_idarray(keyname)
- Chksum *lookup_checksum(Id keyname)
+ Chksum lookup_checksum(Id keyname)
my $chksum = $datapos->lookup_checksum($keyname);
chksum = datapos.lookup_checksum(keyname)
chksum = datapos.lookup_checksum(keyname)