r = pakfire_packagelist_walk(build->packages, pakfire_build_install_package, request);
// Solve the request
- r = pakfire_request_solve(request, NULL, NULL);
+ r = pakfire_request_solve(request, NULL);
switch (r) {
// All okay
case 0:
struct pakfire_request* pakfire_request_unref(struct pakfire_request* request);
int pakfire_request_solve(struct pakfire_request* request,
- struct pakfire_transaction** transaction, struct pakfire_problem*** problems);
+ struct pakfire_transaction** transaction);
int pakfire_request_install(struct pakfire_request* request, const char* what, int flags);
int pakfire_request_install_package(struct pakfire_request* request, struct pakfire_package* package);
#ifdef PAKFIRE_PRIVATE
-#include <pakfire/problem.h>
#include <pakfire/request.h>
int pakfire_ui_confirm(struct pakfire* pakfire, void* data,
const char* message, const char* question);
-int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* request,
- struct pakfire_problem** problems);
+int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* request);
#endif
pakfire_request_erase;
pakfire_request_erase_package;
pakfire_request_get_pool;
- pakfire_request_get_problems;
pakfire_request_get_transaction;
pakfire_request_install;
pakfire_request_install_package;
void* status_callback_data) {
struct pakfire_request* request = NULL;
struct pakfire_transaction* transaction = NULL;
- struct pakfire_problem** problems = NULL;
int r = 1;
// Packages cannot be NULL
// Solve the request
while (!solved) {
- r = pakfire_request_solve(request, &transaction, &problems);
+ r = pakfire_request_solve(request, &transaction);
switch (r) {
case 0:
solved = 1;
// Dependency error
case 2:
- if (!problems)
- goto ERROR;
-
// Let the user choose a problem
- r = pakfire_ui_pick_solution(pakfire, request, problems);
+ r = pakfire_ui_pick_solution(pakfire, request);
if (r)
goto ERROR;
-
- // Free problems
- for (struct pakfire_problem** problem = problems; *problem; problem++)
- pakfire_problem_unref(*problem);
- free(problems);
break;
// Another error occured
// Release lock
pakfire_release_lock(pakfire);
- // Cleanup
- if (problems) {
- for (struct pakfire_problem** problem = problems; *problem; problem++)
- pakfire_problem_unref(*problem);
- free(problems);
- }
if (transaction)
pakfire_transaction_unref(transaction);
if (request)
pakfire_status_callback status_callback, void* status_callback_data) {
struct pakfire_request* request = NULL;
struct pakfire_transaction* transaction = NULL;
- struct pakfire_problem** problems = NULL;
int r = 1;
// Acquire lock
// Solve the request
while (!solved) {
- r = pakfire_request_solve(request, &transaction, &problems);
+ r = pakfire_request_solve(request, &transaction);
switch (r) {
case 0:
solved = 1;
// Dependency error
case 2:
- if (!problems)
- goto ERROR;
-
// Let the user choose a problem
- r = pakfire_ui_pick_solution(pakfire, request, problems);
+ r = pakfire_ui_pick_solution(pakfire, request);
if (r)
goto ERROR;
- // Free problems
- for (struct pakfire_problem** problem = problems; *problem; problem++)
- pakfire_problem_unref(*problem);
- free(problems);
break;
// Another error occured
// Release lock
pakfire_release_lock(pakfire);
- if (problems) {
- for (struct pakfire_problem** problem = problems; *problem; problem++)
- pakfire_problem_unref(*problem);
- free(problems);
- }
if (transaction)
pakfire_transaction_unref(transaction);
if (request)
return request->solver;
}
-static int pakfire_request_get_problems(struct pakfire_request* request,
- struct pakfire_problem*** problems) {
- struct pakfire_problem* problem;
-
- unsigned int count = solver_problem_count(request->solver);
- if (!count)
- return 0;
-
- // Allocate array
- *problems = calloc(count + 1, sizeof(**problems));
- if (!*problems)
- return 1;
-
- Id p = 0;
- for (unsigned int i = 0; i < count; i++) {
- p = solver_next_problem(request->solver, p);
- if (!p)
- break;
-
- // Create problem
- int r = pakfire_problem_create(&problem, request->pakfire, request, p);
- if (r)
- goto ERROR;
-
- // Append to array
- (*problems)[i] = problem;
- };
-
- return 0;
-
-ERROR:
- if (*problems) {
- for (struct pakfire_problem** _problem = *problems; *_problem; _problem++)
- pakfire_problem_unref(*_problem);
- free(*problems);
-
- // Reset pointer
- *problems = NULL;
- }
-
- return 1;
-}
-
PAKFIRE_EXPORT int pakfire_request_solve(struct pakfire_request* request,
- struct pakfire_transaction** transaction, struct pakfire_problem*** problems) {
+ struct pakfire_transaction** transaction) {
int r;
// Prepare pool
pakfire_pool_internalize(request->pakfire);
- // Reset pointers
+ // Reset pointer
if (transaction)
*transaction = NULL;
- if (problems)
- *problems = NULL;
#ifdef ENABLE_DEBUG
Pool* pool = pakfire_get_solv_pool(request->pakfire);
solver_printallsolutions(request->solver);
#endif
- // Fetch problems
- if (problems) {
- r = pakfire_request_get_problems(request, problems);
- if (r)
- return r;
- }
-
return 2;
}
return r;
}
-static struct pakfire_solution** pakfire_ui_append_solutions(
- struct pakfire_solution** list, struct pakfire_solution** solutions) {
- unsigned int existing_length = 0;
- unsigned int appended_length = 0;
+static struct pakfire_solution** pakfire_ui_append_solution(
+ struct pakfire_solution** list, struct pakfire_solution* solution) {
+ unsigned int length = 0;
- // Count lengths of list
+ // Count length of list
if (list) {
- for (struct pakfire_solution** solution = list; *solution; solution++)
- existing_length++;
+ for (struct pakfire_solution** s = list; *s; s++)
+ length++;
}
- // Count what is to be appended
- for (struct pakfire_solution** solution = solutions; *solution; solution++)
- appended_length++;
-
// Increase array size
- list = reallocarray(list, existing_length + appended_length + 1, sizeof(*list));
+ list = reallocarray(list, length + 2, sizeof(*list));
if (!list)
return NULL;
- // Append all elements to list
- for (unsigned int i = 0; i < appended_length; i++)
- list[existing_length + i] = pakfire_solution_ref(solutions[i]);
+ // Append the new element to the list
+ list[length] = pakfire_solution_ref(solution);
// Terminate the list
- list[existing_length + appended_length] = NULL;
+ list[length + 1] = NULL;
return list;
}
-int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* request,
- struct pakfire_problem** problems) {
- if (!problems) {
- errno = EINVAL;
- return 1;
- }
-
- struct pakfire_solution** all_solutions = NULL;
- unsigned int num_solutions = 0;
+int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* request) {
+ struct pakfire_problem* problem = NULL;
struct pakfire_solution** solutions = NULL;
+ struct pakfire_solution* solution = NULL;
+ unsigned int num_solutions = 0;
int r;
// Print a headline
printf("%s\n", _("One or more problems have occurred solving your request:"));
// Print all problems
- for (struct pakfire_problem** problem = problems; *problem; problem++) {
- const char* s = pakfire_problem_to_string(*problem);
-
- printf(" * %s\n", s);
-
- // Fetch all solutions to this problem
- r = pakfire_problem_get_solutions(*problem, &solutions);
+ for (;;) {
+ r = pakfire_request_next_problem(request, &problem);
if (r)
goto ERROR;
- // Skip the rest if there are no solutions
- if (!solutions)
- continue;
+ // No more problems
+ if (!problem)
+ break;
- // Append solutions to list
- all_solutions = pakfire_ui_append_solutions(all_solutions, solutions);
- if (!all_solutions)
- goto ERROR;
+ const char* s = pakfire_problem_to_string(problem);
+
+ printf(" * %s\n", s);
// Show a little headline
printf(" %s\n", _("Possible solutions:"));
- // Print solutions
- for (struct pakfire_solution** solution = solutions; *solution; solution++) {
- s = pakfire_solution_to_string(*solution);
- if (!s) {
- for (struct pakfire_solution** _solution = solutions; *_solution; _solution++)
- pakfire_solution_unref(*_solution);
- free(solutions);
+ for (;;) {
+ r = pakfire_problem_next_solution(problem, &solution);
+ if (r)
+ goto ERROR;
+
+ // No more solutions
+ if (!solution)
+ break;
+
+ // Append the solution to the list
+ solutions = pakfire_ui_append_solution(solutions, solution);
+ if (!solutions)
goto ERROR;
- }
+
+ s = pakfire_solution_to_string(solution);
printf(" [%d] %s\n", ++num_solutions, s);
}
// Empty line
printf("\n");
-
- // Free solutions
- for (struct pakfire_solution** solution = solutions; *solution; solution++)
- pakfire_solution_unref(*solution);
- free(solutions);
}
unsigned int choice = 0;
goto ERROR;
// Fetch selected solution into the solver
- r = pakfire_request_take_solution(request, all_solutions[choice - 1]);
+ r = pakfire_request_take_solution(request, solutions[choice - 1]);
if (r)
goto ERROR;
r = 0;
ERROR:
- if (all_solutions) {
- for (struct pakfire_solution** solution = all_solutions; *solution; solution++)
- pakfire_solution_unref(*solution);
- free(all_solutions);
+ if (solutions) {
+ for (struct pakfire_solution** s = solutions; *s; s++)
+ pakfire_solution_unref(*s);
+ free(solutions);
}
return r;