diff options
author | Michael Schroeder <mls@suse.de> | 2012-11-02 11:41:43 +0100 |
---|---|---|
committer | Michael Schroeder <mls@suse.de> | 2012-11-02 11:41:43 +0100 |
commit | a6db1af2cdd7263bebe48d9342fdb032c413ee4f (patch) | |
tree | 15a49c74ae41538a2a9106529a5266a3d69d0d1e | |
parent | 7662309186d0c0a41118d227abd9b58ce3df855b (diff) | |
download | libsolv-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.i | 3 | ||||
-rw-r--r-- | examples/solv.c | 2 | ||||
-rw-r--r-- | src/selection.c | 125 | ||||
-rw-r--r-- | src/selection.h | 3 |
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); |