repodata_set_str(repodata, handle, tag, str);
}
+static int
+add_prereq_ignoreinst_sortcmp(const void *va, const void *vb, void *dp)
+{
+ return *(Id *)va - *(Id *)vb;
+}
+
+static void
+add_prereq_ignoreinst(Pool *pool, Repodata *data, Id handle, Queue *ign, Queue *keep)
+{
+ int ii, ik;
+
+ /* sort both queues */
+ if (ign->count > 1)
+ solv_sort(ign->elements, ign->count, sizeof(Id), add_prereq_ignoreinst_sortcmp, 0);
+ if (keep->count > 1)
+ solv_sort(keep->elements, keep->count, sizeof(Id), add_prereq_ignoreinst_sortcmp, 0);
+ for (ii = ik = 0; ii < ign->count; )
+ {
+ if (ik == keep->count || ign->elements[ii] < keep->elements[ik])
+ {
+ Id id = ign->elements[ii++];
+ repodata_add_idarray(data, handle, SOLVABLE_PREREQ_IGNOREINST, id);
+ while (ii < ign->count && ign->elements[ii] == id)
+ ii++;
+ }
+ else if (ign->elements[ii] > keep->elements[ik])
+ ik++;
+ else
+ ii++;
+ }
+}
/*
* 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, Queue *keepq)
{
char **n, **v;
unsigned int *f;
cc += haspre; /* add slot for the prereq marker */
olddeps = repo_reserve_ids(repo, 0, cc);
ida = repo->idarraydata + olddeps;
+
for (i = 0; ; i++)
{
Id id;
id = pool_rel2id(pool, id, evr, fl, 1);
}
*ida++ = id;
+ if (haspre == 2 && ignq)
+ {
+ if ((f[i] & DEP_PRE_IN) != 0 && (f[i] & DEP_PRE_UN) == 0)
+ queue_push(ignq, id);
+ else
+ queue_push(keepq, id);
+ }
}
*ida++ = 0;
repo->idarraysize += cc + 1;
char *name;
char *evr;
char *sourcerpm;
+ Queue ignq;
+ Queue keepq;
+ Id ignqbuf[16];
+ Id keepqbuf[16];
name = headstring(rpmhead, TAG_NAME);
if (!name)
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));
+ queue_init_buffer(&keepq, keepqbuf, sizeof(keepqbuf)/sizeof(*keepqbuf));
+
+ s->provides = makedeps(pool, repo, rpmhead, TAG_PROVIDENAME, TAG_PROVIDEVERSION, TAG_PROVIDEFLAGS, 0, 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, &keepq);
+ s->conflicts = makedeps(pool, repo, rpmhead, TAG_CONFLICTNAME, TAG_CONFLICTVERSION, TAG_CONFLICTFLAGS, 0, 0, 0);
+ s->obsoletes = makedeps(pool, repo, rpmhead, TAG_OBSOLETENAME, TAG_OBSOLETEVERSION, TAG_OBSOLETEFLAGS, 0, 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, 0);
+ s->suggests = makedeps(pool, repo, rpmhead, TAG_SUGGESTNAME, TAG_SUGGESTVERSION, TAG_SUGGESTFLAGS, 0, 0, 0);
+ s->supplements = makedeps(pool, repo, rpmhead, TAG_SUPPLEMENTNAME, TAG_SUPPLEMENTVERSION, TAG_SUPPLEMENTFLAGS, 0, 0, 0);
+ s->enhances = makedeps(pool, repo, rpmhead, TAG_ENHANCENAME, TAG_ENHANCEVERSION, TAG_ENHANCEFLAGS, 0, 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)
+ add_prereq_ignoreinst(pool, data, s - pool->solvables, &ignq, &keepq);
+
+ queue_free(&ignq);
+ queue_free(&keepq);
+
if (data)
{
Id handle;
repodata_set_sourcepkg(data, handle, sourcerpm);
if ((flags & RPM_ADD_TRIGGERS) != 0)
{
- unsigned int ida = makedeps(pool, repo, rpmhead, TAG_TRIGGERNAME, TAG_TRIGGERVERSION, TAG_TRIGGERFLAGS, 0);
+ unsigned int ida = makedeps(pool, repo, rpmhead, TAG_TRIGGERNAME, TAG_TRIGGERVERSION, TAG_TRIGGERFLAGS, 0, 0, 0);
Id id, lastid = 0;
for (lastid = 0; (id = repo->idarraydata[ida]) != 0; ida++, lastid = id)
if (id != lastid)
/*-------------------------------------------------------------------
*
- * add (install) rules for solvable
+ * add dependency rules for solvable
*
* s: Solvable for which to add rules
* m: m[s] = 1 for solvables which have rules, prevent rule duplication
Queue workq; /* list of solvables we still have to work on */
Id workqbuf[64];
+ Queue prereqq; /* list of pre-req ids to ignore */
+ Id prereqbuf[16];
int i;
int dontfix; /* ignore dependency errors for installed solvables */
queue_init_buffer(&workq, workqbuf, sizeof(workqbuf)/sizeof(*workqbuf));
queue_push(&workq, s - pool->solvables); /* push solvable Id to work queue */
+ queue_init_buffer(&prereqq, prereqbuf, sizeof(prereqbuf)/sizeof(*prereqbuf));
+
/* loop until there's no more work left */
while (workq.count)
{
if (s->requires)
{
+ int filterpre = 0;
reqp = s->repo->idarraydata + s->requires;
while ((req = *reqp++) != 0) /* go through all requires */
{
if (req == SOLVABLE_PREREQMARKER) /* skip the marker */
- continue;
+ {
+ if (installed && s->repo == installed)
+ {
+ if (prereqq.count)
+ queue_empty(&prereqq);
+ solvable_lookup_idarray(s, SOLVABLE_PREREQ_IGNOREINST, &prereqq);
+ filterpre = prereqq.count;
+ }
+ continue;
+ }
+ if (filterpre)
+ {
+ /* check if this id is filtered. assumes that prereqq.count is small */
+ for (i = 0; i < prereqq.count; i++)
+ if (req == prereqq.elements[i])
+ break;
+ if (i < prereqq.count)
+ {
+ POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, "package %s: ignoring filtered pre-req dependency %s\n", pool_solvable2str(pool, s), pool_dep2str(pool, req));
+ continue;
+ }
+ }
#ifdef ENABLE_COMPLEX_DEPS
if (pool_is_complex_dep(pool, req))
}
}
}
+ queue_free(&prereqq);
queue_free(&workq);
}