diff options
author | Michael Schroeder <mls@suse.de> | 2014-01-27 15:51:03 +0100 |
---|---|---|
committer | Michael Schroeder <mls@suse.de> | 2014-01-27 15:51:03 +0100 |
commit | a53d7e345aa71a076ef238c725a1f8d95bca843d (patch) | |
tree | fce7bbe3ef01c737c4027eb4f65d9f585abcd98f | |
parent | 8b25311cabdb5bbbd7f54592ae4c9db1ec932f77 (diff) | |
download | libsolv-a53d7e345aa71a076ef238c725a1f8d95bca843d.tar.gz libsolv-a53d7e345aa71a076ef238c725a1f8d95bca843d.tar.bz2 libsolv-a53d7e345aa71a076ef238c725a1f8d95bca843d.zip |
add autoproduct support
-rw-r--r-- | ext/repo_autopattern.c | 183 |
1 files changed, 164 insertions, 19 deletions
diff --git a/ext/repo_autopattern.c b/ext/repo_autopattern.c index 5a663ba..0272f02 100644 --- a/ext/repo_autopattern.c +++ b/ext/repo_autopattern.c @@ -61,37 +61,59 @@ repo_add_autopattern(Repo *repo, int flags) Pool *pool = repo->pool; Repodata *data = 0; Solvable *s, *s2; - Queue q, q2; + Queue patq, patq2; + Queue prdq, prdq2; Id p; - Id pattern_id; - Id autopattern_id = 0; + Id pattern_id, product_id; + Id autopattern_id = 0, autoproduct_id = 0; int i, j; - queue_init(&q); - queue_init(&q2); + queue_init(&patq); + queue_init(&patq2); + queue_init(&prdq); + queue_init(&prdq2); pattern_id = pool_str2id(pool, "pattern()", 9); + product_id = pool_str2id(pool, "product()", 9); FOR_REPO_SOLVABLES(repo, p, s) { const char *n = pool_id2str(pool, s->name); - if (!strncmp("pattern:", n, 8)) - queue_push(&q, p); - else if (s->provides) + if (*n == 'p') + { + if (!strncmp("pattern:", n, 8)) + { + queue_push(&patq, p); + continue; + } + else if (!strncmp("product:", n, 8)) + { + queue_push(&prdq, p); + continue; + } + } + if (s->provides) { Id prv, *prvp = repo->idarraydata + s->provides; while ((prv = *prvp++) != 0) /* go through all provides */ if (ISRELDEP(prv)) { Reldep *rd = GETRELDEP(pool, prv); - if (rd->name == pattern_id && rd->flags == REL_EQ) + if (rd->flags != REL_EQ) + continue; + if (rd->name == pattern_id) + { + queue_push2(&patq2, p, rd->evr); + break; + } + if (rd->name == product_id) { - queue_push2(&q2, p, rd->evr); + queue_push2(&prdq2, p, rd->evr); break; } } } } - for (i = 0; i < q2.count; i += 2) + for (i = 0; i < patq2.count; i += 2) { const char *pn = 0; char *newname; @@ -99,21 +121,21 @@ repo_add_autopattern(Repo *repo, int flags) const char *str; unsigned long long num; - s = pool->solvables + q2.elements[i]; + s = pool->solvables + patq2.elements[i]; /* construct new name */ - newname = pool_tmpjoin(pool, "pattern:", pool_id2str(pool, q2.elements[i + 1]), 0); + newname = pool_tmpjoin(pool, "pattern:", pool_id2str(pool, patq2.elements[i + 1]), 0); unescape(newname); name = pool_str2id(pool, newname, 0); if (name) { /* check if we already have that pattern */ - for (j = 0; j < q.count; j++) + for (j = 0; j < patq.count; j++) { - s2 = pool->solvables + q.elements[j]; + s2 = pool->solvables + patq.elements[j]; if (s2->name == name && s2->arch == s->arch && s2->evr == s->evr) break; } - if (j < q.count) + if (j < patq.count) continue; /* yes, do not add again */ } /* new pattern */ @@ -125,7 +147,7 @@ repo_add_autopattern(Repo *repo, int flags) data = repo_add_repodata(repo, flags); } s2 = pool_id2solvable(pool, repo_add_solvable(repo)); - s = pool->solvables + q2.elements[i]; /* re-calc pointer */ + s = pool->solvables + patq2.elements[i]; /* re-calc pointer */ s2->name = name; s2->arch = s->arch; s2->evr = s->evr; @@ -201,8 +223,131 @@ repo_add_autopattern(Repo *repo, int flags) repodata_set_void(data, s2 - pool->solvables, SOLVABLE_ISVISIBLE); } } - queue_free(&q); - queue_free(&q2); + queue_free(&patq); + queue_free(&patq2); + + if (repo == pool->installed) + queue_empty(&prdq2); /* no auto products for installed repos */ + + for (i = 0; i < prdq2.count; i += 2) + { + const char *pn = 0; + char *newname; + Id name, evr = 0, prv, *prvp; + const char *str; + unsigned long long num; + + s = pool->solvables + prdq2.elements[i]; + /* construct new name */ + newname = pool_tmpjoin(pool, "product(", pool_id2str(pool, prdq2.elements[i + 1]), ")"); + unescape(newname); + name = pool_str2id(pool, newname, 0); + if (!name) + continue; /* must have it in provides! */ + prvp = repo->idarraydata + s->provides; + while ((prv = *prvp++) != 0) /* go through all provides */ + { + if (ISRELDEP(prv)) + { + Reldep *rd = GETRELDEP(pool, prv); + if (rd->name == name && rd->flags == REL_EQ) + { + evr = rd->evr; + break; + } + } + } + if (!prv) + continue; /* not found in provides */ + newname = pool_tmpjoin(pool, "product:", pool_id2str(pool, prdq2.elements[i + 1]), 0); + unescape(newname); + name = pool_str2id(pool, newname, 0); + if (name) + { + /* check if we already have that product */ + for (j = 0; j < prdq.count; j++) + { + s2 = pool->solvables + prdq.elements[j]; + if (s2->name == name && s2->arch == s->arch && s2->evr == evr) + break; + } + if (j < prdq.count) + continue; /* yes, do not add again */ + } + /* new product */ + if (!name) + name = pool_str2id(pool, newname, 1); + if (!data) + { + repo_internalize(repo); /* to make that the lookups work */ + data = repo_add_repodata(repo, flags); + } + if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0) + continue; /* eek, not for installed packages, please! */ + s2 = pool_id2solvable(pool, repo_add_solvable(repo)); + s = pool->solvables + prdq2.elements[i]; /* re-calc pointer */ + s2->name = name; + s2->arch = s->arch; + s2->evr = evr; + s2->vendor = s->vendor; + /* add link requires */ + s2->requires = repo_addid_dep(repo, s2->requires, prv, 0); + if (!autoproduct_id) + autoproduct_id = pool_str2id(pool, "autoproduct()", 1); + s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autoproduct_id, s->name, REL_EQ, 1), 0); + /* add self provides */ + s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, s2->name, s2->evr, REL_EQ, 1), 0); + if ((num = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0)) != 0) + repodata_set_num(data, s2 - pool->solvables, SOLVABLE_BUILDTIME, num); + if ((str = solvable_lookup_str(s, SOLVABLE_SUMMARY)) != 0) + repodata_set_str(data, s2 - pool->solvables, SOLVABLE_SUMMARY, str); + if ((str = solvable_lookup_str(s, SOLVABLE_DESCRIPTION)) != 0) + repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DESCRIPTION, str); + if ((str = solvable_lookup_str(s, SOLVABLE_DISTRIBUTION)) != 0) + repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DISTRIBUTION, str); + /* fill in stuff from provides */ + prvp = repo->idarraydata + s->provides; + while ((prv = *prvp++) != 0) /* go through all provides */ + { + Id evr = 0; + if (ISRELDEP(prv)) + { + Reldep *rd = GETRELDEP(pool, prv); + if (rd->flags != REL_EQ) + continue; + prv = rd->name; + evr = rd->evr; + } + pn = pool_id2str(pool, prv); + if (strncmp("product-", pn, 8) != 0) + continue; + newname = 0; + if (evr) + { + newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0); + unescape(newname); + } + if (!strcmp(pn, "product-label()") && evr) + repodata_set_str(data, s2 - pool->solvables, PRODUCT_SHORTLABEL, newname); + else if (!strcmp(pn, "product-type()") && evr) + repodata_set_str(data, s2 - pool->solvables, PRODUCT_TYPE, newname); + else if (!strcmp(pn, "product-cpeid()") && evr) + repodata_set_str(data, s2 - pool->solvables, SOLVABLE_CPEID, newname); + else if (!strcmp(pn, "product-flags()") && evr) + repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_FLAGS, newname); + else if (!strncmp(pn, "product-url(", 12) && evr && pn[12] && pn[13] && strlen(pn + 12) < 32) + { + char type[34]; + strcpy(type, pn + 12); + type[strlen(type) - 1] = 0; /* closing ) */ + repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_URL_TYPE, type); + repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_URL, newname); + } + } + } + queue_free(&prdq); + queue_free(&prdq2); + if (data && !(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); else if (!data && !(flags & REPO_NO_INTERNALIZE)) |