X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fsolvable.c;h=d3d2d31dff6e9fae7639ed8ccec95a8c1aca969e;hb=18ebbaf4f619e79231f5ad18a2ab8c135d22ef56;hp=8e9497634b1cf2773ca56099a507a4ca037ea325;hpb=cbfff346a94de6b55797d027aa8d605976ed4aaa;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/solvable.c b/src/solvable.c index 8e94976..d3d2d31 100644 --- a/src/solvable.c +++ b/src/solvable.c @@ -32,9 +32,9 @@ pool_solvable2str(Pool *pool, Solvable *s) int nl, el, al; char *p; n = pool_id2str(pool, s->name); - e = pool_id2str(pool, s->evr); + e = s->evr ? pool_id2str(pool, s->evr) : ""; /* XXX: may want to skip the epoch here */ - a = pool_id2str(pool, s->arch); + a = s->arch ? pool_id2str(pool, s->arch) : ""; nl = strlen(n); el = strlen(e); al = strlen(a); @@ -58,6 +58,16 @@ pool_solvable2str(Pool *pool, Solvable *s) p[nl + el] = pool->disttype == DISTTYPE_HAIKU ? '-' : '.'; strcpy(p + nl + el + 1, a); } + if (pool->disttype == DISTTYPE_CONDA && solvable_lookup_type(s, SOLVABLE_BUILDFLAVOR)) + { + Queue flavorq; + int i; + queue_init(&flavorq); + solvable_lookup_idarray(s, SOLVABLE_BUILDFLAVOR, &flavorq); + for (i = 0; i < flavorq.count; i++) + p = pool_tmpappend(pool, p, "-", pool_id2str(pool, flavorq.elements[i])); + queue_free(&flavorq); + } return p; } @@ -110,10 +120,15 @@ solvable_lookup_str_joinarray(Solvable *s, Id keyname, const char *joinstr) if (solvable_lookup_idarray(s, keyname, &q) && q.count) { Pool *pool = s->repo->pool; - int i; - str = pool_tmpjoin(pool, pool_id2str(pool, q.elements[0]), 0, 0); - for (i = 1; i < q.count; i++) - str = pool_tmpappend(pool, str, joinstr, pool_id2str(pool, q.elements[i])); + if (q.count == 1) + str = (char *)pool_id2str(pool, q.elements[0]); + else + { + int i; + str = pool_tmpjoin(pool, pool_id2str(pool, q.elements[0]), 0, 0); + for (i = 1; i < q.count; i++) + str = pool_tmpappend(pool, str, joinstr, pool_id2str(pool, q.elements[i])); + } } queue_free(&q); return str; @@ -126,7 +141,7 @@ solvable_lookup_str(Solvable *s, Id keyname) if (!s->repo) return 0; str = repo_lookup_str(s->repo, s - s->repo->pool->solvables, keyname); - if (!str && (keyname == SOLVABLE_LICENSE || keyname == SOLVABLE_GROUP)) + if (!str && (keyname == SOLVABLE_LICENSE || keyname == SOLVABLE_GROUP || keyname == SOLVABLE_BUILDFLAVOR)) str = solvable_lookup_str_joinarray(s, keyname, ", "); return str; } @@ -238,14 +253,14 @@ solvable_lookup_str_poollang(Solvable *s, Id keyname) const char * solvable_lookup_str_lang(Solvable *s, Id keyname, const char *lang, int usebase) { - if (s->repo) - { - Id id = pool_id2langid(s->repo->pool, keyname, lang, 0); - if (id) - return solvable_lookup_str_base(s, id, keyname, usebase); - if (!usebase) - return 0; - } + Id id; + if (!s->repo) + return 0; + id = pool_id2langid(s->repo->pool, keyname, lang, 0); + if (id) + return solvable_lookup_str_base(s, id, keyname, usebase); + if (!usebase) + return 0; return solvable_lookup_str(s, keyname); } @@ -257,14 +272,14 @@ solvable_lookup_num(Solvable *s, Id keyname, unsigned long long notfound) return repo_lookup_num(s->repo, s - s->repo->pool->solvables, keyname, notfound); } -unsigned int -solvable_lookup_sizek(Solvable *s, Id keyname, unsigned int notfound) +unsigned long long +solvable_lookup_sizek(Solvable *s, Id keyname, unsigned long long notfound) { unsigned long long size; if (!s->repo) return notfound; - size = solvable_lookup_num(s, keyname, (unsigned long long)notfound << 10); - return (unsigned int)((size + 1023) >> 10); + size = solvable_lookup_num(s, keyname, (unsigned long long)-1); + return size == (unsigned long long)-1 ? notfound : ((size + 1023) >> 10); } int @@ -278,25 +293,27 @@ solvable_lookup_void(Solvable *s, Id keyname) int solvable_lookup_bool(Solvable *s, Id keyname) { + Id type; if (!s->repo) return 0; /* historic nonsense: there are two ways of storing a bool, as num == 1 or void. test both. */ - if (repo_lookup_type(s->repo, s - s->repo->pool->solvables, keyname) == REPOKEY_TYPE_VOID) + type = repo_lookup_type(s->repo, s - s->repo->pool->solvables, keyname); + if (type == REPOKEY_TYPE_VOID) return 1; - return repo_lookup_num(s->repo, s - s->repo->pool->solvables, keyname, 0) == 1; + if (type == REPOKEY_TYPE_NUM || type == REPOKEY_TYPE_CONSTANT) + return repo_lookup_num(s->repo, s - s->repo->pool->solvables, keyname, 0) == 1; + return 0; } const unsigned char * solvable_lookup_bin_checksum(Solvable *s, Id keyname, Id *typep) { - Repo *repo = s->repo; - - if (!repo) + if (!s->repo) { *typep = 0; return 0; } - return repo_lookup_bin_checksum(repo, s - repo->pool->solvables, keyname, typep); + return repo_lookup_bin_checksum(s->repo, s - s->repo->pool->solvables, keyname, typep); } const char * @@ -409,305 +426,12 @@ solvable_lookup_sourcepkg(Solvable *s) /*****************************************************************************/ -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; -} - -/* - * solvable_trivial_installable_map - anwers is 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 0 - if (s->repo) - { - Id *obsp, obs; - Repo *installed = 0; - if (s->obsoletes && s->repo != installed) - { - obsp = s->repo->idarraydata + s->obsoletes; - while ((obs = *obsp++) != 0) - { - if (providedbyinstalled(pool, installedmap, obs, 0, 0)) - return 0; - } - } - if (s->repo != installed) - { - Id pp; - FOR_PROVIDES(p, pp, s->name) - { - s2 = pool->solvables + p; - if (s2->repo == installed && s2->name == s->name) - return 0; - } - } - } -#endif - 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; -} - -/* 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; -} - -/*****************************************************************************/ - /* * Create maps containing the state of each solvable. Input is a "installed" queue, * it contains all solvable ids that are considered to be installed. * - * The created maps can be used for solvable_trivial_installable_map(), - * pool_calc_duchanges(), pool_calc_installsizechange(). + * The created maps can be used for * pool_calc_duchanges() and + * pool_calc_installsizechange(). * */ void @@ -745,22 +469,28 @@ pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *con /* Tests if two solvables have identical content. Currently * both solvables need to come from the same pool */ + int solvable_identical(Solvable *s1, Solvable *s2) { - unsigned int bt1, bt2; + unsigned long long bt1, bt2; Id rq1, rq2; Id *reqp; - if (s1->name != s2->name) return 0; if (s1->arch != s2->arch) return 0; if (s1->evr != s2->evr) return 0; - /* map missing vendor to empty string */ + + /* check vendor, map missing vendor to empty string */ if ((s1->vendor ? s1->vendor : 1) != (s2->vendor ? s2->vendor : 1)) - return 0; + { + /* workaround for bug 881493 */ + if (s1->repo && !strncmp(pool_id2str(s1->repo->pool, s1->name), "product:", 8)) + return 1; + return 0; + } /* looking good, try some fancier stuff */ /* might also look up the package checksum here */ @@ -773,6 +503,13 @@ solvable_identical(Solvable *s1, Solvable *s2) } else { + if (s1->repo) + { + /* workaround for bugs 881493 and 885830*/ + const char *n = pool_id2str(s1->repo->pool, s1->name); + if (!strncmp(n, "product:", 8) || !strncmp(n, "application:", 12)) + return 1; + } /* look at requires in a last attempt to find recompiled packages */ rq1 = rq2 = 0; if (s1->requires) @@ -784,6 +521,19 @@ solvable_identical(Solvable *s1, Solvable *s2) if (rq1 != rq2) return 0; } + if (s1->repo && s1->repo->pool->disttype == DISTTYPE_CONDA) + { + /* check buildflavor and buildversion */ + const char *str1, *str2; + str1 = solvable_lookup_str(s1, SOLVABLE_BUILDFLAVOR); + str2 = solvable_lookup_str(s2, SOLVABLE_BUILDFLAVOR); + if (str1 != str2 && (!str1 || !str2 || strcmp(str1, str2) != 0)) + return 0; + str1 = solvable_lookup_str(s1, SOLVABLE_BUILDVERSION); + str2 = solvable_lookup_str(s2, SOLVABLE_BUILDVERSION); + if (str1 != str2 && (!str1 || !str2 || strcmp(str1, str2) != 0)) + return 0; + } return 1; } @@ -881,6 +631,9 @@ solvable_matchesdep(Solvable *s, Id keyname, Id dep, int marker) int i; Pool *pool = s->repo->pool; Queue q; + + if (keyname == SOLVABLE_NAME) + return pool_match_nevr(pool, s, dep) ? 1 : 0; /* nevr match hack */ queue_init(&q); solvable_lookup_deparray(s, keyname, &q, marker); for (i = 0; i < q.count; i++) @@ -890,3 +643,67 @@ solvable_matchesdep(Solvable *s, Id keyname, Id dep, int marker) queue_free(&q); return i; } + +int +solvable_matchessolvable_int(Solvable *s, Id keyname, int marker, Id solvid, Map *solvidmap, Queue *depq, Map *missc, int reloff) +{ + Pool *pool = s->repo->pool; + int i, boff; + Id *wp; + + if (depq->count) + queue_empty(depq); + solvable_lookup_deparray(s, keyname, depq, marker); + for (i = 0; i < depq->count; i++) + { + Id dep = depq->elements[i]; + boff = ISRELDEP(dep) ? reloff + GETRELID(dep) : dep; + if (MAPTST(missc, boff)) + continue; + if (ISRELDEP(dep)) + { + Reldep *rd = GETRELDEP(pool, dep); + if (!ISRELDEP(rd->name) && rd->flags < 8) + { + /* do pre-filtering on the base */ + if (MAPTST(missc, rd->name)) + continue; + wp = pool_whatprovides_ptr(pool, rd->name); + if (solvidmap) + { + for (; *wp; wp++) + if (MAPTST(solvidmap, *wp)) + break; + } + else + { + for (; *wp; wp++) + if (*wp == solvid) + break; + } + if (!*wp) + { + /* the base does not include solvid, no need to check the complete dep */ + MAPSET(missc, rd->name); + MAPSET(missc, boff); + continue; + } + } + } + wp = pool_whatprovides_ptr(pool, dep); + if (solvidmap) + { + for (; *wp; wp++) + if (MAPTST(solvidmap, *wp)) + return 1; + } + else + { + for (; *wp; wp++) + if (*wp == solvid) + return 1; + } + MAPSET(missc, boff); + } + return 0; +}