diff options
author | Michael Schroeder <mls@suse.de> | 2012-11-14 19:20:04 +0100 |
---|---|---|
committer | Michael Schroeder <mls@suse.de> | 2012-11-14 19:20:04 +0100 |
commit | d4b8348a7d0c37e866195a33f62b032582300c34 (patch) | |
tree | bd464a3903da197c6e9bd75dd282a7cfc21e779e /src/selection.c | |
parent | 0b74ce02f046f9d117333276e3d9013328912d51 (diff) | |
download | libsolv-d4b8348a7d0c37e866195a33f62b032582300c34.tar.gz libsolv-d4b8348a7d0c37e866195a33f62b032582300c34.tar.bz2 libsolv-d4b8348a7d0c37e866195a33f62b032582300c34.zip |
implement magic epoch promotion for nevra selections
Diffstat (limited to 'src/selection.c')
-rw-r--r-- | src/selection.c | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/src/selection.c b/src/selection.c index a6a857e..cdf071e 100644 --- a/src/selection.c +++ b/src/selection.c @@ -20,6 +20,7 @@ #include "selection.h" #include "solver.h" +#include "evr.h" static int @@ -535,6 +536,82 @@ selection_rel(Pool *pool, Queue *selection, const char *name, int flags) return 0; } +#if defined(MULTI_SEMANTICS) +# define EVRCMP_DEPCMP (pool->disttype == DISTTYPE_DEB ? EVRCMP_COMPARE : EVRCMP_MATCH_RELEASE) +#elif defined(DEBIAN) +# define EVRCMP_DEPCMP EVRCMP_COMPARE +#else +# define EVRCMP_DEPCMP EVRCMP_MATCH_RELEASE +#endif + +/* magic epoch promotion code, works only for SELECTION_NAME selections */ +static void +selection_limit_evr(Pool *pool, Queue *selection, char *evr) +{ + int i, j; + for (i = j = 0; i < selection->count; i += 2) + { + Id select = selection->elements[i] & SOLVER_SELECTMASK; + Id id = selection->elements[i + 1]; + Id p, pp; + Queue tmpq; + Id tmpqb[2]; + const char *highest = 0; + int highestlen = 0; + + FOR_JOB_SELECT(p, pp, select, id) + { + Solvable *s = pool->solvables + p; + const char *sevr = pool_id2str(pool, s->evr); + const char *sp; + for (sp = sevr; *sp >= '0' && *sp <= '9'; sp++) + ; + if (sp == sevr || *sp != ':') + continue; + /* found epoch, compare vr */ + if (strcmp(sp + 1, evr) != 0) + { + int r = pool_evrcmp_str(pool, sp + 1, evr, EVRCMP_DEPCMP); + if (r == -1 || r == 1) + continue; /* no match */ + } + if (highest) + { + if (highestlen == sp - sevr && !strncmp(highest, sevr, highestlen)) + continue; + if (pool_evrcmp_str(pool, sevr, highest, EVRCMP_COMPARE) <= 0) + continue; + } + highest = sevr; + highestlen = sp - sevr; + } + if (highest) + { + /* found epoch, prepend */ + char *evrx = solv_malloc(strlen(evr) + highestlen + 2); + strncpy(evrx, highest, highestlen + 1); + strcpy(evrx + highestlen + 1, evr); + id = pool_str2id(pool, evrx, 1); + solv_free(evrx); + } + else + id = pool_str2id(pool, evr, 1); + queue_init_buffer(&tmpq, tmpqb, sizeof(tmpqb)/sizeof(*tmpqb)); + queue_push2(&tmpq, selection->elements[i], selection->elements[i + 1]); + selection_limit_rel(pool, &tmpq, REL_EQ, id); + if (!tmpq.count) + { + queue_free(&tmpq); + continue; /* oops, no match */ + } + selection->elements[j] = tmpq.elements[0]; + selection->elements[j + 1] = tmpq.elements[1]; + queue_free(&tmpq); + j += 2; + } + queue_truncate(selection, j); +} + static int selection_nevra(Pool *pool, Queue *selection, const char *name, int flags) { @@ -606,7 +683,7 @@ selection_nevra(Pool *pool, Queue *selection, const char *name, int flags) } if (archid) selection_limit_rel(pool, selection, REL_ARCH, archid); - selection_limit_rel(pool, selection, REL_EQ, pool_str2id(pool, r + 1, 1)); + selection_limit_evr(pool, selection, r + 1); /* magic epoch promotion */ solv_free(rname); return ret; } |