if (!pool_match_nevr(pool, s, name))
return 0;
return pool_match_nevr(pool, s, evr);
+ case REL_WITHOUT:
+ if (!pool_match_nevr(pool, s, name))
+ return 0;
+ return !pool_match_nevr(pool, s, evr);
case REL_MULTIARCH:
if (evr != ARCH_ANY)
return 0;
{
/* we use potentially matches for complex deps */
rd1 = GETRELDEP(pool, d1);
- if (rd1->flags == REL_AND || rd1->flags == REL_OR || rd1->flags == REL_WITH || rd1->flags == REL_COND)
+ if (rd1->flags == REL_AND || rd1->flags == REL_OR || rd1->flags == REL_WITH || rd1->flags == REL_WITHOUT || rd1->flags == REL_COND || rd1->flags == REL_UNLESS)
{
if (pool_match_dep(pool, rd1->name, d2))
return 1;
- if (rd1->flags == REL_COND && ISRELDEP(rd1->evr))
+ if ((rd1->flags == REL_COND || rd1->flags == REL_UNLESS) && ISRELDEP(rd1->evr))
{
rd1 = GETRELDEP(pool, rd1->evr);
if (rd1->flags != REL_ELSE)
return 0;
}
- if (rd1->flags != REL_COND && pool_match_dep(pool, rd1->evr, d2))
+ if (rd1->flags != REL_COND && rd1->flags != REL_UNLESS && rd1->flags != REL_WITHOUT && pool_match_dep(pool, rd1->evr, d2))
return 1;
return 0;
}
{
/* we use potentially matches for complex deps */
rd2 = GETRELDEP(pool, d2);
- if (rd2->flags == REL_AND || rd2->flags == REL_OR || rd2->flags == REL_WITH || rd2->flags == REL_COND)
+ if (rd2->flags == REL_AND || rd2->flags == REL_OR || rd2->flags == REL_WITH || rd2->flags == REL_WITHOUT || rd2->flags == REL_COND || rd2->flags == REL_UNLESS)
{
if (pool_match_dep(pool, d1, rd2->name))
return 1;
- if (rd2->flags == REL_COND && ISRELDEP(rd2->evr))
+ if ((rd2->flags == REL_COND || rd2->flags == REL_UNLESS) && ISRELDEP(rd2->evr))
{
rd2 = GETRELDEP(pool, rd2->evr);
if (rd2->flags != REL_ELSE)
return 0;
}
- if (rd2->flags != REL_COND && pool_match_dep(pool, d1, rd2->evr))
+ if (rd2->flags != REL_COND && rd2->flags != REL_UNLESS && rd2->flags != REL_WITHOUT && pool_match_dep(pool, d1, rd2->evr))
return 1;
return 0;
}
if (!ISRELDEP(d1))
{
if (!ISRELDEP(d2))
- return 0;
+ return 0; /* cannot match as d1 != d2 */
rd2 = GETRELDEP(pool, d2);
return pool_match_dep(pool, d1, rd2->name);
}
wp = 0;
}
break;
-
+ case REL_WITHOUT:
+ wp = pool_whatprovides(pool, name);
+ pp2 = pool_whatprovides_ptr(pool, evr);
+ pp = pool->whatprovidesdata + wp;
+ while ((p = *pp++) != 0)
+ {
+ for (pp3 = pp2; *pp3; pp3++)
+ if (*pp3 == p)
+ break;
+ if (!*pp3)
+ queue_push(&plist, p); /* use it */
+ else
+ wp = 0;
+ }
+ break;
case REL_AND:
case REL_OR:
case REL_COND:
- if (flags == REL_COND)
+ case REL_UNLESS:
+ if (flags == REL_COND || flags == REL_UNLESS)
{
if (ISRELDEP(evr))
{
continue;
if (evr && rd->evr != evr)
continue;
- pool->whatprovides_rel[d] = 0;
+ if (pool->whatprovides_rel[d])
+ pool_set_whatprovides(pool, MAKERELDEP(d), 0);
}
}
{
va_list args;
int l;
+
+ if (!pool)
+ return ret;
va_start(args, format);
if (!pool->errstr)
{
return loc;
}
+void
+pool_set_whatprovides(Pool *pool, Id id, Id providers)
+{
+ int d, nrels = pool->nrels;
+ Reldep *rd;
+ Map m;
+
+ /* set new entry */
+ if (ISRELDEP(id))
+ {
+ d = GETRELID(id);
+ pool->whatprovides_rel[d] = providers;
+ d++;
+ }
+ else
+ {
+ pool->whatprovides[id] = providers;
+ if (id < pool->whatprovidesauxoff)
+ pool->whatprovidesaux[id] = 0; /* sorry */
+ d = 1;
+ }
+ if (!pool->whatprovides_rel)
+ return;
+ /* clear cache of all rels that use it */
+ map_init(&m, 0);
+ for (rd = pool->rels + d; d < nrels; d++, rd++)
+ {
+ if (rd->name == id || rd->evr == id ||
+ (m.size && ISRELDEP(rd->name) && MAPTST(&m, GETRELID(rd->name))) ||
+ (m.size && ISRELDEP(rd->evr) && MAPTST(&m, GETRELID(rd->evr))))
+ {
+ pool->whatprovides_rel[d] = 0; /* clear cache */
+ if (!m.size)
+ map_init(&m, nrels);
+ MAPSET(&m, d);
+ }
+ }
+ map_free(&m);
+}
+
static void
add_new_provider(Pool *pool, Id id, Id p)
{
Queue q;
Id *pp;
+ /* find whatprovides entry */
while (ISRELDEP(id))
{
Reldep *rd = GETRELDEP(pool, id);
id = rd->name;
}
+ /* add new provider to existing list keeping it sorted */
queue_init(&q);
for (pp = pool->whatprovidesdata + pool->whatprovides[id]; *pp; pp++)
{
if (*pp == p)
{
- queue_free(&q);
+ queue_free(&q); /* already have it */
return;
}
if (*pp > p)
}
if (p)
queue_push(&q, p);
- pool->whatprovides[id] = pool_queuetowhatprovides(pool, &q);
- if (id < pool->whatprovidesauxoff)
- pool->whatprovidesaux[id] = 0; /* sorry */
+ pool_set_whatprovides(pool, id, pool_queuetowhatprovides(pool, &q));
queue_free(&q);
}
continue;
s->provides = repo_addid_dep(s->repo, s->provides, id, SOLVABLE_FILEMARKER);
if (pool->whatprovides)
- add_new_provider(pool, fn, p);
- if (pool->whatprovides_rel)
- pool->whatprovides_rel[GETRELID(id)] = 0; /* clear cache */
+ add_new_provider(pool, id, p);
s = pool->solvables + q;
if (!s->repo)
continue;