struct pakfire_problem* problem;
Id id;
- char** elements;
+ char* string;
};
-static void import_elements(struct pakfire_solution* solution) {
- struct pakfire_request* request = pakfire_problem_get_request(solution->problem);
+PAKFIRE_EXPORT int pakfire_solution_create(struct pakfire_solution** solution,
+ struct pakfire_problem* problem, Id id) {
+ struct pakfire_solution* s = calloc(1, sizeof(*s));
+ if (!s)
+ return 1;
+
+ s->pakfire = pakfire_problem_get_pakfire(problem);
+ s->nrefs = 1;
+
+ // Store a reference to the problem
+ s->problem = pakfire_problem_ref(problem);
+ s->id = id;
+
+ *solution = s;
+ return 0;
+}
+
+PAKFIRE_EXPORT struct pakfire_solution* pakfire_solution_ref(struct pakfire_solution* solution) {
+ solution->nrefs++;
+
+ return solution;
+}
+
+static void pakfire_solution_free(struct pakfire_solution* solution) {
+ pakfire_problem_unref(solution->problem);
+
+ if (solution->string)
+ free(solution->string);
+ pakfire_unref(solution->pakfire);
+ free(solution);
+}
+
+PAKFIRE_EXPORT struct pakfire_solution* pakfire_solution_unref(struct pakfire_solution* solution) {
+ if (!solution)
+ return NULL;
+
+ if (--solution->nrefs > 0)
+ return solution;
+
+ pakfire_solution_free(solution);
+ return NULL;
+}
+
+static char* pakfire_solution_make_string(struct pakfire_solution* solution) {
+ struct pakfire_request* request = pakfire_problem_get_request(solution->problem);
Solver* solver = pakfire_request_get_solver(request);
Pool* pool = solver->pool;
- // Reserve memory
- unsigned int num = solver_solutionelement_count(solver, pakfire_problem_get_id(solution->problem), solution->id);
- char** elements = solution->elements = calloc(num + 1, sizeof(*elements));
+ // Fetch the problem ID
+ Id problem_id = pakfire_problem_get_id(solution->problem);
+
+ // How many elements do we have?
+ unsigned int count = solver_solutionelement_count(solver, problem_id, solution->id);
+ if (!count) {
+ pakfire_request_unref(request);
+ return NULL;
+ }
+
+ // Allocate memory for all strings
+ char* elements[count + 1];
+
+ // Initialize the array
+ for (unsigned int i = 0; i < count; i++)
+ elements[i] = NULL;
+
+ // The result string
+ char* s = NULL;
Id p;
Id rp;
- Id element = 0;
- while ((element = solver_next_solutionelement(solver, pakfire_problem_get_id(solution->problem), solution->id, element, &p, &rp)) != 0) {
- char line[1024];
+ Id e = 0;
+ int r;
+
+ for (unsigned int i = 0; i < count; i++) {
+ e = solver_next_solutionelement(solver, problem_id, solution->id, e, &p, &rp);
+ if (!e)
+ break;
+
+ char* element = NULL;
if (p == SOLVER_SOLUTION_JOB || p == SOLVER_SOLUTION_POOLJOB) {
if (p == SOLVER_SOLUTION_JOB)
Id what = solver->job.elements[rp];
// XXX pool_job2str must be localised
- snprintf(line, sizeof(line) - 1, _("do not ask to %s"),
- pool_job2str(pool, how, what, 0));
+ r = asprintf(&element, _("do not ask to %s"), pool_job2str(pool, how, what, 0));
} else if (p == SOLVER_SOLUTION_INFARCH) {
Solvable* s = pool->solvables + rp;
if (pool->installed && s->repo == pool->installed)
- snprintf(line, sizeof(line) - 1, _("keep %s despite the inferior architecture"),
+ r = asprintf(&element, _("keep %s despite the inferior architecture"),
pool_solvable2str(pool, s));
else
- snprintf(line, sizeof(line) - 1, _("install %s despite the inferior architecture"),
+ r = asprintf(&element, _("install %s despite the inferior architecture"),
pool_solvable2str(pool, s));
} else if (p == SOLVER_SOLUTION_DISTUPGRADE) {
Solvable* s = pool->solvables + rp;
if (pool->installed && s->repo == pool->installed)
- snprintf(line, sizeof(line) - 1, _("keep obsolete %s"),
- pool_solvable2str(pool, s));
+ r = asprintf(&element, _("keep obsolete %s"), pool_solvable2str(pool, s));
else
- snprintf(line, sizeof(line) - 1, _("install %s"),
- pool_solvable2str(pool, s));
+ r = asprintf(&element, _("install %s"), pool_solvable2str(pool, s));
} else if (p == SOLVER_SOLUTION_BEST) {
Solvable* s = pool->solvables + rp;
if (pool->installed && s->repo == pool->installed)
- snprintf(line, sizeof(line) - 1, _("keep old %s"),
- pool_solvable2str(pool, s));
+ r = asprintf(&element, _("keep old %s"), pool_solvable2str(pool, s));
else
- snprintf(line, sizeof(line) - 1, _("install %s despite the old version"),
+ r = asprintf(&element, _("install %s despite the old version"),
pool_solvable2str(pool, s));
} else if (p > 0 && rp == 0)
- snprintf(line, sizeof(line) - 1, _("allow deinstallation of %s"),
+ r = asprintf(&element, _("allow deinstallation of %s"),
pool_solvid2str(pool, p));
else if (p > 0 && rp > 0)
- snprintf(line, sizeof(line) - 1, _("allow replacement of %s with %s"),
+ r = asprintf(&element, _("allow replacement of %s with %s"),
pool_solvid2str(pool, p), pool_solvid2str(pool, rp));
else
- snprintf(line, sizeof(line) - 1, _("bad solution element"));
+ r = asprintf(&element, _("bad solution element"));
+
+ if (r < 0)
+ goto ERROR;
// Save line in elements array
- *elements++ = strdup(line);
+ elements[i] = element;
}
- // Terminate array
- *elements = NULL;
+ // All okay, concat result string
+ s = pakfire_string_join(elements, "\n");
+ERROR:
pakfire_request_unref(request);
-}
-
-PAKFIRE_EXPORT int pakfire_solution_create(struct pakfire_solution** solution,
- struct pakfire_problem* problem, Id id) {
- struct pakfire_solution* s = calloc(1, sizeof(*s));
- if (!s)
- return 1;
-
- s->pakfire = pakfire_problem_get_pakfire(problem);
- s->nrefs = 1;
- // Store a reference to the problem
- s->problem = pakfire_problem_ref(problem);
- s->id = id;
+ // Free all elements
+ for (char** element = elements; *element; element++)
+ free(*element);
- // Extract information from solver
- import_elements(s);
-
- *solution = s;
- return 0;
+ return s;
}
-PAKFIRE_EXPORT struct pakfire_solution* pakfire_solution_ref(struct pakfire_solution* solution) {
- solution->nrefs++;
-
- return solution;
-}
-
-static void pakfire_solution_free(struct pakfire_solution* solution) {
- pakfire_unref(solution->pakfire);
-
- pakfire_problem_unref(solution->problem);
-
- if (solution->elements)
- while (*solution->elements)
- free(*solution->elements++);
-
- free(solution);
-}
-
-PAKFIRE_EXPORT struct pakfire_solution* pakfire_solution_unref(struct pakfire_solution* solution) {
- if (!solution)
- return NULL;
-
- if (--solution->nrefs > 0)
- return solution;
-
- pakfire_solution_free(solution);
- return NULL;
-}
-
-static size_t count_elements_length(struct pakfire_solution* solution) {
- size_t length = 0;
-
- char** elements = solution->elements;
- while (*elements) {
- length += strlen(*elements++) + 1;
- }
-
- return length;
-}
-
-PAKFIRE_EXPORT char* pakfire_solution_to_string(struct pakfire_solution* solution) {
- // Determine length of output string
- size_t length = count_elements_length(solution);
-
- // Allocate string
- char s[length];
- char* p = s;
-
- char** elements = solution->elements;
- while (*elements) {
- // Copy line
- char* e = *elements++;
- while (*e)
- *p++ = *e++;
-
- // Add newline
- *p++ = '\n';
- }
-
- // Terminate string
- if (p > s)
- *(p-1) = '\0';
+PAKFIRE_EXPORT const char* pakfire_solution_to_string(struct pakfire_solution* solution) {
+ if (!solution->string)
+ solution->string = pakfire_solution_make_string(solution);
- return strdup(s);
+ return solution->string;
}