From: Michael Tremer Date: Fri, 2 Jul 2021 16:21:35 +0000 (+0000) Subject: problems: Refactor fetching solutions X-Git-Tag: 0.9.28~1124 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6c04db9ad011816c74b7df0bab4e4b221ff5462;p=pakfire.git problems: Refactor fetching solutions Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/problem.c b/src/_pakfire/problem.c index 120569c1a..66a123a48 100644 --- a/src/_pakfire/problem.c +++ b/src/_pakfire/problem.c @@ -82,18 +82,37 @@ static PyObject* Problem_string(ProblemObject* self) { } static PyObject* Problem_get_solutions(ProblemObject* self) { + struct pakfire_solution** solutions = NULL; + + // Fetch all solutions + int r = pakfire_problem_get_solutions(self->problem, &solutions); + if (r) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + PyObject* list = PyList_New(0); + if (!list) + return NULL; + + // Return the empty list if there are no solutions + if (!solutions) + return list; + + for (struct pakfire_solution** solution = solutions; *solution; solution++) { + PyObject* s = new_solution(*solution); + if (!s) + goto ERROR; - struct pakfire_solution* solution = pakfire_problem_get_solutions(self->problem); - while (solution) { - PyObject* s = new_solution(solution); PyList_Append(list, s); Py_DECREF(s); - - solution = pakfire_solution_next(solution); } return list; + +ERROR: + Py_DECREF(list); + return NULL; } static struct PyMethodDef Problem_methods[] = { diff --git a/src/libpakfire/include/pakfire/problem.h b/src/libpakfire/include/pakfire/problem.h index c391918ee..1f880b457 100644 --- a/src/libpakfire/include/pakfire/problem.h +++ b/src/libpakfire/include/pakfire/problem.h @@ -32,7 +32,8 @@ struct pakfire_problem* pakfire_problem_unref(struct pakfire_problem* problem); const char* pakfire_problem_to_string(struct pakfire_problem* problem); struct pakfire_request* pakfire_problem_get_request(struct pakfire_problem* problem); -struct pakfire_solution* pakfire_problem_get_solutions(struct pakfire_problem* problem); +int pakfire_problem_get_solutions(struct pakfire_problem* problem, + struct pakfire_solution*** solutions); #ifdef PAKFIRE_PRIVATE diff --git a/src/libpakfire/problem.c b/src/libpakfire/problem.c index e92950903..9a00b2841 100644 --- a/src/libpakfire/problem.c +++ b/src/libpakfire/problem.c @@ -262,20 +262,48 @@ PAKFIRE_EXPORT struct pakfire_request* pakfire_problem_get_request(struct pakfir return pakfire_request_ref(problem->request); } -PAKFIRE_EXPORT struct pakfire_solution* pakfire_problem_get_solutions(struct pakfire_problem* problem) { - struct pakfire_solution* s = NULL; - struct pakfire_solution* ret = NULL; +PAKFIRE_EXPORT int pakfire_problem_get_solutions(struct pakfire_problem* problem, + struct pakfire_solution*** solutions) { Solver* solver = pakfire_request_get_solver(problem->request); + int r; - Id solution = 0; - while ((solution = solver_next_solution(solver, problem->id, solution)) != 0) { - pakfire_solution_create(&s, problem, solution); + // How many solutions are there? + unsigned int count = solver_solution_count(solver, problem->id); + if (!count) { + *solutions = NULL; + return 0; + } + + // Allocate a solutions array + *solutions = calloc(count + 1, sizeof(**solutions)); + if (!*solutions) + return 1; + + struct pakfire_solution* solution = NULL; + + Id s = 0; + for (unsigned int i = 0; i < count; i++) { + s = solver_next_solution(solver, problem->id, s); + if (!s) + break; + + // Create a new solution object + r = pakfire_solution_create(&solution, problem, s); + if (r) + goto ERROR; + + // Append solution to array + (*solutions)[i] = solution; + } + + return 0; - if (ret) - pakfire_solution_append(ret, s); - else - ret = s; +ERROR: + if (*solutions) { + for (struct pakfire_solution** solution = *solutions; *solution; solution++) + pakfire_solution_unref(*solution); + free(*solutions); } - return ret; + return r; }