summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2012-11-02 11:41:43 +0100
committerMichael Schroeder <mls@suse.de>2012-11-02 11:41:43 +0100
commita6db1af2cdd7263bebe48d9342fdb032c413ee4f (patch)
tree15a49c74ae41538a2a9106529a5266a3d69d0d1e
parent7662309186d0c0a41118d227abd9b58ce3df855b (diff)
downloadlibsolv-a6db1af2cdd7263bebe48d9342fdb032c413ee4f.tar.gz
libsolv-a6db1af2cdd7263bebe48d9342fdb032c413ee4f.tar.bz2
libsolv-a6db1af2cdd7263bebe48d9342fdb032c413ee4f.zip
add SELECTION_WITH_SOURCE, rename SELECTION_SOURCE to SELECTION_SOURCE_ONLY
-rw-r--r--bindings/solv.i3
-rw-r--r--examples/solv.c2
-rw-r--r--src/selection.c125
-rw-r--r--src/selection.h3
4 files changed, 117 insertions, 16 deletions
diff --git a/bindings/solv.i b/bindings/solv.i
index f0969f4..0046253 100644
--- a/bindings/solv.i
+++ b/bindings/solv.i
@@ -720,7 +720,8 @@ typedef struct {
static const Id SELECTION_NOCASE = SELECTION_NOCASE;
static const Id SELECTION_INSTALLED_ONLY = SELECTION_INSTALLED_ONLY;
static const Id SELECTION_FLAT = SELECTION_FLAT;
- static const Id SELECTION_SOURCE = SELECTION_SOURCE;
+ static const Id SELECTION_SOURCE_ONLY = SELECTION_SOURCE_ONLY;
+ static const Id SELECTION_WITH_SOURCE = SELECTION_WITH_SOURCE;
Selection(Pool *pool) {
Selection *s;
diff --git a/examples/solv.c b/examples/solv.c
index 1128c2d..f728432 100644
--- a/examples/solv.c
+++ b/examples/solv.c
@@ -2671,6 +2671,8 @@ main(int argc, char **argv)
}
queue_init(&job2);
flags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_GLOB;
+ if (mode == MODE_LIST)
+ flags |= SELECTION_WITH_SOURCE;
if (argv[i][0] == '/')
flags |= SELECTION_FILELIST | (mode == MODE_ERASE ? SELECTION_INSTALLED_ONLY : 0);
rflags = selection_make(pool, &job2, argv[i], flags);
diff --git a/src/selection.c b/src/selection.c
index 0128f80..a6a857e 100644
--- a/src/selection.c
+++ b/src/selection.c
@@ -153,11 +153,49 @@ selection_flatten(Pool *pool, Queue *selection)
static void
selection_limit_rel(Pool *pool, Queue *selection, Id relflags, Id relevr)
{
- int i, j;
- for (i = j = 0; i < selection->count; i += 2)
+ int i;
+ for (i = 0; i < selection->count; i += 2)
{
Id select = selection->elements[i] & SOLVER_SELECTMASK;
Id id = selection->elements[i + 1];
+ if (select == SOLVER_SOLVABLE || select == SOLVER_SOLVABLE_ONE_OF)
+ {
+ /* done by selection_addsrc */
+ Queue q;
+ Id p, pp;
+ Id rel = 0, relname = 0;
+ int miss = 0;
+
+ queue_init(&q);
+ FOR_JOB_SELECT(p, pp, select, id)
+ {
+ Solvable *s = pool->solvables + p;
+ if (!rel || s->name != relname)
+ {
+ relname = s->name;
+ rel = pool_rel2id(pool, relname, relevr, relflags, 1);
+ }
+ if (pool_match_nevr(pool, s, rel))
+ queue_push(&q, p);
+ else
+ miss = 1;
+ }
+ if (miss)
+ {
+ if (q.count == 1)
+ {
+ selection->elements[i] = SOLVER_SOLVABLE | SOLVER_NOAUTOSET;
+ selection->elements[i + 1] = q.elements[0];
+ }
+ else
+ {
+ selection->elements[i] = SOLVER_SOLVABLE_ONE_OF;
+ selection->elements[i + 1] = pool_queuetowhatprovides(pool, &q);
+ }
+ }
+ queue_free(&q);
+ continue;
+ }
if (select != SOLVER_SOLVABLE_NAME && select != SOLVER_SOLVABLE_PROVIDES)
continue; /* actually internal error */
if (relflags == REL_ARCH && (relevr == ARCH_SRC || relevr == ARCH_NOSRC) && ISRELDEP(id))
@@ -180,6 +218,50 @@ selection_limit_rel(Pool *pool, Queue *selection, Id relflags, Id relevr)
selection_prune(pool, selection);
}
+static void
+selection_addsrc(Pool *pool, Queue *selection, int flags)
+{
+ Queue q;
+ Id p, name;
+ int i, havesrc;
+
+ if ((flags & SELECTION_INSTALLED_ONLY) != 0)
+ return; /* sources can't be installed */
+ queue_init(&q);
+ for (i = 0; i < selection->count; i += 2)
+ {
+ if (selection->elements[i] != SOLVER_SOLVABLE_NAME)
+ continue;
+ name = selection->elements[i + 1];
+ havesrc = 0;
+ queue_empty(&q);
+ FOR_POOL_SOLVABLES(p)
+ {
+ Solvable *s = pool->solvables + p;
+ if (s->name != name)
+ continue;
+ if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
+ havesrc = 1;
+ else if (!pool_installable(pool, s))
+ continue;
+ queue_push(&q, p);
+ }
+ if (!havesrc || !q.count)
+ continue;
+ if (q.count == 1)
+ {
+ selection->elements[i] = SOLVER_SOLVABLE | SOLVER_NOAUTOSET;
+ selection->elements[i + 1] = q.elements[0];
+ }
+ else
+ {
+ selection->elements[i] = SOLVER_SOLVABLE_ONE_OF;
+ selection->elements[i + 1] = pool_queuetowhatprovides(pool, &q);
+ }
+ }
+ queue_free(&q);
+}
+
static int
selection_depglob(Pool *pool, Queue *selection, const char *name, int flags)
{
@@ -188,8 +270,11 @@ selection_depglob(Pool *pool, Queue *selection, const char *name, int flags)
int doglob = 0;
int globflags = 0;
- if ((flags & SELECTION_SOURCE) != 0)
- flags &= ~SELECTION_PROVIDES; /* sources don't provide anything */
+ if ((flags & SELECTION_SOURCE_ONLY) != 0)
+ {
+ flags &= ~SELECTION_PROVIDES; /* sources don't provide anything */
+ flags &= ~SELECTION_WITH_SOURCE;
+ }
if (!(flags & (SELECTION_NAME|SELECTION_PROVIDES)))
return 0;
@@ -202,7 +287,7 @@ selection_depglob(Pool *pool, Queue *selection, const char *name, int flags)
id = pool_str2id(pool, name, 0);
if (id)
{
- if ((flags & SELECTION_SOURCE) != 0 && (flags & SELECTION_NAME) != 0)
+ if ((flags & (SELECTION_SOURCE_ONLY | SELECTION_WITH_SOURCE)) != 0 && (flags & SELECTION_NAME) != 0)
{
/* src rpms don't have provides, so we must check every solvable */
FOR_PROVIDES(p, pp, id) /* try fast path first */
@@ -212,8 +297,11 @@ selection_depglob(Pool *pool, Queue *selection, const char *name, int flags)
{
if ((flags & SELECTION_INSTALLED_ONLY) != 0 && s->repo != pool->installed)
continue;
- id = pool_rel2id(pool, id, ARCH_SRC, REL_ARCH, 1);
+ if ((flags & SELECTION_SOURCE_ONLY) != 0)
+ id = pool_rel2id(pool, id, ARCH_SRC, REL_ARCH, 1);
queue_push2(selection, SOLVER_SOLVABLE_NAME, id);
+ if ((flags & SELECTION_WITH_SOURCE) != 0)
+ selection_addsrc(pool, selection, flags);
return SELECTION_NAME;
}
}
@@ -224,8 +312,11 @@ selection_depglob(Pool *pool, Queue *selection, const char *name, int flags)
{
if ((flags & SELECTION_INSTALLED_ONLY) != 0 && s->repo != pool->installed)
continue; /* just in case... src rpms can't be installed */
- id = pool_rel2id(pool, id, ARCH_SRC, REL_ARCH, 1);
+ if ((flags & SELECTION_SOURCE_ONLY) != 0)
+ id = pool_rel2id(pool, id, ARCH_SRC, REL_ARCH, 1);
queue_push2(selection, SOLVER_SOLVABLE_NAME, id);
+ if ((flags & SELECTION_WITH_SOURCE) != 0)
+ selection_addsrc(pool, selection, flags);
return SELECTION_NAME;
}
}
@@ -238,9 +329,11 @@ selection_depglob(Pool *pool, Queue *selection, const char *name, int flags)
match = 1;
if (s->name == id && (flags & SELECTION_NAME) != 0)
{
- if ((flags & SELECTION_SOURCE) != 0)
+ if ((flags & SELECTION_SOURCE_ONLY) != 0)
id = pool_rel2id(pool, id, ARCH_SRC, REL_ARCH, 1);
queue_push2(selection, SOLVER_SOLVABLE_NAME, id);
+ if ((flags & SELECTION_WITH_SOURCE) != 0)
+ selection_addsrc(pool, selection, flags);
return SELECTION_NAME;
}
}
@@ -280,14 +373,14 @@ selection_depglob(Pool *pool, Queue *selection, const char *name, int flags)
{
Solvable *s = pool->solvables + p;
if (!pool_installable(pool, s))
- if (!(flags & SELECTION_SOURCE) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC))
+ if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC))
continue;
if ((flags & SELECTION_INSTALLED_ONLY) != 0 && s->repo != pool->installed)
continue;
id = s->name;
if ((doglob ? fnmatch(name, pool_id2str(pool, id), globflags) : strcasecmp(name, pool_id2str(pool, id))) == 0)
{
- if ((flags & SELECTION_SOURCE) != 0)
+ if ((flags & SELECTION_SOURCE_ONLY) != 0)
id = pool_rel2id(pool, id, ARCH_SRC, REL_ARCH, 1);
/* queue_pushunique2 */
for (i = 0; i < selection->count; i += 2)
@@ -299,7 +392,11 @@ selection_depglob(Pool *pool, Queue *selection, const char *name, int flags)
}
}
if (match)
- return SELECTION_NAME;
+ {
+ if ((flags & SELECTION_WITH_SOURCE) != 0)
+ selection_addsrc(pool, selection, flags);
+ return SELECTION_NAME;
+ }
}
if ((flags & SELECTION_PROVIDES))
{
@@ -343,7 +440,7 @@ selection_depglob_arch(Pool *pool, Queue *selection, const char *name, int flags
char *rname = solv_strdup(name);
rname[r - name] = 0;
if (archid == ARCH_SRC || archid == ARCH_NOSRC)
- flags |= SELECTION_SOURCE;
+ flags |= SELECTION_SOURCE_ONLY;
if ((ret = selection_depglob(pool, selection, rname, flags)) != 0)
{
selection_limit_rel(pool, selection, REL_ARCH, archid);
@@ -373,7 +470,7 @@ selection_filelist(Pool *pool, Queue *selection, const char *name, int flags)
if (!s->repo)
continue;
if (!pool_installable(pool, s))
- if (!(flags & SELECTION_SOURCE) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC))
+ if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC))
continue;
if ((flags & SELECTION_INSTALLED_ONLY) != 0 && s->repo != pool->installed)
continue;
@@ -487,7 +584,7 @@ selection_nevra(Pool *pool, Queue *selection, const char *name, int flags)
if ((r2 = strrchr(r + 1, '.')) != 0 && r2[1] && (archid = str2archid(pool, r2 + 1)) != 0)
*r2 = 0; /* found valid arch, split it off */
if (archid == ARCH_SRC || archid == ARCH_NOSRC)
- flags |= SELECTION_SOURCE;
+ flags |= SELECTION_SOURCE_ONLY;
/* try with just the version */
if ((ret = selection_depglob(pool, selection, rname, flags)) == 0)
diff --git a/src/selection.h b/src/selection.h
index 2a3662f..9b7d454 100644
--- a/src/selection.h
+++ b/src/selection.h
@@ -23,7 +23,8 @@
#define SELECTION_GLOB (1 << 9)
#define SELECTION_FLAT (1 << 10)
#define SELECTION_NOCASE (1 << 11)
-#define SELECTION_SOURCE (1 << 12)
+#define SELECTION_SOURCE_ONLY (1 << 12)
+#define SELECTION_WITH_SOURCE (1 << 13)
extern int selection_make(Pool *pool, Queue *selection, const char *name, int flags);
extern void selection_limit(Pool *pool, Queue *sel1, Queue *sel2);