summaryrefslogtreecommitdiff
path: root/ext/repo_rpmdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/repo_rpmdb.c')
-rw-r--r--ext/repo_rpmdb.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c
index d49f9d8..308cfe5 100644
--- a/ext/repo_rpmdb.c
+++ b/ext/repo_rpmdb.c
@@ -407,18 +407,27 @@ setutf8string(Repodata *repodata, Id handle, Id tag, const char *str)
repodata_set_str(repodata, handle, tag, str);
}
+static int
+ignq_sortcmp(const void *va, const void *vb, void *dp)
+{
+ int r = *(Id *)va - *(Id *)vb;
+ if (!r)
+ r = ((Id *)va)[1] - ((Id *)vb)[1];
+ return r;
+}
+
/*
* strong: 0: ignore strongness
* 1: filter to strong
* 2: filter to weak
*/
static unsigned int
-makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, int flags)
+makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf, int flags, Queue *ignq)
{
char **n, **v;
unsigned int *f;
int i, cc, nc, vc, fc;
- int haspre, premask;
+ int haspre, premask, has_ign;
unsigned int olddeps;
Id *ida;
int strong = 0;
@@ -512,6 +521,8 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf,
cc += haspre; /* add slot for the prereq marker */
olddeps = repo_reserve_ids(repo, 0, cc);
ida = repo->idarraydata + olddeps;
+
+ has_ign = 0;
for (i = 0; ; i++)
{
Id id;
@@ -564,12 +575,33 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf,
id = pool_rel2id(pool, id, evr, fl, 1);
}
*ida++ = id;
+ if (haspre == 2 && ignq)
+ {
+ int is_ign = (f[i] & DEP_PRE_IN) != 0 && (f[i] & DEP_PRE_UN) == 0 ? 1 : 0;
+ has_ign |= is_ign;
+ queue_push2(ignq, id, is_ign);
+ }
}
*ida++ = 0;
repo->idarraysize += cc + 1;
solv_free(n);
solv_free(v);
solv_free(f);
+ if (has_ign && ignq->count > 2)
+ {
+ Id id, lastid = 0;
+ int j;
+
+ solv_sort(ignq->elements, ignq->count / 2, sizeof(Id) * 2, ignq_sortcmp, 0);
+ for (i = j = 0; i < ignq->count; i += 2)
+ {
+ id = ignq->elements[i];
+ if (id != lastid && ignq->elements[i + 1] > 0)
+ ignq->elements[j++] = id;
+ lastid = id;
+ }
+ queue_truncate(ignq, j);
+ }
return olddeps;
}
@@ -909,6 +941,8 @@ rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead,
char *name;
char *evr;
char *sourcerpm;
+ Queue ignq;
+ Id ignqbuf[64];
name = headstring(rpmhead, TAG_NAME);
if (!name)
@@ -935,21 +969,27 @@ rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead,
s->evr = pool_str2id(pool, evr, 1);
s->vendor = pool_str2id(pool, headstring(rpmhead, TAG_VENDOR), 1);
- s->provides = makedeps(pool, repo, rpmhead, TAG_PROVIDENAME, TAG_PROVIDEVERSION, TAG_PROVIDEFLAGS, 0);
+ queue_init_buffer(&ignq, ignqbuf, sizeof(ignqbuf)/sizeof(*ignqbuf));
+
+ s->provides = makedeps(pool, repo, rpmhead, TAG_PROVIDENAME, TAG_PROVIDEVERSION, TAG_PROVIDEFLAGS, 0, 0);
if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
- s->requires = makedeps(pool, repo, rpmhead, TAG_REQUIRENAME, TAG_REQUIREVERSION, TAG_REQUIREFLAGS, flags);
- s->conflicts = makedeps(pool, repo, rpmhead, TAG_CONFLICTNAME, TAG_CONFLICTVERSION, TAG_CONFLICTFLAGS, 0);
- s->obsoletes = makedeps(pool, repo, rpmhead, TAG_OBSOLETENAME, TAG_OBSOLETEVERSION, TAG_OBSOLETEFLAGS, 0);
+ s->requires = makedeps(pool, repo, rpmhead, TAG_REQUIRENAME, TAG_REQUIREVERSION, TAG_REQUIREFLAGS, flags, &ignq);
+ s->conflicts = makedeps(pool, repo, rpmhead, TAG_CONFLICTNAME, TAG_CONFLICTVERSION, TAG_CONFLICTFLAGS, 0, 0);
+ s->obsoletes = makedeps(pool, repo, rpmhead, TAG_OBSOLETENAME, TAG_OBSOLETEVERSION, TAG_OBSOLETEFLAGS, 0, 0);
- s->recommends = makedeps(pool, repo, rpmhead, TAG_RECOMMENDNAME, TAG_RECOMMENDVERSION, TAG_RECOMMENDFLAGS, 0);
- s->suggests = makedeps(pool, repo, rpmhead, TAG_SUGGESTNAME, TAG_SUGGESTVERSION, TAG_SUGGESTFLAGS, 0);
- s->supplements = makedeps(pool, repo, rpmhead, TAG_SUPPLEMENTNAME, TAG_SUPPLEMENTVERSION, TAG_SUPPLEMENTFLAGS, 0);
- s->enhances = makedeps(pool, repo, rpmhead, TAG_ENHANCENAME, TAG_ENHANCEVERSION, TAG_ENHANCEFLAGS, 0);
+ s->recommends = makedeps(pool, repo, rpmhead, TAG_RECOMMENDNAME, TAG_RECOMMENDVERSION, TAG_RECOMMENDFLAGS, 0, 0);
+ s->suggests = makedeps(pool, repo, rpmhead, TAG_SUGGESTNAME, TAG_SUGGESTVERSION, TAG_SUGGESTFLAGS, 0, 0);
+ s->supplements = makedeps(pool, repo, rpmhead, TAG_SUPPLEMENTNAME, TAG_SUPPLEMENTVERSION, TAG_SUPPLEMENTFLAGS, 0, 0);
+ s->enhances = makedeps(pool, repo, rpmhead, TAG_ENHANCENAME, TAG_ENHANCEVERSION, TAG_ENHANCEFLAGS, 0, 0);
s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
s->conflicts = repo_fix_conflicts(repo, s->conflicts);
+ if (data && ignq.count)
+ repodata_set_idarray(data, s - pool->solvables, SOLVABLE_PREREQ_IGNOREINST, &ignq);
+ queue_free(&ignq);
+
if (data)
{
Id handle;
@@ -1014,24 +1054,11 @@ rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead,
repodata_set_sourcepkg(data, handle, sourcerpm);
if ((flags & RPM_ADD_TRIGGERS) != 0)
{
- Id id, lastid;
- unsigned int ida = makedeps(pool, repo, rpmhead, TAG_TRIGGERNAME, TAG_TRIGGERVERSION, TAG_TRIGGERFLAGS, 0);
-
- lastid = 0;
- for (; (id = repo->idarraydata[ida]) != 0; ida++)
- {
- /* we currently do not support rel ids in incore data, so
- * strip off versioning information */
- while (ISRELDEP(id))
- {
- Reldep *rd = GETRELDEP(pool, id);
- id = rd->name;
- }
- if (id == lastid)
- continue;
+ unsigned int ida = makedeps(pool, repo, rpmhead, TAG_TRIGGERNAME, TAG_TRIGGERVERSION, TAG_TRIGGERFLAGS, 0, 0);
+ Id id, lastid = 0;
+ for (lastid = 0; (id = repo->idarraydata[ida]) != 0; ida++, lastid = id)
+ if (id != lastid)
repodata_add_idarray(data, handle, SOLVABLE_TRIGGERS, id);
- lastid = id;
- }
}
if ((flags & RPM_ADD_NO_FILELIST) == 0)
addfilelist(data, handle, rpmhead, flags);