This file contains the major changes between
libsolv versions:
+Version 0.6.29
+- new features:
+ * support for REL_WITHOUT and REL_UNLESS dependencies
+ * solver_get_recommendations available in bindings
+
Version 0.6.28
- new features:
* new pool_best_solvables() function
--- /dev/null
+
+- make dataiterator only return the last occurance of a key
+
+- implement package priority (for things like Debian's pin feature)
+
+- merge SUSETAGS_FILE_* and REPOSITORY_REPOMD_* keys into REPOSITORY_RESOURCE
+
+- re-order key ids
+
+- deal with DIRSTR entries having dirid 0 (for source rpms)
+
+- test rich dep rule creation
+
+- clean up rich dep rule code (see perl-BSSolv)
+
+- drop patchcheck
+
+- rename repo2solv.sh to repo2solv (maybe rewrite in C?)
+
+- obey -A option in repo2solv
+
+- make FAVOR handling deal with versions
+
+- write more manpages
+
+- use dup rules all the time
+
+- bindings: selections.flags() should be a attribute and not a method
+
+- rename repodata_lookup_id_uninternalized to repodata_lookup_id_voidid_uninternalized
+ and add a notfound argument
+
+IDEAS:
+
SET(LIBSOLV_MAJOR "0")
SET(LIBSOLV_MINOR "6")
-SET(LIBSOLV_PATCH "28")
+SET(LIBSOLV_PATCH "29")
ENDIF (ENABLE_PYTHON3 AND NOT DEFINED PythonLibs_FIND_VERSION)
FIND_PACKAGE (PythonLibs REQUIRED)
-FIND_PACKAGE (PythonInterp ${PYTHONLIBS_VERSION_STRING} REQUIRED)
+IF(PYTHONLIBS_VERSION_STRING MATCHES "^([0-9.]+)")
+ SET(python_version "${CMAKE_MATCH_1}")
+ELSE()
+ MESSAGE(FATAL_ERROR "PythonLibs version format unknown '${PYTHONLIBS_VERSION_STRING}'")
+ENDIF()
+FIND_PACKAGE (PythonInterp ${python_version} REQUIRED)
EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} -c "from sys import stdout; from distutils import sysconfig; stdout.write(sysconfig.get_python_lib(True))" OUTPUT_VARIABLE PYTHON_INSTALL_DIR)
%constant int REL_MULTIARCH;
%constant int REL_ELSE;
%constant int REL_ERROR;
+%constant int REL_WITHOUT;
+%constant int REL_UNLESS;
typedef struct {
Pool* const pool;
}
return q;
}
+
+ %typemap(out) Queue get_recommended Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
+ %newobject get_recommended;
+ Queue get_recommended(bool noselected=0) {
+ Queue q;
+ queue_init(&q);
+ solver_get_recommendations($self, &q, NULL, noselected);
+ return q;
+ }
+ %typemap(out) Queue get_suggested Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
+ %newobject get_suggested;
+ Queue get_suggested(bool noselected=0) {
+ Queue q;
+ queue_init(&q);
+ solver_get_recommendations($self, NULL, &q, noselected);
+ return q;
+ }
}
%extend Transaction {
SET (libsolv_MANPAGES1 ${libsolv_MANPAGES1} appdata2solv.1)
ENDIF (ENABLE_APPDATA)
+# prepend gen directory
+STRING(REGEX REPLACE "([^;]+)" "gen/\\1" libsolv_MANPAGES1 "${libsolv_MANPAGES1}")
+STRING(REGEX REPLACE "([^;]+)" "gen/\\1" libsolv_MANPAGES3 "${libsolv_MANPAGES3}")
+
INSTALL(FILES
${libsolv_MANPAGES3}
DESTINATION "${MAN_INSTALL_DIR}/man3")
+VPATH = gen
+
man: man3 man1
man3: libsolv.3 libsolv-bindings.3 libsolv-constantids.3 libsolv-history.3 libsolv-pool.3
.SUFFIXES: .html .3 .1 .txt
.txt.1:
- a2x -f manpage $<
+ a2x -f manpage -D gen $<
.txt.3:
- a2x -f manpage $<
+ a2x -f manpage -D gen $<
.txt.html:
- a2x -f xhtml $<
+ a2x -f xhtml -D gen $<
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
'\" t
.\" Title: appdata2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 07/25/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "APPDATA2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "APPDATA2SOLV" "1" "07/25/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: archpkgs2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 07/25/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "ARCHPKGS2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "ARCHPKGS2SOLV" "1" "07/25/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: archrepo2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 07/25/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "ARCHREPO2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "ARCHREPO2SOLV" "1" "07/25/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: comps2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 07/25/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "COMPS2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "COMPS2SOLV" "1" "07/25/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: deb2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 07/25/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "DEB2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "DEB2SOLV" "1" "07/25/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: deltainfoxml2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 07/25/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "DELTAINFOXML2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "DELTAINFOXML2SOLV" "1" "07/25/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: dumpsolv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 07/25/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "DUMPSOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "DUMPSOLV" "1" "07/25/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: helix2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 12/14/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "HELIX2SOLV" "1" "12/14/2015" "libsolv" "LIBSOLV"
+.TH "HELIX2SOLV" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: installcheck
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "INSTALLCHECK" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "INSTALLCHECK" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" Title: Libsolv-Bindings
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 12/14/2016
+.\" Date: 09/07/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "LIBSOLV\-BINDINGS" "3" "12/14/2016" "libsolv" "LIBSOLV"
+.TH "LIBSOLV\-BINDINGS" "3" "09/07/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\}
.nf
\fBbool add_mdk_info(FILE *\fR\fIfp\fR\fB, int\fR \fIflags\fR \fB= 0)\fR
-\fI$repo\fR\fB\->add_mdk(\fR\fI$fp\fR\fB)\fR;
-\fIrepo\fR\fB\&.add_mdk(\fR\fIfp\fR\fB)\fR
-\fIrepo\fR\fB\&.add_mdk(\fR\fIfp\fR\fB)\fR
+\fI$repo\fR\fB\->add_mdk_info(\fR\fI$fp\fR\fB)\fR;
+\fIrepo\fR\fB\&.add_mdk_info(\fR\fIfp\fR\fB)\fR
+\fIrepo\fR\fB\&.add_mdk_info(\fR\fIfp\fR\fB)\fR
.fi
.if n \{\
.RE
.\}
.nf
\fBconst char *lookup_sourcepkg()\fR;
-my \fR\fI$sourcepkg\fR\fB =\fR \fI$solvable\fR\fB\->lookup_sourcepkg()\fR;
-\fIsourcepkg\fR\fB \fB=\fR \fIsolvable\fR\fB\&.lookup_sourcepkg()\fR
-\fIsourcepkg\fR\fB \fB=\fR \fIsolvable\fR\fB\&.lookup_sourcepkg()\fR
+my \fI$sourcepkg\fR \fB=\fR \fI$solvable\fR\fB\->lookup_sourcepkg()\fR;
+\fIsourcepkg\fR \fB=\fR \fIsolvable\fR\fB\&.lookup_sourcepkg()\fR
+\fIsourcepkg\fR \fB=\fR \fIsolvable\fR\fB\&.lookup_sourcepkg()\fR
.fi
.if n \{\
.RE
.RE
.\}
.sp
-Return true if the dependencies stored in keyname match the specified dependeny\&.
+Return true if the dependencies stored in keyname match the specified dependency\&.
.sp
.if n \{\
.RS 4
.PP
\fBSOLVER_FLAG_NEED_UPDATEPROVIDE\fR
.RS 4
-This is somewhat the opposite of SOLVER_FLAG_NO_UPDATEPROVIDE: Only packages that provied the installed package names are considered for updating\&.
+This is somewhat the opposite of SOLVER_FLAG_NO_UPDATEPROVIDE: Only packages that provide the installed package names are considered for updating\&.
.RE
.PP
\fBSOLVER_FLAG_SPLITPROVIDES\fR
.\}
.sp
Return the reason why a specific solvable was installed or erased\&. For most of the reasons the rule that triggered the decision is also returned\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBSolvable *get_recommended(bool\fR \fInoselected\fR\fB=0)\fR;
+my \fI@solvables\fR \fB=\fR \fI$solver\fR\fB\->get_recommended()\fR;
+\fIsolvables\fR \fB=\fR \fIsolver\fR\fB\&.get_recommended()\fR
+\fIsolvables\fR \fB=\fR \fIsolver\fR\fB\&.get_recommended()\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Return all solvables that are recommended by the solver run result\&. This includes solvables included in the result, set noselected if you want to filter those\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBSolvable *get_suggested(bool\fR \fInoselected\fR\fB=0)\fR;
+my \fI@solvables\fR \fB=\fR \fI$solver\fR\fB\->get_suggested()\fR;
+\fIsolvables\fR \fB=\fR \fIsolver\fR\fB\&.get_suggested()\fR
+\fIsolvables\fR \fB=\fR \fIsolver\fR\fB\&.get_suggested()\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Return all solvables that are suggested by the solver run result\&. This includes solvables included in the result, set noselected if you want to filter those\&.
.SH "THE PROBLEM CLASS"
.sp
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\&.
.nf
\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
+\fIprobrules\fR \fB=\fR \fIproblem\fR\fB\&.findallproblemrules()\fR
+\fIprobrules\fR \fB=\fR \fIproblem\fR\fB\&.findallproblemrules()\fR
.fi
.if n \{\
.RE
.RE
.\}
.sp
-Create a job that implements the solution element\&. Add this job to the array of jobs for all elements of type different to SOLVER_SOLUTION_JOB and SOLVER_SOLUTION_POOLJOB\&. For the later two, a SOLVER_NOOB Job is created, you should replace the old job with the new one\&.
+Create a job that implements the solution element\&. Add this job to the array of jobs for all elements of type different to SOLVER_SOLUTION_JOB and SOLVER_SOLUTION_POOLJOB\&. For the latter two, a SOLVER_NOOB Job is created, you should replace the old job with the new one\&.
.sp
.if n \{\
.RS 4
.RE
.\}
.sp
-Extend the repodata so that it has the same size as the repo it belongs to\&. This method is only needed when switching to a just written repodata extension to make the repodata match the written extension (which is always of the size of the repo)\&.
+Extend the repodata so that it has the same size as the repo it belongs to\&. This method is needed when setting up a new extension repodata so that it matches the repository size\&. It is also needed when switching to a just written repodata extension to make the repodata match the written extension (which is always of the size of the repo)\&.
.sp
.if n \{\
.RS 4
.\}
.nf
\fBvoid set_sourcepkg(Id\fR \fIsolvid\fR\fB, const char *\fR\fIsourcepkg\fR\fB)\fR;
-\fI$data\fR\fB\->set_sourcepkg(\fR\fI$solvid\fR\fB, \fI$sourcepkg\fR\fB)\fR;
+\fI$data\fR\fB\&.set_sourcepkg(\fR\fI$solvid\fR\fB,\fR \fI$sourcepkg\fR\fB)\fR;
\fIdata\fR\fB\&.set_sourcepkg(\fR\fIsolvid\fR\fB,\fR \fIsourcepkg\fR\fB)\fR
\fIdata\fR\fB\&.set_sourcepkg(\fR\fIsolvid\fR\fB,\fR \fIsourcepkg\fR\fB)\fR
.fi
'\" t
.\" Title: Libsolv-Constantids
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 12/14/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "LIBSOLV\-CONSTANTIDS" "3" "12/14/2015" "libsolv" "LIBSOLV"
+.TH "LIBSOLV\-CONSTANTIDS" "3" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: Libsolv-History
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "LIBSOLV\-HISTORY" "3" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "LIBSOLV\-HISTORY" "3" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: Libsolv-Pool
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 05/06/2016
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 09/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "LIBSOLV\-POOL" "3" "05/06/2016" "libsolv" "LIBSOLV"
+.TH "LIBSOLV\-POOL" "3" "09/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
A conditional dependency, the \(lqname\(rq sub\-dependency is only considered if the \(lqevr\(rq sub\-dependency is fulfilled\&. See the section about boolean dependencies about more information\&.
.RE
.PP
+\fBREL_UNLESS\fR
+.RS 4
+A conditional dependency, the \(lqname\(rq sub\-dependency is only considered if the \(lqevr\(rq sub\-dependency is not fulfilled\&. See the section about boolean dependencies about more information\&.
+.RE
+.PP
\fBREL_COMPAT\fR
.RS 4
A compat dependency used in Haiku to represent version ranges\&. The \(lqname\(rq part is the actual version, the \(lqevr\(rq part is the backwards compatibility version\&.
.RE
+.PP
+\fBREL_KIND\fR
+.RS 4
+A pseudo dependency that limits the solvables to a specific kind\&. The kind is expected to be a prefix of the solvable name, e\&.g\&. \(lqpatch:foo\(rq would be of kind \(lqpatch\(rq\&. \(lqREL_KIND\(rq is only supported in the selection functions\&.
+.RE
+.PP
+\fBREL_MULTIARCH\fR
+.RS 4
+A debian multiarch annotation\&. The most common value for the \(lqevr\(rq part is \(lqany\(rq\&.
+.RE
+.PP
+\fBREL_ELSE\fR
+.RS 4
+The else part of a \(lqREL_COND\(rq or \(lqREL_UNLESS\(rq dependency\&. See the section about boolean dependencies\&.
+.RE
+.PP
+\fBREL_ERROR\fR
+.RS 4
+An illegal dependency\&. This is useful to encode dependency parse errors\&.
+.RE
.SS "Functions"
.sp
.if n \{\
You can turn off the architecture replacement checks with the Solver\(cqs SOLVER_FLAG_ALLOW_VENDORCHANGE flag\&.
.SH "BOOLEAN DEPENDENCIES"
.sp
-Boolean Dependencies allow to build complex expressions from simple dependencies\&. While rpm does not support boolean expressions in dependencies and debian only allows an "OR" expression, libsolv allows arbitrary complex expressions\&. The following basic types are supported:
+Boolean Dependencies allow to build complex expressions from simple dependencies\&. Note that depending on the package manager only a subset of those may be useful\&. For example, debian currently only allows an "OR" expression\&.
.PP
\fBREL_OR\fR
.RS 4
.PP
\fBREL_AND\fR
.RS 4
-The expression is true if both dependencies are true\&. The packages fulfilling the dependencies may be different, i\&.e\&. \(lqSupplements: perl AND python\(rq is true if both a package providing perl and a package providing python are installed\&. The solver currently only supports REL_AND in Supplements/Enhances dependencies, in other types of dependencies it gets treated as REL_WITH\&.
+The expression is true if both dependencies are true\&. The packages fulfilling the dependencies may be different, i\&.e\&. \(lqSupplements: perl REL_AND python\(rq is true if both a package providing perl and a package providing python are installed\&.
.RE
.PP
\fBREL_WITH\fR
.RS 4
-The expression is true if both dependencies are true and are fulfilled by the same package\&. Thus \(lqSupplements: perl AND python\(rq would only be true if a package is installed that provides both dependencies (some kind of multi\-language interpreter)\&.
+The expression is true if both dependencies are true and are fulfilled by the same package\&. Thus \(lqSupplements: perl REL_WITH python\(rq would only be true if a package is installed that provides both dependencies (some kind of multi\-language interpreter)\&.
.RE
.PP
\fBREL_COND\fR
.RS 4
-The expression is true if the first dependency is true or the second dependency is false\&. Libsolv currently does not support this type of dependency in the solver code\&.
+The expression is true if the first dependency is true or the second dependency is false\&. \(lqA REL_COND B\(rq is equivalent to \(lqA REL_OR (NOT B)\(rq (except that libsolv does not expose \(lqNOT\(rq)\&.
+.RE
+.PP
+\fBREL_UNLESS\fR
+.RS 4
+The expression is true if the first dependency is true and the second dependency is false\&. \(lqA REL_UNLESS B\(rq is equivalent to \(lqA REL_AND (NOT B)\(rq (except that libsolv does not expose \(lqNOT\(rq)\&.
+.RE
+.PP
+\fBREL_ELSE\fR
+.RS 4
+The \(lqelse\(rq part of a \(lqREL_COND\(rq or \(lqREL_UNLESS\(rq dependency\&. It has to be directly in the evr part of the condition, e\&.g\&. \(lqfoo REL_COND (bar REL_ELSE baz)\(rq\&. For \(lqREL_COND\(rq this is equivalent to writing \(lq(foo REL_COND bar) REL_AND (bar REL_OR baz)\(rq\&. For \(lqREL_UNLESS\(rq this is equivalent to writing \(lq(foo REL_UNLESS bar) REL_OR (bar REL_AND baz)\(rq\&.
.RE
.sp
Each sub\-dependency of a boolean dependency can in turn be a boolean dependency, so you can chain them to create complex dependencies\&.
'\" t
.\" Title: Libsolv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "LIBSOLV" "3" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "LIBSOLV" "3" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: mdk2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "MDK2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "MDK2SOLV" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: mergesolv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "MERGESOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "MERGESOLV" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: repomdxml2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "REPOMDXML2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "REPOMDXML2SOLV" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: rpmdb2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "RPMDB2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "RPMDB2SOLV" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: rpmmd2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "RPMMD2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "RPMMD2SOLV" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: rpms2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "RPMS2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "RPMS2SOLV" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: susetags2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "SUSETAGS2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "SUSETAGS2SOLV" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: testsolv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "TESTSOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "TESTSOLV" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
'\" t
.\" Title: updateinfoxml2solv
.\" Author: [see the "Author" section]
-.\" Generator: DocBook XSL Stylesheets v1.78.0 <http://docbook.sf.net/>
-.\" Date: 08/26/2015
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 08/04/2017
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "UPDATEINFOXML2SOLV" "1" "08/26/2015" "libsolv" "LIBSOLV"
+.TH "UPDATEINFOXML2SOLV" "1" "08/04/2017" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
libsolv's arrays are mapped to tcl's lists:
- TCL set jobs [list $job1 $job2]
+ TCL set jobs [list $job1 $job2]
TCL set problems [$solver solve $jobs]
TCL puts "We have [llength $problems] problems..."
"synthesis.hdlist" file) to the repository.
bool add_mdk_info(FILE *fp, int flags = 0)
- $repo->add_mdk($fp);
- repo.add_mdk(fp)
- repo.add_mdk(fp)
+ $repo->add_mdk_info($fp);
+ repo.add_mdk_info(fp)
+ repo.add_mdk_info(fp)
Extend the packages from the synthesis file with the info.xml and files.xml
data. Do not forget to specify *REPO_EXTEND_SOLVABLES*.
solvable.matchesdep(keyname, dep)
solvable.matchesdep?(keyname, dep)
-Return true if the dependencies stored in keyname match the specified dependeny.
+Return true if the dependencies stored in keyname match the specified dependency.
Selection Selection(int setflags = 0)
my $sel = $solvable->Selection();
*SOLVER_FLAG_NEED_UPDATEPROVIDE*::
This is somewhat the opposite of SOLVER_FLAG_NO_UPDATEPROVIDE: Only
-packages that provied the installed package names are considered
+packages that provide the installed package names are considered
for updating.
*SOLVER_FLAG_SPLITPROVIDES*::
Return the reason why a specific solvable was installed or erased. For most of
the reasons the rule that triggered the decision is also returned.
+ Solvable *get_recommended(bool noselected=0);
+ my @solvables = $solver->get_recommended();
+ solvables = solver.get_recommended()
+ solvables = solver.get_recommended()
+
+Return all solvables that are recommended by the solver run result. This includes
+solvables included in the result, set noselected if you want to filter those.
+
+ Solvable *get_suggested(bool noselected=0);
+ my @solvables = $solver->get_suggested();
+ solvables = solver.get_suggested()
+ solvables = solver.get_suggested()
+
+Return all solvables that are suggested by the solver run result. This includes
+solvables included in the result, set noselected if you want to filter those.
+
+
The Problem Class
-----------------
Problems are the way of the solver to interact with the user. You can simply list
Rule *findallproblemrules(bool unfiltered = 0)
my @probrules = $problem->findallproblemrules();
- probrules = problem.findallproblemrule()
- probrules = problem.findallproblemrule()
+ probrules = problem.findallproblemrules()
+ probrules = problem.findallproblemrules()
Return all rules responsible for the problem. The returned set of rules contains
all the needed information why there was a problem, but it's hard to present
Create a job that implements the solution element. Add this job to the array
of jobs for all elements of type different to SOLVER_SOLUTION_JOB and
-SOLVER_SOLUTION_POOLJOB. For the later two, a SOLVER_NOOB Job is created,
+SOLVER_SOLUTION_POOLJOB. For the latter two, a SOLVER_NOOB Job is created,
you should replace the old job with the new one.
const char *str()
data.extend_to_repo()
Extend the repodata so that it has the same size as the repo it belongs to.
-This method is only needed when switching to a just written repodata extension
-to make the repodata match the written extension (which is always of the
-size of the repo).
+This method is needed when setting up a new extension repodata so that it
+matches the repository size. It is also needed when switching to a just written
+repodata extension to make the repodata match the written extension (which is
+always of the size of the repo).
<equality>
if ($data1 == $data2)
------
Michael Schroeder <mls@suse.de>
+////
+vim: syntax=asciidoc
+////
------
Michael Schroeder <mls@suse.de>
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
the ``evr'' sub-dependency is fulfilled. See the section about boolean
dependencies about more information.
+*REL_UNLESS*::
+A conditional dependency, the ``name'' sub-dependency is only considered if
+the ``evr'' sub-dependency is not fulfilled. See the section about boolean
+dependencies about more information.
+
*REL_COMPAT*::
A compat dependency used in Haiku to represent version ranges. The
``name'' part is the actual version, the ``evr'' part is the backwards
compatibility version.
+*REL_KIND*::
+A pseudo dependency that limits the solvables to a specific kind.
+The kind is expected to be a prefix of the solvable name, e.g.
+``patch:foo'' would be of kind ``patch''. ``REL_KIND'' is only
+supported in the selection functions.
+
+*REL_MULTIARCH*::
+A debian multiarch annotation. The most common value for the ``evr''
+part is ``any''.
+
+*REL_ELSE*::
+The else part of a ``REL_COND'' or ``REL_UNLESS'' dependency. See the
+section about boolean dependencies.
+
+*REL_ERROR*::
+An illegal dependency. This is useful to encode dependency parse errors.
+
=== Functions ===
Id pool_str2id(Pool *pool, const char *str, int create);
Boolean Dependencies
--------------------
Boolean Dependencies allow to build complex expressions from simple
-dependencies. While rpm does not support boolean expressions in
-dependencies and debian only allows an "OR" expression, libsolv
-allows arbitrary complex expressions. The following basic types
-are supported:
+dependencies. Note that depending on the package manager only a subset
+of those may be useful. For example, debian currently only allows
+an "OR" expression.
*REL_OR*::
The expression is true if either the first dependency or the second
*REL_AND*::
The expression is true if both dependencies are true. The packages
fulfilling the dependencies may be different, i.e.
-``Supplements: perl AND python'' is true if both a package providing
-perl and a package providing python are installed. The solver currently
-only supports REL_AND in Supplements/Enhances dependencies, in other
-types of dependencies it gets treated as REL_WITH.
+``Supplements: perl REL_AND python'' is true if both a package providing
+perl and a package providing python are installed.
*REL_WITH*::
The expression is true if both dependencies are true and are fulfilled by
-the same package. Thus ``Supplements: perl AND python'' would only be true
+the same package. Thus ``Supplements: perl REL_WITH python'' would only be true
if a package is installed that provides both dependencies (some kind
of multi-language interpreter).
*REL_COND*::
The expression is true if the first dependency is true or the second
-dependency is false. Libsolv currently does not support this type of
-dependency in the solver code.
+dependency is false. ``A REL_COND B'' is equivalent to
+``A REL_OR (NOT B)'' (except that libsolv does not expose ``NOT'').
+
+*REL_UNLESS*::
+The expression is true if the first dependency is true and the second
+dependency is false. ``A REL_UNLESS B'' is equivalent to
+``A REL_AND (NOT B)'' (except that libsolv does not expose ``NOT'').
+
+*REL_ELSE*::
+The ``else'' part of a ``REL_COND'' or ``REL_UNLESS'' dependency.
+It has to be directly in the evr part of the condition,
+e.g. ``foo REL_COND (bar REL_ELSE baz)''.
+For ``REL_COND'' this is equivalent to writing
+``(foo REL_COND bar) REL_AND (bar REL_OR baz)''.
+For ``REL_UNLESS'' this is equivalent to writing
+``(foo REL_UNLESS bar) REL_OR (bar REL_AND baz)''.
Each sub-dependency of a boolean dependency can in turn be a boolean
dependency, so you can chain them to create complex dependencies.
------
Michael Schroeder <mls@suse.de>
+////
+vim: syntax=asciidoc
+////
------
Michael Schroeder <mls@suse.de>
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
Author
------
Michael Schroeder <mls@suse.de>
+
+////
+vim: syntax=asciidoc
+////
seq = pool_tmpappend(pool, seq, "-", pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_NUM));
if (strchr(seq, '\'') != 0)
continue;
-#ifdef FEDORA
+#if defined(FEDORA) || defined(MAGEIA)
sprintf(cmd, "/usr/bin/applydeltarpm -a '%s' -c -s '", archstr);
#else
sprintf(cmd, "/usr/bin/applydeltarpm -c -s '");
continue;
/* got it, now reconstruct */
newfd = opentmpfile();
-#ifdef FEDORA
+#if defined(FEDORA) || defined(MAGEIA)
sprintf(cmd, "applydeltarpm -a '%s' /dev/fd/%d /dev/fd/%d", archstr, fileno(fp), newfd);
#else
sprintf(cmd, "applydeltarpm /dev/fd/%d /dev/fd/%d", fileno(fp), newfd);
#include "repoinfo.h"
#include "repoinfo_cache.h"
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
#include "repoinfo_config_yum.h"
#endif
#if defined(DEBIAN)
#include "repoinfo_config_debian.h"
#endif
-#if defined(MANDRIVA) || defined(MAGEIA)
+#if defined(MANDRIVA)
#include "repoinfo_config_urpmi.h"
#endif
solv_free(cinfo->components);
}
solv_free(repoinfos);
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
yum_substitute((Pool *)0, 0); /* free data */
#endif
}
read_repoinfos(Pool *pool, int *nrepoinfosp)
{
struct repoinfo *repoinfos = 0;
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
repoinfos = read_repoinfos_yum(pool, nrepoinfosp);
#endif
-#if defined(MANDRIVA) || defined(MAGEIA)
+#if defined(MANDRIVA)
repoinfos = read_repoinfos_urpmi(pool, nrepoinfosp);
#endif
#if defined(DEBIAN)
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
#include <stdio.h>
#include <stdlib.h>
#include "repoinfo_config_yum.h"
-#ifdef FEDORA
+#if defined(FEDORA) || defined(MAGEIA)
# define REPOINFO_PATH "/etc/yum.repos.d"
#endif
#ifdef SUSE
queue_init(&q);
rpmstate = rpm_state_create(pool, pool_get_rootdir(pool));
- rpm_installedrpmdbids(rpmstate, "Providename", "redhat-release", &q);
+ rpm_installedrpmdbids(rpmstate, "Providename", "system-release", &q);
if (q.count)
{
void *handle;
queue_free(&q);
if (!releaseevr)
{
- fprintf(stderr, "no installed package provides 'redhat-release', cannot determine $releasever\n");
+ fprintf(stderr, "no installed package provides 'system-release', cannot determine $releasever\n");
exit(1);
}
}
cinfo->type = TYPE_RPMMD;
cinfo->autorefresh = 1;
cinfo->priority = 99;
-#ifndef FEDORA
+#if !defined(FEDORA) && !defined(MAGEIA)
cinfo->repo_gpgcheck = 1;
#endif
cinfo->metadata_expire = METADATA_EXPIRE;
#include "repoinfo.h"
#include "mirror.h"
#include "checksig.h"
+#if defined(FEDORA) || defined(MAGEIA)
+#include "repoinfo_config_yum.h"
+#endif
#include "repoinfo_download.h"
static inline int
fclose(fp);
if (!cinfo->baseurl)
return 0;
-#ifdef FEDORA
+#if defined(FEDORA) || defined(MAGEIA)
if (strchr(cinfo->baseurl, '$'))
{
char *b = yum_substitute(cinfo->repo->pool, cinfo->baseurl);
#include "fileconflicts.h"
#include "deltarpm.h"
#endif
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
#include "patchjobs.h"
#endif
fprintf(stderr, " search: search name/summary/description\n");
fprintf(stderr, " update: update installed packages\n");
fprintf(stderr, " verify: check dependencies of installed packages\n");
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
fprintf(stderr, " patch: install newest maintenance updates\n");
#endif
fprintf(stderr, "\n");
mainmode = MODE_INSTALL;
mode = SOLVER_INSTALL;
}
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
else if (!strcmp(argv[0], "patch"))
{
mainmode = MODE_PATCH;
exit(0);
}
-#if defined(SUSE) || defined(FEDORA)
+#if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
if (mainmode == MODE_PATCH)
add_patchjobs(pool, &job);
#endif
rerunsolver:
solv = solver_create(pool);
solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1);
-#ifdef FEDORA
+#if defined(FEDORA) || defined(MAGEIA)
solver_set_flag(solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, 1);
#endif
if (mainmode == MODE_ERASE)
int l;
Id fl;
} RichOps[] = {
- { "and", 3, REL_AND },
- { "or", 2, REL_OR },
- { "if", 2, REL_COND },
- { "else", 4, REL_ELSE },
+ { "and", 3, REL_AND },
+ { "or", 2, REL_OR },
+ { "if", 2, REL_COND },
+ { "unless", 6, REL_UNLESS },
+ { "else", 4, REL_ELSE },
+ { "with", 4, REL_WITH },
+ { "without", 7, REL_WITHOUT },
{ NULL, 0, 0},
};
fl = op->fl;
if (!fl)
return 0;
- if (chainfl == REL_COND && fl == REL_ELSE)
+ if ((chainfl == REL_COND || chainfl == REL_UNLESS) && fl == REL_ELSE)
chainfl = 0;
if (chainfl && fl != chainfl)
return 0;
int cnt;
unsigned int dcnt;
unsigned char *dp;
- int forcebinary; /* sigh, see rh#478907 */
unsigned char data[1];
} RpmHead;
return h->dp + o;
}
+static int
+headissourceheuristic(RpmHead *h)
+{
+ unsigned int i, o;
+ unsigned char *d = headfindtag(h, TAG_DIRNAMES);
+ if (!d || d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 8)
+ return 0;
+ o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
+ i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
+ return i == 1 && o < h->dcnt && !h->dp[o] ? 1 : 0;
+}
+
static char *headtoevr(RpmHead *h)
{
unsigned int epoch;
return 0;
s->name = pool_str2id(pool, name, 1);
sourcerpm = headstring(rpmhead, TAG_SOURCERPM);
- if (sourcerpm || (rpmhead->forcebinary && !headexists(rpmhead, TAG_SOURCEPACKAGE)))
+ if (sourcerpm || !(headexists(rpmhead, TAG_SOURCEPACKAGE) || headissourceheuristic(rpmhead)))
s->arch = pool_str2id(pool, headstring(rpmhead, TAG_ARCH), 1);
else
{
#endif
}
-#ifdef FEDORA
+#if defined(FEDORA) || defined(MAGEIA)
int
serialize_dbenv_ops(struct rpmdbstate *state)
{
if (db_env_create(&dbenv, 0))
return pool_error(state->pool, 0, "db_env_create: %s", strerror(errno));
-#if defined(FEDORA) && (DB_VERSION_MAJOR >= 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 5))
+#if (defined(FEDORA) || defined(MAGEIA)) && (DB_VERSION_MAJOR >= 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 5))
dbenv->set_thread_count(dbenv, 8);
#endif
snprintf(dbpath, PATH_MAX, "%s/var/lib/rpm", rootdir ? rootdir : "");
}
else
{
-#ifdef FEDORA
+#if defined(FEDORA) || defined(MAGEIA)
int serialize_fd = serialize_dbenv_ops(state);
r = dbenv->open(dbenv, dbpath, DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL, 0644);
if (serialize_fd >= 0)
static void
closedbenv(struct rpmdbstate *state)
{
-#ifdef FEDORA
+#if defined(FEDORA) || defined(MAGEIA)
uint32_t eflags = 0;
#endif
if (!state->dbenv)
return;
-#ifdef FEDORA
+#if defined(FEDORA) || defined(MAGEIA)
(void)state->dbenv->get_open_flags(state->dbenv, &eflags);
if (!(eflags & DB_PRIVATE))
{
state->rpmhead = solv_realloc(state->rpmhead, sizeof(*rpmhead) + state->rpmheadsize);
}
rpmhead = state->rpmhead;
- rpmhead->forcebinary = 1;
rpmhead->cnt = cnt;
rpmhead->dcnt = dsize;
memcpy(rpmhead->data, (unsigned char *)dbdata->data + 8, l);
Id chksumtype = 0;
Chksum *chksumh = 0;
Chksum *leadsigchksumh = 0;
- int forcebinary = 0;
data = repo_add_repodata(repo, flags);
fclose(fp);
return 0;
}
- forcebinary = lead[6] != 0 || lead[7] != 1;
if (chksumh)
solv_chksum_add(chksumh, lead, 96 + 16);
if (leadsigchksumh)
solv_chksum_add(chksumh, rpmhead->data, sigdsize);
if (leadsigchksumh)
solv_chksum_add(leadsigchksumh, rpmhead->data, sigdsize);
- rpmhead->forcebinary = 0;
rpmhead->cnt = sigcnt;
rpmhead->dcnt = sigdsize - sigcnt * 16;
rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
rpmhead->data[l] = 0;
if (chksumh)
solv_chksum_add(chksumh, rpmhead->data, l);
- rpmhead->forcebinary = forcebinary;
rpmhead->cnt = sigcnt;
rpmhead->dcnt = sigdsize;
rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
if (!name)
name = "";
sourcerpm = headstring(rpmhead, TAG_SOURCERPM);
- if (sourcerpm || (rpmhead->forcebinary && !headexists(rpmhead, TAG_SOURCEPACKAGE)))
+ if (sourcerpm || !(headexists(rpmhead, TAG_SOURCEPACKAGE) || headissourceheuristic(rpmhead)))
arch = headstring(rpmhead, TAG_ARCH);
else
{
RpmHead *rpmhead;
unsigned int sigdsize, sigcnt, l;
unsigned char lead[4096];
- int forcebinary = 0;
if (fread(lead, 96 + 16, 1, fp) != 1 || getu32(lead) != 0xedabeedb)
{
pool_error(state->pool, 0, "%s: not a rpm", name);
return 0;
}
- forcebinary = lead[6] != 0 || lead[7] != 1;
if (lead[78] != 0 || lead[79] != 5)
{
pool_error(state->pool, 0, "%s: not a V5 header", name);
return 0;
}
rpmhead->data[l] = 0;
- rpmhead->forcebinary = forcebinary;
rpmhead->cnt = sigcnt;
rpmhead->dcnt = sigdsize;
rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
memcpy(rpmhead->data, uh + 8, l);
rpmhead->data[l] = 0;
free((void *)uh);
- rpmhead->forcebinary = 0;
rpmhead->cnt = sigcnt;
rpmhead->dcnt = sigdsize;
rpmhead->dp = rpmhead->data + sigcnt * 16;
}
+static inline void record_share(struct parsedata *pd, Id handle, Id name, Id evr, Id arch)
+{
+ Repo *repo = pd->repo;
+ int i = handle - repo->start;
+ if (i >= pd->nshare)
+ {
+ pd->share_with = solv_realloc2(pd->share_with, i + 256, sizeof(*pd->share_with));
+ memset(pd->share_with + pd->nshare, 0, (i + 256 - pd->nshare) * sizeof(*pd->share_with));
+ pd->nshare = i + 256;
+ }
+ pd->share_with[i].name = name;
+ pd->share_with[i].evr = evr;
+ pd->share_with[i].arch = arch;
+}
+
+static void process_shares(struct parsedata *pd)
+{
+ Pool *pool = pd->pool;
+ Repo *repo = pd->repo;
+ Repodata *data = pd->data;
+ int i, last_found;
+ Map keyidmap;
+
+ map_init(&keyidmap, data->nkeys);
+ for (i = 1; i < data->nkeys; i++)
+ {
+ Id keyname = data->keys[i].name;
+ if (keyname == SOLVABLE_INSTALLSIZE || keyname == SOLVABLE_DISKUSAGE || keyname == SOLVABLE_FILELIST)
+ continue;
+ if (keyname == SOLVABLE_MEDIADIR || keyname == SOLVABLE_MEDIAFILE || keyname == SOLVABLE_MEDIANR)
+ continue;
+ if (keyname == SOLVABLE_DOWNLOADSIZE || keyname == SOLVABLE_CHECKSUM)
+ continue;
+ if (keyname == SOLVABLE_SOURCENAME || keyname == SOLVABLE_SOURCEARCH || keyname == SOLVABLE_SOURCEEVR)
+ continue;
+ if (keyname == SOLVABLE_PKGID || keyname == SOLVABLE_HDRID || keyname == SOLVABLE_LEADSIGID)
+ continue;
+ if (keyname == SUSETAGS_SHARE_NAME || keyname == SUSETAGS_SHARE_EVR || keyname == SUSETAGS_SHARE_ARCH)
+ continue;
+ MAPSET(&keyidmap, i);
+ }
+ last_found = 0;
+ for (i = 0; i < pd->nshare; i++)
+ {
+ unsigned int n, nn;
+ Solvable *found = 0;
+ if (!pd->share_with[i].name)
+ continue;
+ for (n = repo->start, nn = repo->start + last_found; n < repo->end; n++, nn++)
+ {
+ if (nn >= repo->end)
+ nn = repo->start;
+ found = pool->solvables + nn;
+ if (found->repo == repo
+ && found->name == pd->share_with[i].name
+ && found->evr == pd->share_with[i].evr
+ && found->arch == pd->share_with[i].arch)
+ {
+ last_found = nn - repo->start;
+ break;
+ }
+ }
+ if (n != repo->end)
+ repodata_merge_some_attrs(data, repo->start + i, repo->start + last_found, &keyidmap, 0);
+ }
+ pd->share_with = solv_free(pd->share_with);
+ pd->nshare = 0;
+ map_free(&keyidmap);
+}
+
+
/*
* parse susetags
*
int intag = 0;
int intag_linestart = 0;
int cummulate = 0;
- int indesc = 0;
+ int notfound = 0;
int indelta = 0;
int last_found_pack = 0;
Id first_new_pkg = 0;
if ((flags & (SUSETAGS_EXTEND|REPO_EXTEND_SOLVABLES)) != 0 && repo->nrepodata)
{
joinhash = joinhash_init(repo, &joinhashm);
- indesc = 1;
}
data = repo_add_repodata(repo, flags);
arch = lookup_shared_id(sdata, p, SUSETAGS_SHARE_ARCH, pool->solvables[p].arch, sdata == data);
if (!arch)
continue;
- if (p - repo->start >= pd.nshare)
- {
- pd.share_with = solv_realloc2(pd.share_with, p - repo->start + 256, sizeof(*pd.share_with));
- memset(pd.share_with + pd.nshare, 0, (p - repo->start + 256 - pd.nshare) * sizeof(*pd.share_with));
- pd.nshare = p - repo->start + 256;
- }
- pd.share_with[p - repo->start].name = name;
- pd.share_with[p - repo->start].evr = evr;
- pd.share_with[p - repo->start].arch = arch;
+ record_share(&pd, p, name, evr, arch);
}
}
}
tag = tag_from_string(line);
- if (indelta)
- {
- /* Example:
- =Dlt: subversion 1.6.16 1.3.1 i586
- =Dsq: subversion 1.6.15 4.2 i586 d57b3fc86e7a2f73796e8e35b96fa86212c910
- =Cks: SHA1 14a8410cf741856a5d70d89dab62984dba6a1ca7
- =Loc: 1 subversion-1.6.15_1.6.16-4.2_1.3.1.i586.delta.rpm
- =Siz: 81558
- */
- switch (tag)
- {
- case CTAG('=', 'D', 's', 'q'):
- {
- Id evr;
- if (split(line + 5, sp, 5) != 5)
- continue;
- repodata_set_id(data, handle, DELTA_SEQ_NAME, pool_str2id(pool, sp[0], 1));
- evr = toevr(pool, &pd, sp[1], sp[2]);
- repodata_set_id(data, handle, DELTA_SEQ_EVR, evr);
- /* repodata_set_id(data, handle, DELTA_SEQ_ARCH, pool_str2id(pool, sp[3], 1)); */
- repodata_set_str(data, handle, DELTA_SEQ_NUM, sp[4]);
- repodata_set_id(data, handle, DELTA_BASE_EVR, evr);
- continue;
- }
- case CTAG('=', 'C', 'k', 's'):
- set_checksum(&pd, data, handle, DELTA_CHECKSUM, line + 6);
- continue;
- case CTAG('=', 'L', 'o', 'c'):
- {
- int i = split(line + 6, sp, 3);
- if (i != 2 && i != 3)
- {
- pd.ret = pool_error(pool, -1, "susetags: line %d: bad location line '%s'\n", pd.lineno, line);
- continue;
- }
- repodata_set_deltalocation(data, handle, atoi(sp[0]), i == 3 ? sp[2] : 0, sp[1]);
- continue;
- }
- case CTAG('=', 'S', 'i', 'z'):
- if (split(line + 6, sp, 3) == 2)
- repodata_set_num(data, handle, DELTA_DOWNLOADSIZE, strtoull(sp[0], 0, 10));
- continue;
- case CTAG('=', 'P', 'k', 'g'):
- case CTAG('=', 'P', 'a', 't'):
- case CTAG('=', 'D', 'l', 't'):
- handle = 0;
- indelta = 0;
- break;
- default:
- pool_debug(pool, SOLV_ERROR, "susetags: unknown line: %d: %s\n", pd.lineno, line);
- continue;
- }
- }
-
- /*
- * start of (next) package or pattern or delta
- *
- * =Pkg: <name> <version> <release> <architecture>
- * (=Pat: ...)
- */
- if (tag == CTAG('=', 'D', 'l', 't'))
- {
+ /* handle global tags and tags that start a new section */
+ switch (tag)
+ {
+ case CTAG('=', 'V', 'e', 'r'):
+ /* start of a new file */
if (s)
finish_solvable(&pd, s, freshens);
s = 0;
- pd.kind = 0;
- if (split(line + 5, sp, 5) != 4)
+ handle = 0;
+ freshens = 0;
+ indelta = 0;
+ notfound = 0;
+ last_found_pack = 0;
+ if (createdpkgs)
{
- pd.ret = pool_error(pool, -1, "susetags: line %d: bad line '%s'\n", pd.lineno, line);
- break;
+ solv_free(joinhash);
+ joinhash = joinhash_init(repo, &joinhashm);
+ createdpkgs = 0;
}
- handle = repodata_new_handle(data);
- repodata_set_id(data, handle, DELTA_PACKAGE_NAME, pool_str2id(pool, sp[0], 1));
- repodata_set_id(data, handle, DELTA_PACKAGE_EVR, toevr(pool, &pd, sp[1], sp[2]));
- repodata_set_id(data, handle, DELTA_PACKAGE_ARCH, pool_str2id(pool, sp[3], 1));
- repodata_add_flexarray(data, SOLVID_META, REPOSITORY_DELTAINFO, handle);
- indelta = 1;
continue;
- }
- if (tag == CTAG('=', 'P', 'k', 'g')
- || tag == CTAG('=', 'P', 'a', 't'))
- {
- /* If we have an old solvable, complete it by filling in some
- default stuff. */
+
+ case CTAG('=', 'L', 'a', 'n'):
+ /* define language of the following material */
+ pd.language = solv_free(pd.language);
+ memset(pd.langcache, 0, sizeof(pd.langcache));
+ if (line[6])
+ pd.language = solv_strdup(line + 6);
+ continue;
+
+ case CTAG('=', 'P', 'k', 'g'): /* start of a package */
+ case CTAG('=', 'P', 'a', 't'): /* start of a pattern */
+ case CTAG('=', 'D', 'l', 't'): /* start of a delta */
+ /* =Pkg: <name> <version> <release> <architecture> */
+ /* If we have an old solvable, complete it by filling in some default stuff. */
if (s)
finish_solvable(&pd, s, freshens);
+ s = 0;
+ handle = 0;
+ freshens = 0;
+ indelta = 0;
+ notfound = 0;
- /*
- * define kind
- */
-
+ /* define kind */
pd.kind = 0;
- if (line[3] == 't')
+ if (tag == CTAG('=', 'P', 'a', 't'))
pd.kind = "pattern";
- /*
- * parse nevra
- */
-
+ /* parse nevra */
if (split(line + 5, sp, 5) != 4)
{
pd.ret = pool_error(pool, -1, "susetags: line %d: bad line '%s'\n", pd.lineno, line);
break;
}
- s = 0;
- freshens = 0;
+
+ if (tag == CTAG('=', 'D', 'l', 't'))
+ {
+ /* start new delta */
+ handle = repodata_new_handle(data);
+ repodata_set_id(data, handle, DELTA_PACKAGE_NAME, pool_str2id(pool, sp[0], 1));
+ repodata_set_id(data, handle, DELTA_PACKAGE_EVR, toevr(pool, &pd, sp[1], sp[2]));
+ repodata_set_id(data, handle, DELTA_PACKAGE_ARCH, pool_str2id(pool, sp[3], 1));
+ repodata_add_flexarray(data, SOLVID_META, REPOSITORY_DELTAINFO, handle);
+ indelta = 1;
+ continue;
+ }
if (joinhash)
{
/* data join operation. find solvable matching name/arch/evr and
* add data to it */
- Id name, evr, arch;
+ Id name, arch;
/* we don't use the create flag here as a simple pre-check for existance */
if (pd.kind)
name = pool_str2id(pool, join2(&pd.jd, pd.kind, ":", sp[0]), 0);
else
name = pool_str2id(pool, sp[0], 0);
- evr = toevr(pool, &pd, sp[1], sp[2]);
arch = pool_str2id(pool, sp[3], 0);
if (name && arch)
{
Id start = (flags & REPO_EXTEND_SOLVABLES) ? 0 : first_new_pkg;
+ Id evr = toevr(pool, &pd, sp[1], sp[2]);
if (repo->start + last_found_pack + 1 >= start && repo->start + last_found_pack + 1 < repo->end)
{
s = pool->solvables + repo->start + last_found_pack + 1;
}
/* do not create new packages in EXTEND_SOLVABLES mode */
if (!s && (flags & REPO_EXTEND_SOLVABLES) != 0)
- continue;
+ {
+ notfound = 1;
+ continue;
+ }
/* fallthrough to package creation */
}
if (!s)
first_new_pkg = s - pool->solvables;
createdpkgs = 1;
}
+ handle = s - pool->solvables;
last_found_pack = (s - pool->solvables) - repo->start;
- if (data)
- handle = s - pool->solvables;
+ continue;
+
+ default:
+ break;
}
- /* If we have no current solvable to add to, ignore all further lines
- for it. Probably invalid input data in the second set of
- solvables. */
- if (indesc >= 2 && !s)
- {
+ /* handle delta tags */
+ if (indelta)
+ {
+ /* Example:
+ =Dlt: subversion 1.6.16 1.3.1 i586
+ =Dsq: subversion 1.6.15 4.2 i586 d57b3fc86e7a2f73796e8e35b96fa86212c910
+ =Cks: SHA1 14a8410cf741856a5d70d89dab62984dba6a1ca7
+ =Loc: 1 subversion-1.6.15_1.6.16-4.2_1.3.1.i586.delta.rpm
+ =Siz: 81558
+ */
+ switch (tag)
+ {
+ case CTAG('=', 'D', 's', 'q'):
+ {
+ Id evr;
+ if (split(line + 5, sp, 5) != 5)
+ continue;
+ repodata_set_id(data, handle, DELTA_SEQ_NAME, pool_str2id(pool, sp[0], 1));
+ evr = toevr(pool, &pd, sp[1], sp[2]);
+ repodata_set_id(data, handle, DELTA_SEQ_EVR, evr);
+ /* repodata_set_id(data, handle, DELTA_SEQ_ARCH, pool_str2id(pool, sp[3], 1)); */
+ repodata_set_str(data, handle, DELTA_SEQ_NUM, sp[4]);
+ repodata_set_id(data, handle, DELTA_BASE_EVR, evr);
+ continue;
+ }
+ case CTAG('=', 'C', 'k', 's'):
+ set_checksum(&pd, data, handle, DELTA_CHECKSUM, line + 6);
+ continue;
+ case CTAG('=', 'L', 'o', 'c'):
+ {
+ int i = split(line + 6, sp, 3);
+ if (i != 2 && i != 3)
+ {
+ pd.ret = pool_error(pool, -1, "susetags: line %d: bad location line '%s'\n", pd.lineno, line);
+ continue;
+ }
+ repodata_set_deltalocation(data, handle, atoi(sp[0]), i == 3 ? sp[2] : 0, sp[1]);
+ continue;
+ }
+ case CTAG('=', 'S', 'i', 'z'):
+ if (split(line + 6, sp, 3) == 2)
+ repodata_set_num(data, handle, DELTA_DOWNLOADSIZE, strtoull(sp[0], 0, 10));
+ continue;
+ default:
+ pool_debug(pool, SOLV_WARN, "susetags: unknown line: %d: %s\n", pd.lineno, line);
+ continue;
+ }
+ }
+
+ /* we need a solvable for all other tags */
+ if (!s)
+ {
+ if (notfound)
+ continue; /* did not find the solvable to extend */
#if 0
- pool_debug(pool, SOLV_ERROR, "susetags: huh %d: %s?\n", pd.lineno, line);
+ pool_debug(pool, SOLV_WARN, "susetags: stray line: %d: %s\n", pd.lineno, line);
#endif
continue;
}
+
switch (tag)
{
case CTAG('=', 'P', 'r', 'v'): /* provides */
continue;
case CTAG('=', 'P', 'r', 'q'): /* pre-requires / packages required */
if (pd.kind)
- {
- s->requires = adddep(pool, &pd, s->requires, line, 0, 0); /* patterns: a required package */
- }
+ s->requires = adddep(pool, &pd, s->requires, line, 0, 0); /* pattern: package requires */
else
- s->requires = adddep(pool, &pd, s->requires, line, SOLVABLE_PREREQMARKER, 0); /* package: pre-requires */
+ s->requires = adddep(pool, &pd, s->requires, line, SOLVABLE_PREREQMARKER, 0); /* pre-requires */
continue;
case CTAG('=', 'O', 'b', 's'): /* obsoletes */
s->obsoletes = adddep(pool, &pd, s->obsoletes, line, 0, pd.kind);
case CTAG('=', 'P', 'e', 'n'): /* pattern: package enhances */
s->enhances = adddep(pool, &pd, s->enhances, line, 0, 0);
continue;
- case CTAG('=', 'V', 'e', 'r'): /* - version - */
- last_found_pack = 0;
- handle = 0;
- indesc++;
- if (createdpkgs)
- {
- solv_free(joinhash);
- joinhash = joinhash_init(repo, &joinhashm);
- createdpkgs = 0;
- }
- continue;
case CTAG('=', 'V', 'n', 'd'): /* vendor */
s->vendor = pool_str2id(pool, line + 6, 1);
continue;
k = atoi(line + 6);
if (k || !strcasecmp(line + 6, "true"))
repodata_set_void(data, handle, SOLVABLE_ISVISIBLE);
+ continue;
}
- continue;
case CTAG('=', 'S', 'h', 'r'):
{
Id name, evr, arch;
name = pool_str2id(pool, sp[0], 1);
evr = toevr(pool, &pd, sp[1], sp[2]);
arch = pool_str2id(pool, sp[3], 1);
- if (last_found_pack >= pd.nshare)
- {
- pd.share_with = solv_realloc2(pd.share_with, last_found_pack + 256, sizeof(*pd.share_with));
- memset(pd.share_with + pd.nshare, 0, (last_found_pack + 256 - pd.nshare) * sizeof(*pd.share_with));
- pd.nshare = last_found_pack + 256;
- }
- pd.share_with[last_found_pack].name = name;
- pd.share_with[last_found_pack].evr = evr;
- pd.share_with[last_found_pack].arch = arch;
+ record_share(&pd, handle, name, evr, arch);
if ((flags & SUSETAGS_RECORD_SHARES) != 0)
{
if (s->name == name)
case CTAG('=', 'C', 'k', 's'):
set_checksum(&pd, data, handle, SOLVABLE_CHECKSUM, line + 6);
break;
- case CTAG('=', 'L', 'a', 'n'):
- pd.language = solv_free(pd.language);
- memset(pd.langcache, 0, sizeof(pd.langcache));
- if (line[6])
- pd.language = solv_strdup(line + 6);
- break;
case CTAG('=', 'F', 'l', 's'):
{
}
break;
- case CTAG('=', 'P', 'a', 't'):
- case CTAG('=', 'P', 'k', 'g'):
- break;
-
default:
#if 0
pool_debug(pool, SOLV_WARN, "susetags: unknown line: %d: %s\n", pd.lineno, line);
#endif
break;
}
-
}
if (s)
finish_solvable(&pd, s, freshens);
solv_free(pd.filelist);
- /* Shared attributes
- * (e.g. multiple binaries built from same source)
- */
+ /* process shared attributes (e.g. multiple binaries built from same source) */
if (pd.nshare)
- {
- int i, last_found;
- Map keyidmap;
-
- map_init(&keyidmap, data->nkeys);
- for (i = 1; i < data->nkeys; i++)
- {
- Id keyname = data->keys[i].name;
- if (keyname == SOLVABLE_INSTALLSIZE || keyname == SOLVABLE_DISKUSAGE || keyname == SOLVABLE_FILELIST)
- continue;
- if (keyname == SOLVABLE_MEDIADIR || keyname == SOLVABLE_MEDIAFILE || keyname == SOLVABLE_MEDIANR)
- continue;
- if (keyname == SOLVABLE_DOWNLOADSIZE || keyname == SOLVABLE_CHECKSUM)
- continue;
- if (keyname == SOLVABLE_SOURCENAME || keyname == SOLVABLE_SOURCEARCH || keyname == SOLVABLE_SOURCEEVR)
- continue;
- if (keyname == SOLVABLE_PKGID || keyname == SOLVABLE_HDRID || keyname == SOLVABLE_LEADSIGID)
- continue;
- if (keyname == SUSETAGS_SHARE_NAME || keyname == SUSETAGS_SHARE_EVR || keyname == SUSETAGS_SHARE_ARCH)
- continue;
- MAPSET(&keyidmap, i);
- }
- last_found = 0;
- for (i = 0; i < pd.nshare; i++)
- {
- unsigned int n, nn;
- Solvable *found = 0;
- if (!pd.share_with[i].name)
- continue;
- for (n = repo->start, nn = repo->start + last_found; n < repo->end; n++, nn++)
- {
- if (nn >= repo->end)
- nn = repo->start;
- found = pool->solvables + nn;
- if (found->repo == repo
- && found->name == pd.share_with[i].name
- && found->evr == pd.share_with[i].evr
- && found->arch == pd.share_with[i].arch)
- {
- last_found = nn - repo->start;
- break;
- }
- }
- if (n != repo->end)
- repodata_merge_some_attrs(data, repo->start + i, repo->start + last_found, &keyidmap, 0);
- }
- free(pd.share_with);
- map_free(&keyidmap);
- }
+ process_shares(&pd);
solv_free(joinhash);
repodata_free_dircache(data);
{ REL_AND, "&" },
{ REL_OR , "|" },
{ REL_WITH , "+" },
+ { REL_WITHOUT , "-" },
{ REL_NAMESPACE , "<NAMESPACE>" },
{ REL_ARCH, "." },
{ REL_MULTIARCH, "<MULTIARCH>" },
{ REL_KIND, "<KIND>" },
{ REL_ELSE, "<ELSE>" },
{ REL_ERROR, "<ERROR>" },
+ { REL_UNLESS, "<UNLESS>" },
{ REL_LT, "<" },
{ 0, 0 }
};
-------------------------------------------------------------------
+Thu Sep 7 16:18:20 CEST 2017 - mls@suse.de
+
+- expose solver_get_recommendations in bindings
+- fix bug in solver_prune_to_highest_prio_per_name resulting in
+ bad solver_get_recommendations output
+- support 'without' and 'unless' dependencies
+- fix yumobs rule generation bug
+- Use same heuristic as upstream to determine src rpms
+- bump version to 0.6.29
+
+-------------------------------------------------------------------
Fri Jun 30 16:37:31 CEST 2017 - mls@suse.de
- make peace with newer perl versions
{
for (;;)
{
- if (rd->flags == REL_AND || rd->flags == REL_COND) /* those two are the complex ones */
+ if (rd->flags == REL_AND || rd->flags == REL_COND || rd->flags == REL_UNLESS) /* those two are the complex ones */
return 1;
if (rd->flags != REL_OR)
return 0;
return -1;
}
+/* distributive property: (a1*a2 + b1*b2) * (c1*c2 + d1*d2) =
+ a1*a2*c1*c2 + a1*a2*d1*d2 + b1*b2*c1*c2 + b1*b2*d1*d2 */
+static int
+distribute_depblocks(Pool *pool, Queue *bq, int bqcnt, int bqcnt2, int flags)
+{
+ int i, j, bqcnt3;
+#ifdef CPLXDEBUG
+ printf("COMPLEX DISTRIBUTE %d %d %d\n", bqcnt, bqcnt2, bq->count);
+#endif
+ bqcnt2 = expand_simpledeps(pool, bq, bqcnt, bqcnt2);
+ bqcnt3 = bq->count;
+ for (i = bqcnt; i < bqcnt2; i++)
+ {
+ for (j = bqcnt2; j < bqcnt3; j++)
+ {
+ int a, b;
+ int bqcnt4 = bq->count;
+ int k = i;
+
+ /* mix i block with j block, both blocks are sorted */
+ while (bq->elements[k] && bq->elements[j])
+ {
+ if (bq->elements[k] < bq->elements[j])
+ queue_push(bq, bq->elements[k++]);
+ else
+ {
+ if (bq->elements[k] == bq->elements[j])
+ k++;
+ queue_push(bq, bq->elements[j++]);
+ }
+ }
+ while (bq->elements[j])
+ queue_push(bq, bq->elements[j++]);
+ while (bq->elements[k])
+ queue_push(bq, bq->elements[k++]);
+
+ /* block is finished, check for A + -A */
+ for (a = bqcnt4, b = bq->count - 1; a < b; )
+ {
+ if (-bq->elements[a] == bq->elements[b])
+ break;
+ if (-bq->elements[a] > bq->elements[b])
+ a++;
+ else
+ b--;
+ }
+ if (a < b)
+ queue_truncate(bq, bqcnt4); /* ignore this block */
+ else
+ queue_push(bq, 0); /* finish block */
+ }
+ /* advance to next block */
+ while (bq->elements[i])
+ i++;
+ }
+ queue_deleten(bq, bqcnt, bqcnt3 - bqcnt);
+ if (bqcnt == bq->count)
+ return flags & CPLXDEPS_TODNF ? 0 : 1;
+ return -1;
+}
+
+static int normalize_dep(Pool *pool, Id dep, Queue *bq, int flags);
+
+static int
+normalize_dep_or(Pool *pool, Id dep1, Id dep2, Queue *bq, int flags, int invflags)
+{
+ int r1, r2, bqcnt2, bqcnt = bq->count;
+ r1 = normalize_dep(pool, dep1, bq, flags);
+ if (r1 == 1)
+ return 1; /* early exit */
+ bqcnt2 = bq->count;
+ r2 = normalize_dep(pool, dep2, bq, flags ^ invflags);
+ if (invflags)
+ r2 = invert_depblocks(pool, bq, bqcnt2, r2);
+ if (r1 == 1 || r2 == 1)
+ {
+ queue_truncate(bq, bqcnt);
+ return 1;
+ }
+ if (r1 == 0)
+ return r2;
+ if (r2 == 0)
+ return r1;
+ if ((flags & CPLXDEPS_TODNF) == 0)
+ return distribute_depblocks(pool, bq, bqcnt, bqcnt2, flags);
+ return -1;
+}
+
+static int
+normalize_dep_and(Pool *pool, Id dep1, Id dep2, Queue *bq, int flags, int invflags)
+{
+ int r1, r2, bqcnt2, bqcnt = bq->count;
+ r1 = normalize_dep(pool, dep1, bq, flags);
+ if (r1 == 0)
+ return 0; /* early exit */
+ bqcnt2 = bq->count;
+ r2 = normalize_dep(pool, dep2, bq, flags ^ invflags);
+ if (invflags)
+ r2 = invert_depblocks(pool, bq, bqcnt2, r2);
+ if (r1 == 0 || r2 == 0)
+ {
+ queue_truncate(bq, bqcnt);
+ return 0;
+ }
+ if (r1 == 1)
+ return r2;
+ if (r2 == 1)
+ return r1;
+ if ((flags & CPLXDEPS_TODNF) != 0)
+ return distribute_depblocks(pool, bq, bqcnt, bqcnt2, flags);
+ return -1;
+}
+
+static int
+normalize_dep_if_else(Pool *pool, Id dep1, Id dep2, Id dep3, Queue *bq, int flags)
+{
+ /* A IF (B ELSE C) -> (A OR ~B) AND (C OR B) */
+ int r1, r2, bqcnt2, bqcnt = bq->count;
+ r1 = normalize_dep_or(pool, dep1, dep2, bq, flags, CPLXDEPS_TODNF);
+ if (r1 == 0)
+ return 0; /* early exit */
+ bqcnt2 = bq->count;
+ r2 = normalize_dep_or(pool, dep2, dep3, bq, flags, 0);
+ if (r1 == 0 || r2 == 0)
+ {
+ queue_truncate(bq, bqcnt);
+ return 0;
+ }
+ if (r1 == 1)
+ return r2;
+ if (r2 == 1)
+ return r1;
+ if ((flags & CPLXDEPS_TODNF) != 0)
+ return distribute_depblocks(pool, bq, bqcnt, bqcnt2, flags);
+ return -1;
+}
+
+static int
+normalize_dep_unless_else(Pool *pool, Id dep1, Id dep2, Id dep3, Queue *bq, int flags)
+{
+ /* A UNLESS (B ELSE C) -> (A AND ~B) OR (C AND B) */
+ int r1, r2, bqcnt2, bqcnt = bq->count;
+ r1 = normalize_dep_and(pool, dep1, dep2, bq, flags, CPLXDEPS_TODNF);
+ if (r1 == 1)
+ return 1; /* early exit */
+ bqcnt2 = bq->count;
+ r2 = normalize_dep_and(pool, dep2, dep3, bq, flags, 0);
+ if (r1 == 1 || r2 == 1)
+ {
+ queue_truncate(bq, bqcnt);
+ return 1;
+ }
+ if (r1 == 0)
+ return r2;
+ if (r2 == 0)
+ return r1;
+ if ((flags & CPLXDEPS_TODNF) == 0)
+ return distribute_depblocks(pool, bq, bqcnt, bqcnt2, flags);
+ return -1;
+}
+
/*
* returns:
* 0: no blocks
static int
normalize_dep(Pool *pool, Id dep, Queue *bq, int flags)
{
- int bqcnt = bq->count;
- int bqcnt2;
- int todnf = flags & CPLXDEPS_TODNF ? 1 : 0;
Id p, dp;
+ int bqcnt;
-#ifdef CPLXDEBUG
- printf("normalize_dep %s todnf:%d\n", pool_dep2str(pool, dep), todnf);
-#endif
if (pool_is_complex_dep(pool, dep))
{
Reldep *rd = GETRELDEP(pool, dep);
- if (rd->flags == REL_AND || rd->flags == REL_OR || rd->flags == REL_COND)
+ if (rd->flags == REL_COND)
{
- int rdflags = rd->flags;
- Id name = rd->name;
Id evr = rd->evr;
- int r, mode;
-
- if (rdflags == REL_COND)
- {
- /* check for relly complex ELSE case */
- if (ISRELDEP(evr))
- {
- Reldep *rd2 = GETRELDEP(pool, evr);
- if (rd2->flags == REL_ELSE)
- {
- int r2;
- /* really complex case */
- if ((flags & CPLXDEPS_ELSE_MASK) == CPLXDEPS_ELSE_AND_1)
- {
- /* A OR ~B */
- rdflags = REL_COND;
- evr = rd2->name;
- }
- else if ((flags & CPLXDEPS_ELSE_MASK) == CPLXDEPS_ELSE_AND_2)
- {
- /* C OR B */
- rdflags = REL_OR;
- name = rd2->evr;
- evr = rd2->name;
- }
- else if ((flags & CPLXDEPS_ELSE_MASK) == CPLXDEPS_ELSE_OR_1)
- {
- /* A AND B */
- rdflags = REL_AND;
- evr = rd2->name;
- }
- else if ((flags & CPLXDEPS_ELSE_MASK) == CPLXDEPS_ELSE_OR_2)
- {
- /* A AND C */
- rdflags = REL_AND;
- evr = rd2->evr;
- }
- else if ((flags & CPLXDEPS_ELSE_MASK) == CPLXDEPS_ELSE_OR_3)
- {
- /* C AND ~B */
- rdflags = REL_ELSE;
- name = rd2->evr;
- evr = rd2->name;
- }
- else if (!todnf)
- {
- /* we want AND: A IF (B ELSE C) -> (A OR ~B) AND (C OR B) */
- r = normalize_dep(pool, dep, bq, flags | CPLXDEPS_ELSE_AND_1);
- if (r == 0 && (flags & CPLXDEPS_DONTFIX) == 0)
- return 0;
- r2 = normalize_dep(pool, dep, bq, flags | CPLXDEPS_ELSE_AND_2);
- if (r2 == 0 && (flags & CPLXDEPS_DONTFIX) == 0)
- {
- queue_truncate(bq, bqcnt);
- return 0;
- }
- if (r == -1 || r2 == -1)
- return -1;
- return r == 1 || r2 == 1 ? 1 : 0;
- }
- else
- {
- int r2, r3;
- /* we want OR: A IF (B ELSE C) -> (A AND B) OR (A AND C) OR (~B AND C) */
- r = normalize_dep(pool, dep, bq, flags | CPLXDEPS_ELSE_OR_1);
- if (r == 1)
- return 1;
- r2 = normalize_dep(pool, dep, bq, flags | CPLXDEPS_ELSE_OR_2);
- if (r2 == 1)
- {
- queue_truncate(bq, bqcnt);
- return 1;
- }
- r3 = normalize_dep(pool, dep, bq, flags | CPLXDEPS_ELSE_OR_3);
- if (r3 == 1)
- {
- queue_truncate(bq, bqcnt);
- return 1;
- }
- if (r == -1 || r2 == -1 || r3 == -1)
- return -1;
- return 0;
- }
- }
- }
- }
- mode = rdflags == REL_AND || rdflags == REL_ELSE ? 0 : 1;
-
- /* get blocks of first argument */
- r = normalize_dep(pool, name, bq, flags);
- if (r == 0)
- {
- if (rdflags == REL_ELSE)
- return 0;
- if (rdflags == REL_AND && (flags & CPLXDEPS_DONTFIX) == 0)
- return 0;
- if (rdflags == REL_COND)
- {
- r = normalize_dep(pool, evr, bq, (flags ^ CPLXDEPS_TODNF) & ~CPLXDEPS_DONTFIX);
- return invert_depblocks(pool, bq, bqcnt, r); /* invert block for COND */
- }
- return normalize_dep(pool, evr, bq, flags);
- }
- if (r == 1)
- {
- if (rdflags == REL_ELSE)
- {
- r = normalize_dep(pool, evr, bq, (flags ^ CPLXDEPS_TODNF) & ~CPLXDEPS_DONTFIX);
- return invert_depblocks(pool, bq, bqcnt, r); /* invert block for ELSE */
- }
- if (rdflags == REL_OR || rdflags == REL_COND)
- return 1;
- return normalize_dep(pool, evr, bq, flags);
- }
-
- /* get blocks of second argument */
- bqcnt2 = bq->count;
- /* COND is OR with NEG on evr block, so we invert the todnf flag in that case */
- r = normalize_dep(pool, evr, bq, rdflags == REL_COND || rdflags == REL_ELSE ? ((flags ^ CPLXDEPS_TODNF) & ~CPLXDEPS_DONTFIX) : flags);
- if (rdflags == REL_COND || rdflags == REL_ELSE)
- r = invert_depblocks(pool, bq, bqcnt2, r); /* invert 2nd block */
- if (r == 0)
+ if (ISRELDEP(evr))
{
- if (rdflags == REL_OR)
- return -1;
- if (rdflags == REL_AND && (flags & CPLXDEPS_DONTFIX) != 0)
- return -1;
- queue_truncate(bq, bqcnt);
- return 0;
- }
- if (r == 1)
- {
- if (rdflags == REL_COND || rdflags == REL_OR)
- {
- queue_truncate(bq, bqcnt);
- return 1;
- }
- return -1;
- }
- if (mode == todnf)
- {
- /* simple case: just join em. nothing more to do here. */
-#ifdef CPLXDEBUG
- printf("SIMPLE JOIN %d %d %d\n", bqcnt, bqcnt2, bq->count);
-#endif
- return -1;
+ Reldep *rd2 = GETRELDEP(pool, evr);
+ if (rd2->flags == REL_ELSE)
+ return normalize_dep_if_else(pool, rd->name, rd2->name, rd2->evr, bq, flags);
}
- else
+ return normalize_dep_or(pool, rd->name, rd->evr, bq, flags, CPLXDEPS_TODNF);
+ }
+ if (rd->flags == REL_UNLESS)
+ {
+ Id evr = rd->evr;
+ if (ISRELDEP(evr))
{
- /* complex case: mix em */
- int i, j, bqcnt3;
-#ifdef CPLXDEBUG
- printf("COMPLEX JOIN %d %d %d\n", bqcnt, bqcnt2, bq->count);
-#endif
- bqcnt2 = expand_simpledeps(pool, bq, bqcnt, bqcnt2);
- bqcnt3 = bq->count;
- for (i = bqcnt; i < bqcnt2; i++)
- {
- for (j = bqcnt2; j < bqcnt3; j++)
- {
- int a, b;
- int bqcnt4 = bq->count;
- int k = i;
-
- /* mix i block with j block, both blocks are sorted */
- while (bq->elements[k] && bq->elements[j])
- {
- if (bq->elements[k] < bq->elements[j])
- queue_push(bq, bq->elements[k++]);
- else
- {
- if (bq->elements[k] == bq->elements[j])
- k++;
- queue_push(bq, bq->elements[j++]);
- }
- }
- while (bq->elements[j])
- queue_push(bq, bq->elements[j++]);
- while (bq->elements[k])
- queue_push(bq, bq->elements[k++]);
-
- /* block is finished, check for A + -A */
- for (a = bqcnt4, b = bq->count - 1; a < b; )
- {
- if (-bq->elements[a] == bq->elements[b])
- break;
- if (-bq->elements[a] > bq->elements[b])
- a++;
- else
- b--;
- }
- if (a < b)
- queue_truncate(bq, bqcnt4); /* ignore this block */
- else
- queue_push(bq, 0); /* finish block */
- }
- /* advance to next block */
- while (bq->elements[i])
- i++;
- }
- i = -1;
- if (bqcnt3 == bq->count) /* ignored all blocks? */
- i = todnf ? 0 : 1;
- queue_deleten(bq, bqcnt, bqcnt3 - bqcnt);
- return i;
+ Reldep *rd2 = GETRELDEP(pool, evr);
+ if (rd2->flags == REL_ELSE)
+ return normalize_dep_unless_else(pool, rd->name, rd2->name, rd2->evr, bq, flags);
}
+ return normalize_dep_and(pool, rd->name, rd->evr, bq, flags, CPLXDEPS_TODNF);
}
+ if (rd->flags == REL_OR)
+ return normalize_dep_or(pool, rd->name, rd->evr, bq, flags, 0);
+ if (rd->flags == REL_AND)
+ return normalize_dep_and(pool, rd->name, rd->evr, bq, flags, 0);
}
/* fallback case: just use package list */
if (!pool_match_nevr(pool, pool->solvables + p, dep))
continue;
queue_push(bq, p);
- if (todnf)
+ if ((flags & CPLXDEPS_TODNF) != 0)
queue_push(bq, 0);
}
}
- else if (todnf)
+ else if ((flags & CPLXDEPS_TODNF) != 0)
{
while ((p = pool->whatprovidesdata[dp++]) != 0)
queue_push2(bq, p, 0);
queue_push2(bq, pool->nsolvables, dp); /* not yet expanded marker + offset */
if (bq->count == bqcnt)
return 0; /* no provider */
- if (!todnf)
+ if (!(flags & CPLXDEPS_TODNF))
queue_push(bq, 0); /* finish block */
return -1;
}
while (ISRELDEP(dep))
{
Reldep *rd = GETRELDEP(pool, dep);
- if (rd->flags != REL_AND && rd->flags != REL_OR && rd->flags != REL_COND)
+ if (rd->flags != REL_AND && rd->flags != REL_OR && rd->flags != REL_COND && rd->flags != REL_UNLESS)
break;
pool_add_pos_literals_complex_dep(pool, rd->name, q, m, neg);
dep = rd->evr;
- if (rd->flags == REL_COND)
+ if (rd->flags == REL_COND || rd->flags == REL_UNLESS)
{
neg = !neg;
if (ISRELDEP(dep))
#define CPLXDEPS_NAME (1 << 3)
#define CPLXDEPS_DONTFIX (1 << 4)
-#define CPLXDEPS_ELSE_AND_1 (1 << 8)
-#define CPLXDEPS_ELSE_AND_2 (1 << 9)
-#define CPLXDEPS_ELSE_OR_1 (1 << 10)
-#define CPLXDEPS_ELSE_OR_2 (1 << 11)
-#define CPLXDEPS_ELSE_OR_3 (1 << 12)
-#define CPLXDEPS_ELSE_MASK (0x1f00)
-
#endif
{
if (pool->solvables[plist->elements[i]].name != name)
{
+ name = pool->solvables[plist->elements[i]].name;
if (pq.count > 2)
solver_prune_to_highest_prio(solv, &pq);
for (k = 0; k < pq.count; k++)
plist->elements[j++] = pq.elements[k];
queue_empty(&pq);
- queue_push(&pq, plist->elements[i]);
- name = pool->solvables[pq.elements[0]].name;
}
+ queue_push(&pq, plist->elements[i]);
}
if (pq.count > 2)
solver_prune_to_highest_prio(solv, &pq);
if (!pool_match_nevr(pool, s, name))
return 0;
return pool_match_nevr(pool, s, evr);
+ case REL_WITHOUT:
+ if (!pool_match_nevr(pool, s, name))
+ return 0;
+ return !pool_match_nevr(pool, s, evr);
case REL_MULTIARCH:
if (evr != ARCH_ANY)
return 0;
{
/* we use potentially matches for complex deps */
rd1 = GETRELDEP(pool, d1);
- if (rd1->flags == REL_AND || rd1->flags == REL_OR || rd1->flags == REL_WITH || rd1->flags == REL_COND)
+ if (rd1->flags == REL_AND || rd1->flags == REL_OR || rd1->flags == REL_WITH || rd1->flags == REL_WITHOUT || rd1->flags == REL_COND || rd1->flags == REL_UNLESS)
{
if (pool_match_dep(pool, rd1->name, d2))
return 1;
- if (rd1->flags == REL_COND && ISRELDEP(rd1->evr))
+ if ((rd1->flags == REL_COND || rd1->flags == REL_UNLESS) && ISRELDEP(rd1->evr))
{
rd1 = GETRELDEP(pool, rd1->evr);
if (rd1->flags != REL_ELSE)
return 0;
}
- if (rd1->flags != REL_COND && pool_match_dep(pool, rd1->evr, d2))
+ if (rd1->flags != REL_COND && rd1->flags != REL_UNLESS && rd1->flags != REL_WITHOUT && pool_match_dep(pool, rd1->evr, d2))
return 1;
return 0;
}
{
/* we use potentially matches for complex deps */
rd2 = GETRELDEP(pool, d2);
- if (rd2->flags == REL_AND || rd2->flags == REL_OR || rd2->flags == REL_WITH || rd2->flags == REL_COND)
+ if (rd2->flags == REL_AND || rd2->flags == REL_OR || rd2->flags == REL_WITH || rd2->flags == REL_WITHOUT || rd2->flags == REL_COND || rd2->flags == REL_UNLESS)
{
if (pool_match_dep(pool, d1, rd2->name))
return 1;
- if (rd2->flags == REL_COND && ISRELDEP(rd2->evr))
+ if ((rd2->flags == REL_COND || rd2->flags == REL_UNLESS) && ISRELDEP(rd2->evr))
{
rd2 = GETRELDEP(pool, rd2->evr);
if (rd2->flags != REL_ELSE)
return 0;
}
- if (rd2->flags != REL_COND && pool_match_dep(pool, d1, rd2->evr))
+ if (rd2->flags != REL_COND && rd2->flags != REL_UNLESS && rd2->flags != REL_WITHOUT && pool_match_dep(pool, d1, rd2->evr))
return 1;
return 0;
}
wp = 0;
}
break;
-
+ case REL_WITHOUT:
+ wp = pool_whatprovides(pool, name);
+ pp2 = pool_whatprovides_ptr(pool, evr);
+ pp = pool->whatprovidesdata + wp;
+ while ((p = *pp++) != 0)
+ {
+ for (pp3 = pp2; *pp3; pp3++)
+ if (*pp3 == p)
+ break;
+ if (!*pp3)
+ queue_push(&plist, p); /* use it */
+ else
+ wp = 0;
+ }
+ break;
case REL_AND:
case REL_OR:
case REL_COND:
- if (flags == REL_COND)
+ case REL_UNLESS:
+ if (flags == REL_COND || flags == REL_UNLESS)
{
if (ISRELDEP(evr))
{
#define REL_NAMESPACE 19
#define REL_ARCH 20
#define REL_FILECONFLICT 21
-#define REL_COND 22
+#define REL_COND 22 /* OR_NOT */
#define REL_COMPAT 23
#define REL_KIND 24 /* for filters only */
#define REL_MULTIARCH 25 /* debian multiarch annotation */
-#define REL_ELSE 26 /* only as evr part of REL_COND */
+#define REL_ELSE 26 /* only as evr part of REL_COND/REL_UNLESS */
#define REL_ERROR 27 /* parse errors and the like */
+#define REL_WITHOUT 28
+#define REL_UNLESS 29 /* AND_NOT */
#if !defined(__GNUC__) && !defined(__attribute__)
# define __attribute__(x)
continue; \
else
-#ifdef ENABLE_COMPS
-#define ISCONDDEP(id) (ISRELDEP(id) && (GETRELDEP(pool, id))->flags == REL_COND)
-#define MODIFYCONDDEP(id, tst) do { Reldep *condrd = GETRELDEP(pool, id); Id condp, condpp; FOR_PROVIDES(condrd->evr, condp, condpp) if (tst) break; id = condp ? condrd->name : 0;} while(0)
-#endif
-
#define POOL_DEBUG(type, ...) do {if ((pool->debugmask & (type)) != 0) pool_debug(pool, (type), __VA_ARGS__);} while (0)
#define IF_POOLDEBUG(type) if ((pool->debugmask & (type)) != 0)
return pool->disttype == DISTTYPE_RPM ? " or " : " | ";
case REL_WITH:
return pool->disttype == DISTTYPE_RPM ? " with " : " + ";
+ case REL_WITHOUT:
+ return pool->disttype == DISTTYPE_RPM ? " without " : " - ";
case REL_NAMESPACE:
return " NAMESPACE "; /* actually not used in dep2str */
case REL_ARCH:
return " FILECONFLICT ";
case REL_COND:
return pool->disttype == DISTTYPE_RPM ? " if " : " IF ";
+ case REL_UNLESS:
+ return pool->disttype == DISTTYPE_RPM ? " unless " : " UNLESS ";
case REL_COMPAT:
return " compat >= ";
case REL_KIND:
{
Reldep *rd = GETRELDEP(pool, id);
int rel = rd->flags;
- if (oldrel == REL_AND || oldrel == REL_OR || oldrel == REL_WITH || oldrel == REL_COND || oldrel == REL_ELSE || oldrel == -1)
- if (rel == REL_AND || rel == REL_OR || rel == REL_WITH || rel == REL_COND || rel == REL_ELSE)
- if ((oldrel != rel || rel == REL_COND || rel == REL_ELSE) && !(oldrel == REL_COND && rel == REL_ELSE))
+ if (oldrel == REL_AND || oldrel == REL_OR || oldrel == REL_WITH || oldrel == REL_WITHOUT || oldrel == REL_COND || oldrel == REL_UNLESS || oldrel == REL_ELSE || oldrel == -1)
+ if (rel == REL_AND || rel == REL_OR || rel == REL_WITH || rel == REL_WITHOUT || rel == REL_COND || rel == REL_UNLESS || rel == REL_ELSE)
+ if ((oldrel != rel || rel == REL_COND || rel == REL_UNLESS || rel == REL_ELSE) && !((oldrel == REL_COND || oldrel == REL_UNLESS) && rel == REL_ELSE))
{
*p++ = '(';
dep2strcpy(pool, p, rd->name, rd->flags);
Reldep *rd = GETRELDEP(pool, dep);
if (rd->flags >= 8)
{
- if (rd->flags == REL_COND)
+ if (rd->flags == REL_COND || rd->flags == REL_UNLESS)
return 1;
if (rd->flags == REL_AND)
{
#if 0
printf("checking yumobs for %s\n", pool_solvable2str(pool, s));
#endif
- queue_empty(&qo);
for (opp = solv->obsoletes_data + solv->obsoletes[p - installed->start]; (op = *opp++) != 0;)
{
Solvable *os = pool->solvables + op;
if (ISRELDEP(id))
{
Reldep *rd = GETRELDEP(pool, id);
- if (rd->flags == REL_AND || rd->flags == REL_OR || rd->flags == REL_WITH || rd->flags == REL_COND)
+ if (rd->flags == REL_AND || rd->flags == REL_OR || rd->flags == REL_WITH || rd->flags == REL_WITHOUT || rd->flags == REL_COND || rd->flags == REL_UNLESS)
{
if (matchdep(pool, rd->name, rname, rflags, revr, flags))
return 1;
- if (rd->flags == REL_COND && ISRELDEP(rd->evr))
+ if ((rd->flags == REL_COND || rd->flags == REL_UNLESS) && ISRELDEP(rd->evr))
{
rd = GETRELDEP(pool, rd->evr);
if (rd->flags != REL_ELSE)
return 0;
}
- if (rd->flags != REL_COND && matchdep(pool, rd->evr, rname, rflags, revr, flags))
+ if (rd->flags != REL_COND && rd->flags != REL_UNLESS && rd->flags != REL_WITHOUT && matchdep(pool, rd->evr, rname, rflags, revr, flags))
return 1;
return 0;
}
return 0;
}
+int
+solver_dep_fulfilled_cplx(Solver *solv, Reldep *rd)
+{
+ Pool *pool = solv->pool;
+ if (rd->flags == REL_COND)
+ {
+ if (ISRELDEP(rd->evr))
+ {
+ Reldep *rd2 = GETRELDEP(pool, rd->evr);
+ if (rd2->flags == REL_ELSE)
+ {
+ if (solver_dep_fulfilled(solv, rd2->name))
+ return solver_dep_fulfilled(solv, rd->name);
+ return solver_dep_fulfilled(solv, rd2->evr);
+ }
+ }
+ if (solver_dep_fulfilled(solv, rd->name))
+ return 1;
+ return !solver_dep_fulfilled(solv, rd->evr);
+ }
+ if (rd->flags == REL_UNLESS)
+ {
+ if (ISRELDEP(rd->evr))
+ {
+ Reldep *rd2 = GETRELDEP(pool, rd->evr);
+ if (rd2->flags == REL_ELSE)
+ {
+ if (!solver_dep_fulfilled(solv, rd2->name))
+ return solver_dep_fulfilled(solv, rd->name);
+ return solver_dep_fulfilled(solv, rd2->evr);
+ }
+ }
+ if (!solver_dep_fulfilled(solv, rd->name))
+ return 0;
+ return !solver_dep_fulfilled(solv, rd->evr);
+ }
+ if (rd->flags == REL_AND)
+ {
+ if (!solver_dep_fulfilled(solv, rd->name))
+ return 0;
+ return solver_dep_fulfilled(solv, rd->evr);
+ }
+ if (rd->flags == REL_OR)
+ {
+ if (solver_dep_fulfilled(solv, rd->name))
+ return 1;
+ return solver_dep_fulfilled(solv, rd->evr);
+ }
+ return 0;
+}
+
/* mirrors solver_dep_fulfilled, but returns 2 if a new package
* was involved */
return 0;
return r1 == 2 ? 2 : 1;
}
+ if (rd->flags == REL_UNLESS)
+ {
+ int r1, r2;
+ if (ISRELDEP(rd->evr))
+ {
+ Reldep *rd2 = GETRELDEP(pool, rd->evr);
+ if (rd2->flags == REL_ELSE)
+ {
+ r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->name);
+ if (r1)
+ {
+ r2 = solver_dep_fulfilled_alreadyinstalled(solv, rd2->evr);
+ return r2 && r1 == 2 ? 2 : r2;
+ }
+ return solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
+ }
+ }
+ /* A AND NOT(B) */
+ r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
+ r2 = !solver_dep_fulfilled_alreadyinstalled(solv, rd->evr);
+ if (!r1 || !r2)
+ return 0;
+ return r1 == 2 ? 2 : 1;
+ }
if (rd->flags == REL_AND)
{
int r2, r1 = solver_dep_fulfilled_alreadyinstalled(solv, rd->name);
extern void solver_reset(Solver *solv);
extern int solver_splitprovides(Solver *solv, Id dep, Map *m);
+extern int solver_dep_fulfilled_cplx(Solver *solv, Reldep *rd);
static inline int
solver_dep_fulfilled(Solver *solv, Id dep)
if (ISRELDEP(dep))
{
Reldep *rd = GETRELDEP(pool, dep);
- if (rd->flags == REL_COND)
- {
- if (ISRELDEP(rd->evr))
- {
- Reldep *rd2 = GETRELDEP(pool, rd->evr);
- if (rd2->flags == REL_ELSE)
- {
- if (solver_dep_fulfilled(solv, rd2->name))
- return solver_dep_fulfilled(solv, rd->name);
- return solver_dep_fulfilled(solv, rd2->evr);
- }
- }
- if (solver_dep_fulfilled(solv, rd->name))
- return 1;
- return !solver_dep_fulfilled(solv, rd->evr);
- }
- if (rd->flags == REL_AND)
- {
- if (!solver_dep_fulfilled(solv, rd->name))
- return 0;
- return solver_dep_fulfilled(solv, rd->evr);
- }
- if (rd->flags == REL_OR)
- {
- if (solver_dep_fulfilled(solv, rd->name))
- return 1;
- return solver_dep_fulfilled(solv, rd->evr);
- }
+ if (rd->flags == REL_COND || rd->flags == REL_UNLESS || rd->flags == REL_AND || rd->flags == REL_OR)
+ return solver_dep_fulfilled_cplx(solv, rd);
if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
return solver_splitprovides(solv, rd->evr, 0);
}
--- /dev/null
+feature complex_deps
+repo available 0 testtags <inline>
+#>=Pkg: A1 1 1 x86_64
+#>=Prv: A
+#>=Pkg: A2 1 1 x86_64
+#>=Prv: A
+#>=Pkg: B1 1 1 x86_64
+#>=Prv: B
+#>=Pkg: B2 1 1 x86_64
+#>=Prv: B
+#>=Pkg: X 1 1 x86_64
+#>=Req: A & B
+#>=Pkg: Y 1 1 x86_64
+#>=Con: A & B
+job install name X
+result rules <inline>
+#>rule job 3986285ed3e7fa05cb3367ca1e7f0d3d X-1-1.x86_64@available
+#>rule pkg 8d94817282778a96505d2865a9b6c417 B1-1-1.x86_64@available
+#>rule pkg 8d94817282778a96505d2865a9b6c417 B2-1-1.x86_64@available
+#>rule pkg 8d94817282778a96505d2865a9b6c417 -X-1-1.x86_64@available
+#>rule pkg 9294f4d070a449a787a945d757c853ac A1-1-1.x86_64@available
+#>rule pkg 9294f4d070a449a787a945d757c853ac A2-1-1.x86_64@available
+#>rule pkg 9294f4d070a449a787a945d757c853ac -X-1-1.x86_64@available
+nextjob
+job install name Y
+result rules <inline>
+#>rule job 181d7955b2179c4ffdffedf0198f4807 Y-1-1.x86_64@available
+#>rule pkg 05a449a52d4792a0b847f482f5d7b509 -A1-1-1.x86_64@available
+#>rule pkg 05a449a52d4792a0b847f482f5d7b509 -B2-1-1.x86_64@available
+#>rule pkg 05a449a52d4792a0b847f482f5d7b509 -Y-1-1.x86_64@available
+#>rule pkg 85eac3dcd30bb5f51ad50b6644455822 -A2-1-1.x86_64@available
+#>rule pkg 85eac3dcd30bb5f51ad50b6644455822 -B2-1-1.x86_64@available
+#>rule pkg 85eac3dcd30bb5f51ad50b6644455822 -Y-1-1.x86_64@available
+#>rule pkg 8611a3d851adbd063a5d34a3ad4804e6 -A1-1-1.x86_64@available
+#>rule pkg 8611a3d851adbd063a5d34a3ad4804e6 -B1-1-1.x86_64@available
+#>rule pkg 8611a3d851adbd063a5d34a3ad4804e6 -Y-1-1.x86_64@available
+#>rule pkg ba6ba0db8d7421f83f7df6cc4df6df7d -A2-1-1.x86_64@available
+#>rule pkg ba6ba0db8d7421f83f7df6cc4df6df7d -B1-1-1.x86_64@available
+#>rule pkg ba6ba0db8d7421f83f7df6cc4df6df7d -Y-1-1.x86_64@available
--- /dev/null
+feature complex_deps
+repo available 0 testtags <inline>
+#>=Pkg: A1 1 1 x86_64
+#>=Prv: A
+#>=Pkg: A2 1 1 x86_64
+#>=Prv: A
+#>=Pkg: B1 1 1 x86_64
+#>=Prv: B
+#>=Pkg: B2 1 1 x86_64
+#>=Prv: B
+#>=Pkg: C1 1 1 x86_64
+#>=Prv: C
+#>=Pkg: C2 1 1 x86_64
+#>=Prv: C
+#>=Pkg: D1 1 1 x86_64
+#>=Prv: D
+#>=Pkg: D2 1 1 x86_64
+#>=Prv: D
+#>=Pkg: X 1 1 x86_64
+#>=Req: (A & B) | (C & D)
+#>=Pkg: Y 1 1 x86_64
+#>=Con: (A & B) | (C & D)
+job install name X
+result rules <inline>
+#>rule job 3986285ed3e7fa05cb3367ca1e7f0d3d X-1-1.x86_64@available
+#>rule pkg 500f33fd32c5be8fb62896b334f580e7 B1-1-1.x86_64@available
+#>rule pkg 500f33fd32c5be8fb62896b334f580e7 B2-1-1.x86_64@available
+#>rule pkg 500f33fd32c5be8fb62896b334f580e7 D1-1-1.x86_64@available
+#>rule pkg 500f33fd32c5be8fb62896b334f580e7 D2-1-1.x86_64@available
+#>rule pkg 500f33fd32c5be8fb62896b334f580e7 -X-1-1.x86_64@available
+#>rule pkg 551b370e0a9430e9fcb2608b73b2d6f1 A1-1-1.x86_64@available
+#>rule pkg 551b370e0a9430e9fcb2608b73b2d6f1 A2-1-1.x86_64@available
+#>rule pkg 551b370e0a9430e9fcb2608b73b2d6f1 D1-1-1.x86_64@available
+#>rule pkg 551b370e0a9430e9fcb2608b73b2d6f1 D2-1-1.x86_64@available
+#>rule pkg 551b370e0a9430e9fcb2608b73b2d6f1 -X-1-1.x86_64@available
+#>rule pkg dee60af94c8ea49c9f99362dcb65806a B1-1-1.x86_64@available
+#>rule pkg dee60af94c8ea49c9f99362dcb65806a B2-1-1.x86_64@available
+#>rule pkg dee60af94c8ea49c9f99362dcb65806a C1-1-1.x86_64@available
+#>rule pkg dee60af94c8ea49c9f99362dcb65806a C2-1-1.x86_64@available
+#>rule pkg dee60af94c8ea49c9f99362dcb65806a -X-1-1.x86_64@available
+#>rule pkg e524681ade2cf622db027a5d989023c4 A1-1-1.x86_64@available
+#>rule pkg e524681ade2cf622db027a5d989023c4 A2-1-1.x86_64@available
+#>rule pkg e524681ade2cf622db027a5d989023c4 C1-1-1.x86_64@available
+#>rule pkg e524681ade2cf622db027a5d989023c4 C2-1-1.x86_64@available
+#>rule pkg e524681ade2cf622db027a5d989023c4 -X-1-1.x86_64@available
+nextjob
+job install name Y
+result rules <inline>
+#>rule job 181d7955b2179c4ffdffedf0198f4807 Y-1-1.x86_64@available
+#>rule pkg 05a449a52d4792a0b847f482f5d7b509 -A1-1-1.x86_64@available
+#>rule pkg 05a449a52d4792a0b847f482f5d7b509 -B2-1-1.x86_64@available
+#>rule pkg 05a449a52d4792a0b847f482f5d7b509 -Y-1-1.x86_64@available
+#>rule pkg 57f43a628a3173b517f444966e291dcc -C2-1-1.x86_64@available
+#>rule pkg 57f43a628a3173b517f444966e291dcc -D2-1-1.x86_64@available
+#>rule pkg 57f43a628a3173b517f444966e291dcc -Y-1-1.x86_64@available
+#>rule pkg 61248d82dae65a4a486fc7321a4e50ac -C2-1-1.x86_64@available
+#>rule pkg 61248d82dae65a4a486fc7321a4e50ac -D1-1-1.x86_64@available
+#>rule pkg 61248d82dae65a4a486fc7321a4e50ac -Y-1-1.x86_64@available
+#>rule pkg 85eac3dcd30bb5f51ad50b6644455822 -A2-1-1.x86_64@available
+#>rule pkg 85eac3dcd30bb5f51ad50b6644455822 -B2-1-1.x86_64@available
+#>rule pkg 85eac3dcd30bb5f51ad50b6644455822 -Y-1-1.x86_64@available
+#>rule pkg 8611a3d851adbd063a5d34a3ad4804e6 -A1-1-1.x86_64@available
+#>rule pkg 8611a3d851adbd063a5d34a3ad4804e6 -B1-1-1.x86_64@available
+#>rule pkg 8611a3d851adbd063a5d34a3ad4804e6 -Y-1-1.x86_64@available
+#>rule pkg 919596a70a75b1cdd73c596397bf70e7 -C1-1-1.x86_64@available
+#>rule pkg 919596a70a75b1cdd73c596397bf70e7 -D2-1-1.x86_64@available
+#>rule pkg 919596a70a75b1cdd73c596397bf70e7 -Y-1-1.x86_64@available
+#>rule pkg ba6ba0db8d7421f83f7df6cc4df6df7d -A2-1-1.x86_64@available
+#>rule pkg ba6ba0db8d7421f83f7df6cc4df6df7d -B1-1-1.x86_64@available
+#>rule pkg ba6ba0db8d7421f83f7df6cc4df6df7d -Y-1-1.x86_64@available
+#>rule pkg da2fe506ceca44a0c6eafab14af37505 -C1-1-1.x86_64@available
+#>rule pkg da2fe506ceca44a0c6eafab14af37505 -D1-1-1.x86_64@available
+#>rule pkg da2fe506ceca44a0c6eafab14af37505 -Y-1-1.x86_64@available
--- /dev/null
+feature complex_deps
+repo available 0 testtags <inline>
+#>=Pkg: A1 1 1 x86_64
+#>=Prv: A
+#>=Pkg: A2 1 1 x86_64
+#>=Prv: A
+#>=Pkg: B1 1 1 x86_64
+#>=Prv: B
+#>=Pkg: B2 1 1 x86_64
+#>=Prv: B
+#>=Pkg: X 1 1 x86_64
+#>=Req: A <IF> B
+#>=Pkg: Y 1 1 x86_64
+#>=Con: A <IF> B
+job install name X
+result rules <inline>
+#>rule job 3986285ed3e7fa05cb3367ca1e7f0d3d X-1-1.x86_64@available
+#>rule pkg 2c561cfd067b5ec806fd5c4fcd2ac761 A1-1-1.x86_64@available
+#>rule pkg 2c561cfd067b5ec806fd5c4fcd2ac761 A2-1-1.x86_64@available
+#>rule pkg 2c561cfd067b5ec806fd5c4fcd2ac761 -B1-1-1.x86_64@available
+#>rule pkg 2c561cfd067b5ec806fd5c4fcd2ac761 -X-1-1.x86_64@available
+#>rule pkg 72c9298b01fec76aae2722e2cdfdc776 A1-1-1.x86_64@available
+#>rule pkg 72c9298b01fec76aae2722e2cdfdc776 A2-1-1.x86_64@available
+#>rule pkg 72c9298b01fec76aae2722e2cdfdc776 -B2-1-1.x86_64@available
+#>rule pkg 72c9298b01fec76aae2722e2cdfdc776 -X-1-1.x86_64@available
+nextjob
+job install name Y
+result rules <inline>
+#>rule job 181d7955b2179c4ffdffedf0198f4807 Y-1-1.x86_64@available
+#>rule pkg 0fd77d3093bfb9bc85606ae155bee7e0 -A1-1-1.x86_64@available
+#>rule pkg 0fd77d3093bfb9bc85606ae155bee7e0 -Y-1-1.x86_64@available
+#>rule pkg 45e18ba2f65a39574c1f4b1c77b565ec -A2-1-1.x86_64@available
+#>rule pkg 45e18ba2f65a39574c1f4b1c77b565ec -Y-1-1.x86_64@available
+#>rule pkg 88a787532b7e170c57d67c5123982b0d B1-1-1.x86_64@available
+#>rule pkg 88a787532b7e170c57d67c5123982b0d B2-1-1.x86_64@available
+#>rule pkg 88a787532b7e170c57d67c5123982b0d -Y-1-1.x86_64@available
--- /dev/null
+feature complex_deps
+repo available 0 testtags <inline>
+#>=Pkg: A1 1 1 x86_64
+#>=Prv: A
+#>=Pkg: A2 1 1 x86_64
+#>=Prv: A
+#>=Pkg: B1 1 1 x86_64
+#>=Prv: B
+#>=Pkg: B2 1 1 x86_64
+#>=Prv: B
+#>=Pkg: C1 1 1 x86_64
+#>=Prv: C
+#>=Pkg: C2 1 1 x86_64
+#>=Prv: C
+#>=Pkg: X 1 1 x86_64
+#>=Req: A <IF> (B <ELSE> C)
+#>=Pkg: Y 1 1 x86_64
+#>=Con: A <IF> (B <ELSE> C)
+job install name X
+result rules <inline>
+#>rule job 3986285ed3e7fa05cb3367ca1e7f0d3d X-1-1.x86_64@available
+#>rule pkg 2c561cfd067b5ec806fd5c4fcd2ac761 A1-1-1.x86_64@available
+#>rule pkg 2c561cfd067b5ec806fd5c4fcd2ac761 A2-1-1.x86_64@available
+#>rule pkg 2c561cfd067b5ec806fd5c4fcd2ac761 -B1-1-1.x86_64@available
+#>rule pkg 2c561cfd067b5ec806fd5c4fcd2ac761 -X-1-1.x86_64@available
+#>rule pkg 72c9298b01fec76aae2722e2cdfdc776 A1-1-1.x86_64@available
+#>rule pkg 72c9298b01fec76aae2722e2cdfdc776 A2-1-1.x86_64@available
+#>rule pkg 72c9298b01fec76aae2722e2cdfdc776 -B2-1-1.x86_64@available
+#>rule pkg 72c9298b01fec76aae2722e2cdfdc776 -X-1-1.x86_64@available
+#>rule pkg dee60af94c8ea49c9f99362dcb65806a B1-1-1.x86_64@available
+#>rule pkg dee60af94c8ea49c9f99362dcb65806a B2-1-1.x86_64@available
+#>rule pkg dee60af94c8ea49c9f99362dcb65806a C1-1-1.x86_64@available
+#>rule pkg dee60af94c8ea49c9f99362dcb65806a C2-1-1.x86_64@available
+#>rule pkg dee60af94c8ea49c9f99362dcb65806a -X-1-1.x86_64@available
+nextjob
+job install name Y
+result rules <inline>
+#>rule job 181d7955b2179c4ffdffedf0198f4807 Y-1-1.x86_64@available
+#>rule pkg 05a449a52d4792a0b847f482f5d7b509 -A1-1-1.x86_64@available
+#>rule pkg 05a449a52d4792a0b847f482f5d7b509 -B2-1-1.x86_64@available
+#>rule pkg 05a449a52d4792a0b847f482f5d7b509 -Y-1-1.x86_64@available
+#>rule pkg 2823a39a3d1ae2f7d45ca97e97f5bf8e -A1-1-1.x86_64@available
+#>rule pkg 2823a39a3d1ae2f7d45ca97e97f5bf8e -C1-1-1.x86_64@available
+#>rule pkg 2823a39a3d1ae2f7d45ca97e97f5bf8e -Y-1-1.x86_64@available
+#>rule pkg 46a6ab5f0c299f23867d74570cc179b8 B1-1-1.x86_64@available
+#>rule pkg 46a6ab5f0c299f23867d74570cc179b8 B2-1-1.x86_64@available
+#>rule pkg 46a6ab5f0c299f23867d74570cc179b8 -C1-1-1.x86_64@available
+#>rule pkg 46a6ab5f0c299f23867d74570cc179b8 -Y-1-1.x86_64@available
+#>rule pkg 85eac3dcd30bb5f51ad50b6644455822 -A2-1-1.x86_64@available
+#>rule pkg 85eac3dcd30bb5f51ad50b6644455822 -B2-1-1.x86_64@available
+#>rule pkg 85eac3dcd30bb5f51ad50b6644455822 -Y-1-1.x86_64@available
+#>rule pkg 8611a3d851adbd063a5d34a3ad4804e6 -A1-1-1.x86_64@available
+#>rule pkg 8611a3d851adbd063a5d34a3ad4804e6 -B1-1-1.x86_64@available
+#>rule pkg 8611a3d851adbd063a5d34a3ad4804e6 -Y-1-1.x86_64@available
+#>rule pkg 92d66d3ad45eaa7d443a05245c9a0eaf -A2-1-1.x86_64@available
+#>rule pkg 92d66d3ad45eaa7d443a05245c9a0eaf -C1-1-1.x86_64@available
+#>rule pkg 92d66d3ad45eaa7d443a05245c9a0eaf -Y-1-1.x86_64@available
+#>rule pkg ba6ba0db8d7421f83f7df6cc4df6df7d -A2-1-1.x86_64@available
+#>rule pkg ba6ba0db8d7421f83f7df6cc4df6df7d -B1-1-1.x86_64@available
+#>rule pkg ba6ba0db8d7421f83f7df6cc4df6df7d -Y-1-1.x86_64@available
+#>rule pkg c3f6b37277eb48011d0e68c11323ea3e B1-1-1.x86_64@available
+#>rule pkg c3f6b37277eb48011d0e68c11323ea3e B2-1-1.x86_64@available
+#>rule pkg c3f6b37277eb48011d0e68c11323ea3e -C2-1-1.x86_64@available
+#>rule pkg c3f6b37277eb48011d0e68c11323ea3e -Y-1-1.x86_64@available
+#>rule pkg c450fe9f8321047ee2cd1e6fc9f34df6 -A2-1-1.x86_64@available
+#>rule pkg c450fe9f8321047ee2cd1e6fc9f34df6 -C2-1-1.x86_64@available
+#>rule pkg c450fe9f8321047ee2cd1e6fc9f34df6 -Y-1-1.x86_64@available
+#>rule pkg da9eb4921698e87f788a89bd25cf75b8 -A1-1-1.x86_64@available
+#>rule pkg da9eb4921698e87f788a89bd25cf75b8 -C2-1-1.x86_64@available
+#>rule pkg da9eb4921698e87f788a89bd25cf75b8 -Y-1-1.x86_64@available
--- /dev/null
+feature complex_deps
+repo available 0 testtags <inline>
+#>=Pkg: A1 1 1 x86_64
+#>=Prv: A
+#>=Pkg: A2 1 1 x86_64
+#>=Prv: A
+#>=Pkg: B1 1 1 x86_64
+#>=Prv: B
+#>=Pkg: B2 1 1 x86_64
+#>=Prv: B
+#>=Pkg: X 1 1 x86_64
+#>=Req: A | B
+#>=Pkg: Y 1 1 x86_64
+#>=Con: A | B
+job install name X
+result rules <inline>
+#>rule job 3986285ed3e7fa05cb3367ca1e7f0d3d X-1-1.x86_64@available
+#>rule pkg 7d7fb2231997a6ba15d2c7c1d11d4ff1 A1-1-1.x86_64@available
+#>rule pkg 7d7fb2231997a6ba15d2c7c1d11d4ff1 A2-1-1.x86_64@available
+#>rule pkg 7d7fb2231997a6ba15d2c7c1d11d4ff1 B1-1-1.x86_64@available
+#>rule pkg 7d7fb2231997a6ba15d2c7c1d11d4ff1 B2-1-1.x86_64@available
+#>rule pkg 7d7fb2231997a6ba15d2c7c1d11d4ff1 -X-1-1.x86_64@available
+nextjob
+job install name Y
+result rules <inline>
+#>rule job 181d7955b2179c4ffdffedf0198f4807 Y-1-1.x86_64@available
+#>rule pkg 0fd77d3093bfb9bc85606ae155bee7e0 -A1-1-1.x86_64@available
+#>rule pkg 0fd77d3093bfb9bc85606ae155bee7e0 -Y-1-1.x86_64@available
+#>rule pkg 45e18ba2f65a39574c1f4b1c77b565ec -A2-1-1.x86_64@available
+#>rule pkg 45e18ba2f65a39574c1f4b1c77b565ec -Y-1-1.x86_64@available
+#>rule pkg 69d83d7a676b6a65f79a6fc5bcf2ca6e -B1-1-1.x86_64@available
+#>rule pkg 69d83d7a676b6a65f79a6fc5bcf2ca6e -Y-1-1.x86_64@available
+#>rule pkg d6e57752cc50ab9fc0a218fda6dbf172 -B2-1-1.x86_64@available
+#>rule pkg d6e57752cc50ab9fc0a218fda6dbf172 -Y-1-1.x86_64@available
--- /dev/null
+feature complex_deps
+repo available 0 testtags <inline>
+#>=Pkg: A1 1 1 x86_64
+#>=Prv: A
+#>=Pkg: A2 1 1 x86_64
+#>=Prv: A
+#>=Pkg: B1 1 1 x86_64
+#>=Prv: B
+#>=Pkg: B2 1 1 x86_64
+#>=Prv: B
+#>=Pkg: C1 1 1 x86_64
+#>=Prv: C
+#>=Pkg: C2 1 1 x86_64
+#>=Prv: C
+#>=Pkg: D1 1 1 x86_64
+#>=Prv: D
+#>=Pkg: D2 1 1 x86_64
+#>=Prv: D
+#>=Pkg: X 1 1 x86_64
+#>=Req: (A | B) & (C | D)
+#>=Pkg: Y 1 1 x86_64
+#>=Con: (A | B) & (C | D)
+job install name X
+result rules <inline>
+#>rule job 3986285ed3e7fa05cb3367ca1e7f0d3d X-1-1.x86_64@available
+#>rule pkg 7d7fb2231997a6ba15d2c7c1d11d4ff1 A1-1-1.x86_64@available
+#>rule pkg 7d7fb2231997a6ba15d2c7c1d11d4ff1 A2-1-1.x86_64@available
+#>rule pkg 7d7fb2231997a6ba15d2c7c1d11d4ff1 B1-1-1.x86_64@available
+#>rule pkg 7d7fb2231997a6ba15d2c7c1d11d4ff1 B2-1-1.x86_64@available
+#>rule pkg 7d7fb2231997a6ba15d2c7c1d11d4ff1 -X-1-1.x86_64@available
+#>rule pkg cb5c72eeb44f643493f3df3e7e62f9dc C1-1-1.x86_64@available
+#>rule pkg cb5c72eeb44f643493f3df3e7e62f9dc C2-1-1.x86_64@available
+#>rule pkg cb5c72eeb44f643493f3df3e7e62f9dc D1-1-1.x86_64@available
+#>rule pkg cb5c72eeb44f643493f3df3e7e62f9dc D2-1-1.x86_64@available
+#>rule pkg cb5c72eeb44f643493f3df3e7e62f9dc -X-1-1.x86_64@available
+nextjob
+job install name Y
+result rules <inline>
+#>rule job 181d7955b2179c4ffdffedf0198f4807 Y-1-1.x86_64@available
+#>rule pkg 16cbba917580ca34f91961a74cfd07c2 -B1-1-1.x86_64@available
+#>rule pkg 16cbba917580ca34f91961a74cfd07c2 -D1-1-1.x86_64@available
+#>rule pkg 16cbba917580ca34f91961a74cfd07c2 -Y-1-1.x86_64@available
+#>rule pkg 1db9a5695f062c299dbb815adf4f2374 -A1-1-1.x86_64@available
+#>rule pkg 1db9a5695f062c299dbb815adf4f2374 -D2-1-1.x86_64@available
+#>rule pkg 1db9a5695f062c299dbb815adf4f2374 -Y-1-1.x86_64@available
+#>rule pkg 22f3f4d055f6daaeb6f5622907a9206f -A2-1-1.x86_64@available
+#>rule pkg 22f3f4d055f6daaeb6f5622907a9206f -D1-1-1.x86_64@available
+#>rule pkg 22f3f4d055f6daaeb6f5622907a9206f -Y-1-1.x86_64@available
+#>rule pkg 2823a39a3d1ae2f7d45ca97e97f5bf8e -A1-1-1.x86_64@available
+#>rule pkg 2823a39a3d1ae2f7d45ca97e97f5bf8e -C1-1-1.x86_64@available
+#>rule pkg 2823a39a3d1ae2f7d45ca97e97f5bf8e -Y-1-1.x86_64@available
+#>rule pkg 33a12cadfd9dd12dc60a3e250ae9f92a -B2-1-1.x86_64@available
+#>rule pkg 33a12cadfd9dd12dc60a3e250ae9f92a -C2-1-1.x86_64@available
+#>rule pkg 33a12cadfd9dd12dc60a3e250ae9f92a -Y-1-1.x86_64@available
+#>rule pkg 48a9e473b42b382f7cf46ac33e98ba76 -B2-1-1.x86_64@available
+#>rule pkg 48a9e473b42b382f7cf46ac33e98ba76 -C1-1-1.x86_64@available
+#>rule pkg 48a9e473b42b382f7cf46ac33e98ba76 -Y-1-1.x86_64@available
+#>rule pkg 714e9978244eb65bc57b7c4fac5a0430 -B1-1-1.x86_64@available
+#>rule pkg 714e9978244eb65bc57b7c4fac5a0430 -C1-1-1.x86_64@available
+#>rule pkg 714e9978244eb65bc57b7c4fac5a0430 -Y-1-1.x86_64@available
+#>rule pkg 86df5aaf92e5ea31f8efedf442fd431e -B1-1-1.x86_64@available
+#>rule pkg 86df5aaf92e5ea31f8efedf442fd431e -C2-1-1.x86_64@available
+#>rule pkg 86df5aaf92e5ea31f8efedf442fd431e -Y-1-1.x86_64@available
+#>rule pkg 87928b09a90963097188f62d00bfb3d9 -B2-1-1.x86_64@available
+#>rule pkg 87928b09a90963097188f62d00bfb3d9 -D1-1-1.x86_64@available
+#>rule pkg 87928b09a90963097188f62d00bfb3d9 -Y-1-1.x86_64@available
+#>rule pkg 92d66d3ad45eaa7d443a05245c9a0eaf -A2-1-1.x86_64@available
+#>rule pkg 92d66d3ad45eaa7d443a05245c9a0eaf -C1-1-1.x86_64@available
+#>rule pkg 92d66d3ad45eaa7d443a05245c9a0eaf -Y-1-1.x86_64@available
+#>rule pkg b5f410efacf9eb0b2b725e3e7b7d6e93 -B1-1-1.x86_64@available
+#>rule pkg b5f410efacf9eb0b2b725e3e7b7d6e93 -D2-1-1.x86_64@available
+#>rule pkg b5f410efacf9eb0b2b725e3e7b7d6e93 -Y-1-1.x86_64@available
+#>rule pkg c450fe9f8321047ee2cd1e6fc9f34df6 -A2-1-1.x86_64@available
+#>rule pkg c450fe9f8321047ee2cd1e6fc9f34df6 -C2-1-1.x86_64@available
+#>rule pkg c450fe9f8321047ee2cd1e6fc9f34df6 -Y-1-1.x86_64@available
+#>rule pkg da9eb4921698e87f788a89bd25cf75b8 -A1-1-1.x86_64@available
+#>rule pkg da9eb4921698e87f788a89bd25cf75b8 -C2-1-1.x86_64@available
+#>rule pkg da9eb4921698e87f788a89bd25cf75b8 -Y-1-1.x86_64@available
+#>rule pkg dfd799532ba714fd139acf879992c2de -A2-1-1.x86_64@available
+#>rule pkg dfd799532ba714fd139acf879992c2de -D2-1-1.x86_64@available
+#>rule pkg dfd799532ba714fd139acf879992c2de -Y-1-1.x86_64@available
+#>rule pkg eab097949c9719f1e7e196241c6ec0f4 -B2-1-1.x86_64@available
+#>rule pkg eab097949c9719f1e7e196241c6ec0f4 -D2-1-1.x86_64@available
+#>rule pkg eab097949c9719f1e7e196241c6ec0f4 -Y-1-1.x86_64@available
+#>rule pkg ede76598bf66f6be0b1fa3439c97a71b -A1-1-1.x86_64@available
+#>rule pkg ede76598bf66f6be0b1fa3439c97a71b -D1-1-1.x86_64@available
+#>rule pkg ede76598bf66f6be0b1fa3439c97a71b -Y-1-1.x86_64@available
--- /dev/null
+repo system 0 empty
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Rec: B
+#>=Pkg: B 1 1 noarch
+#>=Pkg: B 3 1 noarch
+#>=Con: A
+#>=Pkg: B 2 1 noarch
+system i686 rpm system
+
+solverflags ignorerecommended
+job install name A
+
+result transaction,recommended,problems <inline>
+#>install A-1-1.noarch@available
+#>recommended B-2-1.noarch@available
--- /dev/null
+repo system 0 empty
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Rec: B
+#>=Pkg: B 1 1 noarch
+#>=Pkg: B 3 1 noarch
+#>=Pkg: B 2 1 noarch
+repo other 0 testtags <inline>
+#>=Pkg: B 4 1 noarch
+#>=Pkg: B 6 1 noarch
+#>=Pkg: B 5 1 noarch
+system i686 rpm system
+
+solverflags ignorerecommended
+job install name A
+
+result transaction,recommended,problems <inline>
+#>install A-1-1.noarch@available
+#>recommended B-6-1.noarch@other
--- /dev/null
+repo system 0 empty
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Rec: B < 3
+#>=Pkg: B 1 1 noarch
+#>=Pkg: B 3 1 noarch
+#>=Pkg: B 2 1 noarch
+system i686 rpm system
+
+solverflags ignorerecommended
+job install name A
+
+result transaction,recommended,problems <inline>
+#>install A-1-1.noarch@available
+#>recommended B-2-1.noarch@available
--- /dev/null
+repo system 0 empty
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Rec: B = 2-1
+#>=Pkg: B 1 1 noarch
+#>=Pkg: B 3 1 noarch
+#>=Pkg: B 2 1 noarch
+system i686 rpm system
+
+solverflags ignorerecommended
+job install name A
+
+result transaction,recommended,problems <inline>
+#>install A-1-1.noarch@available
+#>recommended B-2-1.noarch@available
--- /dev/null
+repo system 0 empty
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Rec: B
+#>=Pkg: B 1 1 noarch
+#>=Pkg: B 3 1 noarch
+#>=Pkg: B 2 1 noarch
+system i686 rpm system
+
+solverflags ignorerecommended
+job install name A
+
+result transaction,recommended,problems <inline>
+#>install A-1-1.noarch@available
+#>recommended B-3-1.noarch@available
--- /dev/null
+repo system 0 empty
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Sug: B
+#>=Pkg: B 1 1 noarch
+#>=Pkg: B 3 1 noarch
+#>=Con: A
+#>=Pkg: B 2 1 noarch
+system i686 rpm system
+
+solverflags ignorerecommended
+job install name A
+
+result transaction,recommended,problems <inline>
+#>install A-1-1.noarch@available
+#>suggested B-2-1.noarch@available
--- /dev/null
+repo system 0 empty
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Sug: B
+#>=Pkg: B 1 1 noarch
+#>=Pkg: B 3 1 noarch
+#>=Pkg: B 2 1 noarch
+repo other 0 testtags <inline>
+#>=Pkg: B 4 1 noarch
+#>=Pkg: B 6 1 noarch
+#>=Pkg: B 5 1 noarch
+system i686 rpm system
+
+solverflags ignorerecommended
+job install name A
+
+result transaction,recommended,problems <inline>
+#>install A-1-1.noarch@available
+#>suggested B-6-1.noarch@other
--- /dev/null
+repo system 0 empty
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Sug: B < 3
+#>=Pkg: B 1 1 noarch
+#>=Pkg: B 3 1 noarch
+#>=Pkg: B 2 1 noarch
+system i686 rpm system
+
+solverflags ignorerecommended
+job install name A
+
+result transaction,recommended,problems <inline>
+#>install A-1-1.noarch@available
+#>suggested B-2-1.noarch@available
--- /dev/null
+repo system 0 empty
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Sug: B = 2-1
+#>=Pkg: B 1 1 noarch
+#>=Pkg: B 3 1 noarch
+#>=Pkg: B 2 1 noarch
+system i686 rpm system
+
+solverflags ignorerecommended
+job install name A
+
+result transaction,recommended,problems <inline>
+#>install A-1-1.noarch@available
+#>suggested B-2-1.noarch@available
--- /dev/null
+repo system 0 empty
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Sug: B
+#>=Pkg: B 1 1 noarch
+#>=Pkg: B 3 1 noarch
+#>=Pkg: B 2 1 noarch
+system i686 rpm system
+
+solverflags ignorerecommended
+job install name A
+
+result transaction,recommended,problems <inline>
+#>install A-1-1.noarch@available
+#>suggested B-3-1.noarch@available