X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Flinkedpkg.c;h=6387373c71be5cda2385bb67281f6bf59412e661;hb=2903497e256388eff53b408875c0f2239c3566cb;hp=c5adc9a14c6653a6b66f8cb721f76a8b0355dd3d;hpb=fd257fb9c490f4af3fbfb71c4d099fe876be28eb;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/linkedpkg.c b/src/linkedpkg.c index c5adc9a..6387373 100644 --- a/src/linkedpkg.c +++ b/src/linkedpkg.c @@ -21,7 +21,7 @@ * * product: * created from product data in the repository (which is generated from files - * in /etc/products.d. In the future we may switch to using product() + * in /etc/products.d). In the future we may switch to using product() * provides of packages. * * pattern: @@ -37,6 +37,7 @@ #include "pool.h" #include "repo.h" +#include "evr.h" #include "linkedpkg.h" #ifdef ENABLE_LINKED_PKGS @@ -47,12 +48,11 @@ find_application_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp Id req = 0; Id prv = 0; Id p, pp; - Id pkgname = 0; + Id pkgname = 0, appdataid = 0; /* find appdata requires */ if (s->requires) { - Id appdataid = 0; Id *reqp = s->repo->idarraydata + s->requires; while ((req = *reqp++) != 0) /* go through all requires */ { @@ -63,22 +63,34 @@ find_application_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp else pkgname = req; } - req = appdataid; } + req = appdataid ? appdataid : pkgname; if (!req) return; /* find application-appdata provides */ if (s->provides) { Id *prvp = s->repo->idarraydata + s->provides; + const char *reqs = pool_id2str(pool, req); + const char *prvs; while ((prv = *prvp++) != 0) /* go through all provides */ { if (ISRELDEP(prv)) continue; - if (strncmp("application-appdata(", pool_id2str(pool, prv), 20)) + prvs = pool_id2str(pool, prv); + if (strncmp("application-appdata(", prvs, 20)) continue; - if (!strcmp(pool_id2str(pool, prv) + 12, pool_id2str(pool, req))) - break; + if (appdataid) + { + if (!strcmp(prvs + 12, reqs)) + break; + } + else + { + int reqsl = strlen(reqs); + if (!strncmp(prvs + 20, reqs, reqsl) && !strcmp(prvs + 20 + reqsl, ")")) + break; + } } } if (!prv) @@ -88,7 +100,7 @@ find_application_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp if (pool->solvables[p].repo == s->repo) if (!pkgname || pool->solvables[p].name == pkgname) queue_push(qr, p); - if (!qr->count && pkgname) + if (!qr->count && pkgname && appdataid) { /* huh, no matching package? try without pkgname filter */ FOR_PROVIDES(p, pp, req) @@ -112,6 +124,7 @@ find_product_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp, Qu { Id p, pp, namerelid; char *str; + unsigned int sbt = 0; /* search for project requires */ namerelid = 0; @@ -149,6 +162,29 @@ find_product_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp, Qu continue; queue_push(qr, p); } + if (qr->count > 1) + { + /* multiple providers. try buildtime filter */ + sbt = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0); + if (sbt) + { + unsigned int bt; + int i, j; + int filterqp = 1; + for (i = j = 0; i < qr->count; i++) + { + bt = solvable_lookup_num(pool->solvables + qr->elements[i], SOLVABLE_BUILDTIME, 0); + if (!bt) + filterqp = 0; /* can't filter */ + if (!bt || bt == sbt) + qr->elements[j++] = qr->elements[i]; + } + if (j) + qr->count = j; + if (!j || !filterqp) + sbt = 0; /* filter failed */ + } + } if (!qr->count && s->repo == pool->installed) { /* oh no! Look up reference file */ @@ -174,6 +210,8 @@ find_product_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp, Qu Solvable *ps = pool->solvables + p; if (s->name != ps->name || ps->repo != s->repo || ps->arch != s->arch || s->evr != ps->evr) continue; + if (sbt && solvable_lookup_num(ps, SOLVABLE_BUILDTIME, 0) != sbt) + continue; queue_push(qp, p); } } @@ -272,4 +310,72 @@ find_package_link(Pool *pool, Solvable *s, Id *reqidp, Queue *qr, Id *prvidp, Qu find_product_link(pool, s, reqidp, qr, prvidp, qp); } +static int +name_min_max(Pool *pool, Solvable *s, Id *namep, Id *minp, Id *maxp) +{ + Queue q; + Id qbuf[4]; + Id name, min, max; + int i; + + queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf)); + find_package_link(pool, s, 0, &q, 0, 0); + if (!q.count) + { + queue_free(&q); + return 0; + } + s = pool->solvables + q.elements[0]; + name = s->name; + min = max = s->evr; + for (i = 1; i < q.count; i++) + { + s = pool->solvables + q.elements[i]; + if (s->name != name) + { + queue_free(&q); + return 0; + } + if (s->evr == min || s->evr == max) + continue; + if (pool_evrcmp(pool, min, s->evr, EVRCMP_COMPARE) >= 0) + min = s->evr; + else if (min == max || pool_evrcmp(pool, max, s->evr, EVRCMP_COMPARE) <= 0) + max = s->evr; + } + queue_free(&q); + *namep = name; + *minp = min; + *maxp = max; + return 1; +} + +int +pool_link_evrcmp(Pool *pool, Solvable *s1, Solvable *s2) +{ + Id name1, evrmin1, evrmax1; + Id name2, evrmin2, evrmax2; + + if (s1->name != s2->name) + return 0; /* can't compare */ + if (!name_min_max(pool, s1, &name1, &evrmin1, &evrmax1)) + return 0; + if (!name_min_max(pool, s2, &name2, &evrmin2, &evrmax2)) + return 0; + /* compare linked names */ + if (name1 != name2) + return 0; + if (evrmin1 == evrmin2 && evrmax1 == evrmax2) + return 0; + /* now compare evr intervals */ + if (evrmin1 == evrmax1 && evrmin2 == evrmax2) + return pool_evrcmp(pool, evrmin1, evrmax2, EVRCMP_COMPARE); + if (evrmin1 != evrmax2 && pool_evrcmp(pool, evrmin1, evrmax2, EVRCMP_COMPARE) > 0) + return 1; + if (evrmax1 != evrmin2 && pool_evrcmp(pool, evrmax1, evrmin2, EVRCMP_COMPARE) < 0) + return -1; + return 0; +} + + #endif