]> git.ipfire.org Git - people/stevee/pakfire.git/blob - src/_pakfire/solver.c
Use autotools.
[people/stevee/pakfire.git] / src / _pakfire / solver.c
1 /*#############################################################################
2 # #
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2011 Pakfire development team #
5 # #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
10 # #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
15 # #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
18 # #
19 #############################################################################*/
20
21 #include "pool.h"
22 #include "problem.h"
23 #include "request.h"
24 #include "solver.h"
25
26 #include <solv/solverdebug.h>
27
28 PyTypeObject SolverType = {
29 PyObject_HEAD_INIT(NULL)
30 tp_name: "_pakfire.Solver",
31 tp_basicsize: sizeof(SolverObject),
32 tp_flags: Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
33 tp_new : Solver_new,
34 tp_dealloc: (destructor) Solver_dealloc,
35 tp_doc: "Sat Solver objects",
36 };
37
38 PyObject* Solver_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
39 SolverObject *self;
40
41 PoolObject *pool;
42
43 if (!PyArg_ParseTuple(args, "O", &pool)) {
44 /* XXX raise exception */
45 }
46
47 self = (SolverObject *)type->tp_alloc(type, 0);
48 if (self != NULL) {
49 self->_solver = solver_create(pool->_pool);
50 if (self->_solver == NULL) {
51 Py_DECREF(self);
52 return NULL;
53 }
54 }
55
56 /* enable splitprovides by default */
57 solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, 1);
58
59 /* keep explicit obsoletes */
60 solver_set_flag(self->_solver, SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES, 1);
61
62 return (PyObject *)self;
63 }
64
65 PyObject *Solver_dealloc(SolverObject *self) {
66 solver_free(self->_solver);
67 self->ob_type->tp_free((PyObject *)self);
68
69 Py_RETURN_NONE;
70 }
71
72 PyObject *Solver_get_flag(SolverObject *self, PyObject *args) {
73 int flag = 0;
74
75 if (!PyArg_ParseTuple(args, "i", &flag)) {
76 return NULL;
77 }
78
79 int val = solver_get_flag(self->_solver, flag);
80 return Py_BuildValue("i", val);
81 }
82
83 PyObject *Solver_set_flag(SolverObject *self, PyObject *args) {
84 int flag = 0, val = 0;
85
86 if (!PyArg_ParseTuple(args, "ii", &flag, &val)) {
87 return NULL;
88 }
89
90 solver_set_flag(self->_solver, flag, val);
91 Py_RETURN_NONE;
92 }
93
94 PyObject *Solver_get_allow_downgrade(SolverObject *self, PyObject *args) {
95 int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_DOWNGRADE);
96
97 return Py_BuildValue("i", val);
98 }
99
100 PyObject *Solver_set_allow_downgrade(SolverObject *self, PyObject *args) {
101 int val;
102
103 if (!PyArg_ParseTuple(args, "i", &val)) {
104 return NULL;
105 }
106
107 solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_DOWNGRADE, val);
108 Py_RETURN_NONE;
109 }
110
111 PyObject *Solver_get_allow_archchange(SolverObject *self, PyObject *args) {
112 int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_ARCHCHANGE);
113
114 return Py_BuildValue("i", val);
115 }
116
117 PyObject *Solver_set_allow_archchange(SolverObject *self, PyObject *args) {
118 int val;
119
120 if (!PyArg_ParseTuple(args, "i", &val)) {
121 return NULL;
122 }
123
124 solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_ARCHCHANGE, val);
125 Py_RETURN_NONE;
126 }
127
128 PyObject *Solver_get_allow_vendorchange(SolverObject *self, PyObject *args) {
129 int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_VENDORCHANGE);
130
131 return Py_BuildValue("i", val);
132 }
133
134 PyObject *Solver_set_allow_vendorchange(SolverObject *self, PyObject *args) {
135 int val;
136
137 if (!PyArg_ParseTuple(args, "i", &val)) {
138 return NULL;
139 }
140
141 solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_VENDORCHANGE, val);
142 Py_RETURN_NONE;
143 }
144
145 PyObject *Solver_get_allow_uninstall(SolverObject *self, PyObject *args) {
146 int val = solver_get_flag(self->_solver, SOLVER_FLAG_ALLOW_UNINSTALL);
147
148 return Py_BuildValue("i", val);
149 }
150
151 PyObject *Solver_set_allow_uninstall(SolverObject *self, PyObject *args) {
152 int val;
153
154 if (!PyArg_ParseTuple(args, "i", &val)) {
155 return NULL;
156 }
157
158 solver_set_flag(self->_solver, SOLVER_FLAG_ALLOW_UNINSTALL, val);
159 Py_RETURN_NONE;
160 }
161
162 PyObject *Solver_get_updatesystem(SolverObject *self, PyObject *args) {
163 //return Py_BuildValue("i", self->_solver->updatesystem);
164 Py_RETURN_NONE;
165 }
166
167 PyObject *Solver_set_updatesystem(SolverObject *self, PyObject *args) {
168 /*int val;
169
170 if (!PyArg_ParseTuple(args, "i", &val)) {
171 return NULL;
172 }
173
174 self->_solver->updatesystem = val; */
175
176 Py_RETURN_NONE;
177 }
178
179 PyObject *Solver_get_do_split_provides(SolverObject *self, PyObject *args) {
180 int val = solver_get_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES);
181
182 return Py_BuildValue("i", val);
183 }
184
185 PyObject *Solver_set_do_split_provides(SolverObject *self, PyObject *args) {
186 int val;
187
188 if (!PyArg_ParseTuple(args, "i", &val)) {
189 return NULL;
190 }
191
192 solver_set_flag(self->_solver, SOLVER_FLAG_SPLITPROVIDES, val);
193 Py_RETURN_NONE;
194 }
195
196 PyObject *Solver_solve(SolverObject *self, PyObject *args) {
197 RequestObject *request;
198 int force_best = 0;
199 int res = 0;
200
201 if (!PyArg_ParseTuple(args, "O|i", &request, &force_best)) {
202 return NULL;
203 }
204
205 // Make sure, the pool is prepared.
206 _Pool_prepare(self->_solver->pool);
207
208 /* Force best solution. */
209 if (force_best) {
210 for (int i = 0; i < request->_queue.count; i += 2)
211 request->_queue.elements[i] |= SOLVER_FORCEBEST;
212 }
213
214 res = solver_solve(self->_solver, &request->_queue);
215
216 #ifdef DEBUG
217 solver_printallsolutions(self->_solver);
218 #endif
219
220 if (res == 0) {
221 Py_RETURN_TRUE;
222 }
223 Py_RETURN_FALSE;
224 }
225
226 PyObject *Solver_get_problems(SolverObject *self, PyObject *args) {
227 RequestObject *request;
228
229 if (!PyArg_ParseTuple(args, "O", &request)) {
230 return NULL;
231 }
232
233 PyObject *list = PyList_New(0);
234
235 ProblemObject *problem;
236 Id p = 0;
237 while ((p = solver_next_problem(self->_solver, p)) != 0) {
238 problem = PyObject_New(ProblemObject, &ProblemType);
239
240 problem->_pool = self->_solver->pool;
241 problem->_solver = self->_solver;
242 problem->_id = p;
243 Problem_init(problem);
244
245 PyList_Append(list, (PyObject *)problem);
246 }
247
248 return list;
249 }