summaryrefslogtreecommitdiff
path: root/src/suse.c
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-27 14:58:05 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-27 14:58:05 +0900
commitf458102388250c8a1cbbfa8f18d27baa204c696c (patch)
tree447d75c1ae4449828e094d36a2f97f9b46b455ef /src/suse.c
parent8fcc0d8e03716077d1f2c2ca79fc622880a32196 (diff)
downloadlibsolv-f458102388250c8a1cbbfa8f18d27baa204c696c.tar.gz
libsolv-f458102388250c8a1cbbfa8f18d27baa204c696c.tar.bz2
libsolv-f458102388250c8a1cbbfa8f18d27baa204c696c.zip
Imported Upstream version 0.6.23upstream/0.6.23
Change-Id: Idc1e282dc113b7350d8e123283f1a36097b76857 Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'src/suse.c')
-rw-r--r--src/suse.c748
1 files changed, 748 insertions, 0 deletions
diff --git a/src/suse.c b/src/suse.c
new file mode 100644
index 0000000..6106f3f
--- /dev/null
+++ b/src/suse.c
@@ -0,0 +1,748 @@
+/*
+ * Copyright (c) 2016, SUSE LLC.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+/* weird SUSE stuff. better not use it for your projects. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "solver.h"
+#include "solver_private.h"
+#include "bitmap.h"
+#include "pool.h"
+#include "poolvendor.h"
+#include "util.h"
+
+Offset
+repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens)
+{
+ Pool *pool = repo->pool;
+ Id id, idp, idl;
+ char buf[1024], *p, *dep;
+ int i, l;
+
+ if (provides)
+ {
+ for (i = provides; repo->idarraydata[i]; i++)
+ {
+ id = repo->idarraydata[i];
+ if (ISRELDEP(id))
+ continue;
+ dep = (char *)pool_id2str(pool, id);
+ if (!strncmp(dep, "locale(", 7) && strlen(dep) < sizeof(buf) - 2)
+ {
+ idp = 0;
+ strcpy(buf + 2, dep);
+ dep = buf + 2 + 7;
+ if ((p = strchr(dep, ':')) != 0 && p != dep)
+ {
+ *p++ = 0;
+ idp = pool_str2id(pool, dep, 1);
+ dep = p;
+ }
+ id = 0;
+ while ((p = strchr(dep, ';')) != 0)
+ {
+ if (p == dep)
+ {
+ dep = p + 1;
+ continue;
+ }
+ *p++ = 0;
+ idl = pool_str2id(pool, dep, 1);
+ idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
+ if (id)
+ id = pool_rel2id(pool, id, idl, REL_OR, 1);
+ else
+ id = idl;
+ dep = p;
+ }
+ if (dep[0] && dep[1])
+ {
+ for (p = dep; *p && *p != ')'; p++)
+ ;
+ *p = 0;
+ idl = pool_str2id(pool, dep, 1);
+ idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
+ if (id)
+ id = pool_rel2id(pool, id, idl, REL_OR, 1);
+ else
+ id = idl;
+ }
+ if (idp)
+ id = pool_rel2id(pool, idp, id, REL_AND, 1);
+ if (id)
+ supplements = repo_addid_dep(repo, supplements, id, 0);
+ }
+ else if ((p = strchr(dep, ':')) != 0 && p != dep && p[1] == '/' && strlen(dep) < sizeof(buf))
+ {
+ strcpy(buf, dep);
+ p = buf + (p - dep);
+ *p++ = 0;
+ idp = pool_str2id(pool, buf, 1);
+ /* strip trailing slashes */
+ l = strlen(p);
+ while (l > 1 && p[l - 1] == '/')
+ p[--l] = 0;
+ id = pool_str2id(pool, p, 1);
+ id = pool_rel2id(pool, idp, id, REL_WITH, 1);
+ id = pool_rel2id(pool, NAMESPACE_SPLITPROVIDES, id, REL_NAMESPACE, 1);
+ supplements = repo_addid_dep(repo, supplements, id, 0);
+ }
+ }
+ }
+ if (supplements)
+ {
+ for (i = supplements; repo->idarraydata[i]; i++)
+ {
+ id = repo->idarraydata[i];
+ if (ISRELDEP(id))
+ continue;
+ dep = (char *)pool_id2str(pool, id);
+ if (!strncmp(dep, "system:modalias(", 16))
+ dep += 7;
+ if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf))
+ {
+ strcpy(buf, dep);
+ p = strchr(buf + 9, ':');
+ if (p && p != buf + 9 && strchr(p + 1, ':'))
+ {
+ *p++ = 0;
+ idp = pool_str2id(pool, buf + 9, 1);
+ p[strlen(p) - 1] = 0;
+ id = pool_str2id(pool, p, 1);
+ id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
+ id = pool_rel2id(pool, idp, id, REL_AND, 1);
+ }
+ else
+ {
+ p = buf + 9;
+ p[strlen(p) - 1] = 0;
+ id = pool_str2id(pool, p, 1);
+ id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
+ }
+ if (id)
+ repo->idarraydata[i] = id;
+ }
+ else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf))
+ {
+ strcpy(buf, dep);
+ id = 0;
+ dep = buf + 11;
+ while ((p = strchr(dep, ':')) != 0)
+ {
+ if (p == dep)
+ {
+ dep = p + 1;
+ continue;
+ }
+ /* argh, allow pattern: prefix. sigh */
+ if (p - dep == 7 && !strncmp(dep, "pattern", 7))
+ {
+ p = strchr(p + 1, ':');
+ if (!p)
+ break;
+ }
+ *p++ = 0;
+ idp = pool_str2id(pool, dep, 1);
+ if (id)
+ id = pool_rel2id(pool, id, idp, REL_AND, 1);
+ else
+ id = idp;
+ dep = p;
+ }
+ if (dep[0] && dep[1])
+ {
+ dep[strlen(dep) - 1] = 0;
+ idp = pool_str2id(pool, dep, 1);
+ if (id)
+ id = pool_rel2id(pool, id, idp, REL_AND, 1);
+ else
+ id = idp;
+ }
+ if (id)
+ repo->idarraydata[i] = id;
+ }
+ else if (!strncmp(dep, "filesystem(", 11) && strlen(dep) < sizeof(buf))
+ {
+ strcpy(buf, dep + 11);
+ if ((p = strrchr(buf, ')')) != 0)
+ *p = 0;
+ id = pool_str2id(pool, buf, 1);
+ id = pool_rel2id(pool, NAMESPACE_FILESYSTEM, id, REL_NAMESPACE, 1);
+ repo->idarraydata[i] = id;
+ }
+ }
+ }
+ if (freshens && repo->idarraydata[freshens])
+ {
+ Id idsupp = 0, idfresh = 0;
+ if (!supplements || !repo->idarraydata[supplements])
+ return freshens;
+ for (i = supplements; repo->idarraydata[i]; i++)
+ {
+ if (!idsupp)
+ idsupp = repo->idarraydata[i];
+ else
+ idsupp = pool_rel2id(pool, idsupp, repo->idarraydata[i], REL_OR, 1);
+ }
+ for (i = freshens; repo->idarraydata[i]; i++)
+ {
+ if (!idfresh)
+ idfresh = repo->idarraydata[i];
+ else
+ idfresh = pool_rel2id(pool, idfresh, repo->idarraydata[i], REL_OR, 1);
+ }
+ if (!idsupp)
+ idsupp = idfresh;
+ else
+ idsupp = pool_rel2id(pool, idsupp, idfresh, REL_AND, 1);
+ supplements = repo_addid_dep(repo, 0, idsupp, 0);
+ }
+ return supplements;
+}
+
+Offset
+repo_fix_conflicts(Repo *repo, Offset conflicts)
+{
+ char buf[1024], *p, *dep;
+ Pool *pool = repo->pool;
+ Id id;
+ int i;
+
+ if (!conflicts)
+ return conflicts;
+ for (i = conflicts; repo->idarraydata[i]; i++)
+ {
+ id = repo->idarraydata[i];
+ if (ISRELDEP(id))
+ continue;
+ dep = (char *)pool_id2str(pool, id);
+ if (!strncmp(dep, "otherproviders(", 15) && strlen(dep) < sizeof(buf) - 2)
+ {
+ strcpy(buf, dep + 15);
+ if ((p = strchr(buf, ')')) != 0)
+ *p = 0;
+ id = pool_str2id(pool, buf, 1);
+ id = pool_rel2id(pool, NAMESPACE_OTHERPROVIDERS, id, REL_NAMESPACE, 1);
+ repo->idarraydata[i] = id;
+ }
+ }
+ return conflicts;
+}
+
+void
+repo_rewrite_suse_deps(Solvable *s, Offset freshens)
+{
+ s->supplements = repo_fix_supplements(s->repo, s->provides, s->supplements, freshens);
+ if (s->conflicts)
+ s->conflicts = repo_fix_conflicts(s->repo, s->conflicts);
+}
+
+/**********************************************************************************/
+
+static inline Id
+dep2name(Pool *pool, Id dep)
+{
+ while (ISRELDEP(dep))
+ {
+ Reldep *rd = GETRELDEP(pool, dep);
+ dep = rd->name;
+ }
+ return dep;
+}
+
+static int
+providedbyinstalled_multiversion(Pool *pool, Map *installed, Id n, Id con)
+{
+ Id p, pp;
+ Solvable *sn = pool->solvables + n;
+
+ FOR_PROVIDES(p, pp, sn->name)
+ {
+ Solvable *s = pool->solvables + p;
+ if (s->name != sn->name || s->arch != sn->arch)
+ continue;
+ if (!MAPTST(installed, p))
+ continue;
+ if (pool_match_nevr(pool, pool->solvables + p, con))
+ continue;
+ return 1; /* found installed package that doesn't conflict */
+ }
+ return 0;
+}
+
+static inline int
+providedbyinstalled(Pool *pool, Map *installed, Id dep, int ispatch, Map *multiversionmap)
+{
+ Id p, pp;
+ FOR_PROVIDES(p, pp, dep)
+ {
+ if (p == SYSTEMSOLVABLE)
+ return -1;
+ if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep))
+ continue;
+ if (ispatch && multiversionmap && multiversionmap->size && MAPTST(multiversionmap, p) && ISRELDEP(dep))
+ if (providedbyinstalled_multiversion(pool, installed, p, dep))
+ continue;
+ if (MAPTST(installed, p))
+ return 1;
+ }
+ return 0;
+}
+
+/* xmap:
+ * 1: installed
+ * 2: conflicts with installed
+ * 8: interesting (only true if installed)
+ * 16: undecided
+ */
+
+static int
+providedbyinstalled_multiversion_xmap(Pool *pool, unsigned char *map, Id n, Id con)
+{
+ Id p, pp;
+ Solvable *sn = pool->solvables + n;
+
+ FOR_PROVIDES(p, pp, sn->name)
+ {
+ Solvable *s = pool->solvables + p;
+ if (s->name != sn->name || s->arch != sn->arch)
+ continue;
+ if ((map[p] & 9) != 9)
+ continue;
+ if (pool_match_nevr(pool, pool->solvables + p, con))
+ continue;
+ return 1; /* found installed package that doesn't conflict */
+ }
+ return 0;
+}
+
+
+static inline int
+providedbyinstalled_xmap(Pool *pool, unsigned char *map, Id dep, int ispatch, Map *multiversionmap)
+{
+ Id p, pp;
+ int r = 0;
+ FOR_PROVIDES(p, pp, dep)
+ {
+ if (p == SYSTEMSOLVABLE)
+ return 1; /* always boring, as never constraining */
+ if (ispatch && !pool_match_nevr(pool, pool->solvables + p, dep))
+ continue;
+ if (ispatch && multiversionmap && multiversionmap->size && MAPTST(multiversionmap, p) && ISRELDEP(dep))
+ if (providedbyinstalled_multiversion_xmap(pool, map, p, dep))
+ continue;
+ if ((map[p] & 9) == 9)
+ return 9;
+ r |= map[p] & 17;
+ }
+ return r;
+}
+
+/* FIXME: this mirrors policy_illegal_vendorchange */
+static int
+pool_illegal_vendorchange(Pool *pool, Solvable *s1, Solvable *s2)
+{
+ Id v1, v2;
+ Id vendormask1, vendormask2;
+
+ if (pool->custom_vendorcheck)
+ return pool->custom_vendorcheck(pool, s1, s2);
+ /* treat a missing vendor as empty string */
+ v1 = s1->vendor ? s1->vendor : ID_EMPTY;
+ v2 = s2->vendor ? s2->vendor : ID_EMPTY;
+ if (v1 == v2)
+ return 0;
+ vendormask1 = pool_vendor2mask(pool, v1);
+ if (!vendormask1)
+ return 1; /* can't match */
+ vendormask2 = pool_vendor2mask(pool, v2);
+ if ((vendormask1 & vendormask2) != 0)
+ return 0;
+ return 1; /* no class matches */
+}
+
+/* check if this patch is relevant according to the vendor. To bad that patches
+ * don't have a vendor, so we need to do some careful repo testing. */
+int
+solvable_is_irrelevant_patch(Solvable *s, Map *installedmap)
+{
+ Pool *pool = s->repo->pool;
+ Id con, *conp;
+ int hadpatchpackage = 0;
+
+ if (!s->conflicts)
+ return 0;
+ conp = s->repo->idarraydata + s->conflicts;
+ while ((con = *conp++) != 0)
+ {
+ Reldep *rd;
+ Id p, pp, p2, pp2;
+ if (!ISRELDEP(con))
+ continue;
+ rd = GETRELDEP(pool, con);
+ if (rd->flags != REL_LT)
+ continue;
+ FOR_PROVIDES(p, pp, con)
+ {
+ Solvable *si;
+ if (!MAPTST(installedmap, p))
+ continue;
+ si = pool->solvables + p;
+ if (!pool_match_nevr(pool, si, con))
+ continue;
+ FOR_PROVIDES(p2, pp2, rd->name)
+ {
+ Solvable *s2 = pool->solvables + p2;
+ if (!pool_match_nevr(pool, s2, rd->name))
+ continue;
+ if (pool_match_nevr(pool, s2, con))
+ continue; /* does not fulfill patch */
+ if (s2->repo == s->repo)
+ {
+ hadpatchpackage = 1;
+ /* ok, we have a package from the patch repo that solves the conflict. check vendor */
+ if (si->vendor == s2->vendor)
+ return 0;
+ if (!pool_illegal_vendorchange(pool, si, s2))
+ return 0;
+ /* vendor change was illegal, ignore conflict */
+ }
+ }
+ }
+ }
+ /* if we didn't find a patchpackage don't claim that the patch is irrelevant */
+ if (!hadpatchpackage)
+ return 0;
+ return 1;
+}
+
+/*
+ * solvable_trivial_installable_map - answers if a solvable is installable
+ * without any other installs/deinstalls.
+ * The packages considered to be installed are provided via the
+ * installedmap bitmap. A additional "conflictsmap" bitmap providing
+ * information about the conflicts of the installed packages can be
+ * used for extra speed up. Provide a NULL pointer if you do not
+ * have this information.
+ * Both maps can be created with pool_create_state_maps() or
+ * solver_create_state_maps().
+ *
+ * returns:
+ * 1: solvable is installable without any other package changes
+ * 0: solvable is not installable
+ * -1: solvable is installable, but doesn't constrain any installed packages
+ */
+int
+solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *multiversionmap)
+{
+ Pool *pool = s->repo->pool;
+ Solvable *s2;
+ Id p, *dp;
+ Id *reqp, req;
+ Id *conp, con;
+ int r, interesting = 0;
+
+ if (conflictsmap && MAPTST(conflictsmap, s - pool->solvables))
+ return 0;
+ if (s->requires)
+ {
+ reqp = s->repo->idarraydata + s->requires;
+ while ((req = *reqp++) != 0)
+ {
+ if (req == SOLVABLE_PREREQMARKER)
+ continue;
+ r = providedbyinstalled(pool, installedmap, req, 0, 0);
+ if (!r)
+ return 0;
+ if (r > 0)
+ interesting = 1;
+ }
+ }
+ if (s->conflicts)
+ {
+ int ispatch = 0;
+
+ if (!strncmp("patch:", pool_id2str(pool, s->name), 6))
+ ispatch = 1;
+ conp = s->repo->idarraydata + s->conflicts;
+ while ((con = *conp++) != 0)
+ {
+ if (providedbyinstalled(pool, installedmap, con, ispatch, multiversionmap))
+ {
+ if (ispatch && solvable_is_irrelevant_patch(s, installedmap))
+ return -1;
+ return 0;
+ }
+ if (!interesting && ISRELDEP(con))
+ {
+ con = dep2name(pool, con);
+ if (providedbyinstalled(pool, installedmap, con, ispatch, multiversionmap))
+ interesting = 1;
+ }
+ }
+ if (ispatch && interesting && solvable_is_irrelevant_patch(s, installedmap))
+ interesting = 0;
+ }
+ if (!conflictsmap)
+ {
+ int i;
+
+ p = s - pool->solvables;
+ for (i = 1; i < pool->nsolvables; i++)
+ {
+ if (!MAPTST(installedmap, i))
+ continue;
+ s2 = pool->solvables + i;
+ if (!s2->conflicts)
+ continue;
+ conp = s2->repo->idarraydata + s2->conflicts;
+ while ((con = *conp++) != 0)
+ {
+ dp = pool_whatprovides_ptr(pool, con);
+ for (; *dp; dp++)
+ if (*dp == p)
+ return 0;
+ }
+ }
+ }
+ return interesting ? 1 : -1;
+}
+
+/*
+ * different interface for solvable_trivial_installable_map, where
+ * the information about the installed packages is provided
+ * by a queue.
+ */
+int
+solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *multiversionmap)
+{
+ Pool *pool = s->repo->pool;
+ int i;
+ Id p;
+ Map installedmap;
+ int r;
+
+ map_init(&installedmap, pool->nsolvables);
+ for (i = 0; i < installed->count; i++)
+ {
+ p = installed->elements[i];
+ if (p > 0) /* makes it work with decisionq */
+ MAPSET(&installedmap, p);
+ }
+ r = solvable_trivial_installable_map(s, &installedmap, 0, multiversionmap);
+ map_free(&installedmap);
+ return r;
+}
+
+/*
+ * different interface for solvable_trivial_installable_map, where
+ * the information about the installed packages is provided
+ * by a repo containing the installed solvables.
+ */
+int
+solvable_trivial_installable_repo(Solvable *s, Repo *installed, Map *multiversionmap)
+{
+ Pool *pool = s->repo->pool;
+ Id p;
+ Solvable *s2;
+ Map installedmap;
+ int r;
+
+ map_init(&installedmap, pool->nsolvables);
+ FOR_REPO_SOLVABLES(installed, p, s2)
+ MAPSET(&installedmap, p);
+ r = solvable_trivial_installable_map(s, &installedmap, 0, multiversionmap);
+ map_free(&installedmap);
+ return r;
+}
+
+/*
+ * pool_trivial_installable - calculate if a set of solvables is
+ * trivial installable without any other installs/deinstalls of
+ * packages not belonging to the set.
+ *
+ * the state is returned in the result queue:
+ * 1: solvable is installable without any other package changes
+ * 0: solvable is not installable
+ * -1: solvable is installable, but doesn't constrain any installed packages
+ */
+
+void
+pool_trivial_installable_multiversionmap(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res, Map *multiversionmap)
+{
+ int i, r, m, did;
+ Id p, *dp, con, *conp, req, *reqp;
+ unsigned char *map;
+ Solvable *s;
+
+ map = solv_calloc(pool->nsolvables, 1);
+ for (p = 1; p < pool->nsolvables; p++)
+ {
+ if (!MAPTST(installedmap, p))
+ continue;
+ map[p] |= 9;
+ s = pool->solvables + p;
+ if (!s->conflicts)
+ continue;
+ conp = s->repo->idarraydata + s->conflicts;
+ while ((con = *conp++) != 0)
+ {
+ dp = pool_whatprovides_ptr(pool, con);
+ for (; *dp; dp++)
+ map[p] |= 2; /* XXX: self conflict ? */
+ }
+ }
+ for (i = 0; i < pkgs->count; i++)
+ map[pkgs->elements[i]] = 16;
+
+ for (i = 0, did = 0; did < pkgs->count; i++, did++)
+ {
+ if (i == pkgs->count)
+ i = 0;
+ p = pkgs->elements[i];
+ if ((map[p] & 16) == 0)
+ continue;
+ if ((map[p] & 2) != 0)
+ {
+ map[p] = 2;
+ continue;
+ }
+ s = pool->solvables + p;
+ m = 1;
+ if (s->requires)
+ {
+ reqp = s->repo->idarraydata + s->requires;
+ while ((req = *reqp++) != 0)
+ {
+ if (req == SOLVABLE_PREREQMARKER)
+ continue;
+ r = providedbyinstalled_xmap(pool, map, req, 0, 0);
+ if (!r)
+ {
+ /* decided and miss */
+ map[p] = 2;
+ did = 0;
+ break;
+ }
+ if (r == 16)
+ break; /* undecided */
+ m |= r; /* 1 | 9 | 17 */
+ }
+ if (req)
+ continue;
+ if ((m & 9) == 9)
+ m = 9;
+ }
+ if (s->conflicts)
+ {
+ int ispatch = 0; /* see solver.c patch handling */
+
+ if (!strncmp("patch:", pool_id2str(pool, s->name), 6))
+ ispatch = 1;
+ conp = s->repo->idarraydata + s->conflicts;
+ while ((con = *conp++) != 0)
+ {
+ if ((providedbyinstalled_xmap(pool, map, con, ispatch, multiversionmap) & 1) != 0)
+ {
+ map[p] = 2;
+ did = 0;
+ break;
+ }
+ if ((m == 1 || m == 17) && ISRELDEP(con))
+ {
+ con = dep2name(pool, con);
+ if ((providedbyinstalled_xmap(pool, map, con, ispatch, multiversionmap) & 1) != 0)
+ m = 9;
+ }
+ }
+ if (con)
+ continue; /* found a conflict */
+ }
+ if (m != map[p])
+ {
+ map[p] = m;
+ did = 0;
+ }
+ }
+ queue_free(res);
+ queue_init_clone(res, pkgs);
+ for (i = 0; i < pkgs->count; i++)
+ {
+ m = map[pkgs->elements[i]];
+ if ((m & 9) == 9)
+ r = 1;
+ else if (m & 1)
+ r = -1;
+ else
+ r = 0;
+ res->elements[i] = r;
+ }
+ free(map);
+}
+
+void
+pool_trivial_installable(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res)
+{
+ pool_trivial_installable_multiversionmap(pool, installedmap, pkgs, res, 0);
+}
+
+void
+solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res)
+{
+ Pool *pool = solv->pool;
+ Map installedmap;
+ int i;
+ pool_create_state_maps(pool, &solv->decisionq, &installedmap, 0);
+ pool_trivial_installable_multiversionmap(pool, &installedmap, pkgs, res, solv->multiversion.size ? &solv->multiversion : 0);
+ for (i = 0; i < res->count; i++)
+ if (res->elements[i] != -1)
+ {
+ Solvable *s = pool->solvables + pkgs->elements[i];
+ if (!strncmp("patch:", pool_id2str(pool, s->name), 6) && solvable_is_irrelevant_patch(s, &installedmap))
+ res->elements[i] = -1;
+ }
+ map_free(&installedmap);
+}
+
+void
+solver_printtrivial(Solver *solv)
+{
+ Pool *pool = solv->pool;
+ Queue in, out;
+ Id p;
+ const char *n;
+ Solvable *s;
+ int i;
+
+ queue_init(&in);
+ for (p = 1, s = pool->solvables + p; p < solv->pool->nsolvables; p++, s++)
+ {
+ n = pool_id2str(pool, s->name);
+ if (strncmp(n, "patch:", 6) != 0 && strncmp(n, "pattern:", 8) != 0)
+ continue;
+ queue_push(&in, p);
+ }
+ if (!in.count)
+ {
+ queue_free(&in);
+ return;
+ }
+ queue_init(&out);
+ solver_trivial_installable(solv, &in, &out);
+ POOL_DEBUG(SOLV_DEBUG_RESULT, "trivial installable status:\n");
+ for (i = 0; i < in.count; i++)
+ POOL_DEBUG(SOLV_DEBUG_RESULT, " %s: %d\n", pool_solvid2str(pool, in.elements[i]), out.elements[i]);
+ POOL_DEBUG(SOLV_DEBUG_RESULT, "\n");
+ queue_free(&in);
+ queue_free(&out);
+}
+
+