From 524f855df0f94933f1078098800c0a93a7f8e86e Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Thu, 11 Apr 2013 09:58:42 -0700 Subject: merged 0.3.0 --- VERSION.cmake | 4 +- bindings/solv.i | 1 + examples/p5solv | 8 +- examples/pysolv | 12 +-- examples/rbsolv | 8 +- examples/solv.c | 16 ++-- ext/repo_arch.c | 7 +- ext/repo_helix.c | 2 +- ext/repo_rpmdb.c | 75 ++++++++++++++++-- ext/repo_rpmdb.h | 1 + ext/repo_rpmmd.c | 23 ++++-- ext/testcase.c | 206 ++++++++++++++++++++++++++++++++++++------------ package/libsolv.changes | 9 +++ src/dataiterator.h | 11 +++ src/knownid.h | 24 +++--- src/libsolv.ver | 2 + src/policy.c | 24 ++---- src/pool.c | 47 ++++++++++- src/pool.h | 6 +- src/repo.h | 13 +++ src/repo_write.c | 2 + src/repodata.c | 126 +++++++++++++++++++++++++++-- src/repodata.h | 1 + src/repopack.h | 4 + src/rules.c | 95 ++++++++++++++++------ src/rules.h | 1 + src/selection.c | 32 ++++++-- src/solvable.c | 47 ++++++----- src/solver.c | 171 ++++++++++++++++++++++++++++++++++++++-- src/solver.h | 52 +----------- tools/common_write.c | 2 + tools/installcheck.c | 6 +- 32 files changed, 796 insertions(+), 242 deletions(-) diff --git a/VERSION.cmake b/VERSION.cmake index 073a056..eb05739 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -48,6 +48,6 @@ SET(LIBSOLV_SOVERSION "0") SET(LIBSOLVEXT_SOVERSION "0") SET(LIBSOLV_MAJOR "0") -SET(LIBSOLV_MINOR "2") -SET(LIBSOLV_PATCH "4") +SET(LIBSOLV_MINOR "3") +SET(LIBSOLV_PATCH "0") diff --git a/bindings/solv.i b/bindings/solv.i index 16564ff..cbb8a20 100644 --- a/bindings/solv.i +++ b/bindings/solv.i @@ -1649,6 +1649,7 @@ rb_eval_string( } ndi = solv_calloc(1, sizeof(*ndi)); dataiterator_init_clone(ndi, $self); + dataiterator_strdup(ndi); return ndi; } #ifdef SWIGRUBY diff --git a/examples/p5solv b/examples/p5solv index e02d6da..324d30d 100755 --- a/examples/p5solv +++ b/examples/p5solv @@ -617,11 +617,11 @@ for my $job (@jobs) { $job->{'how'} ^= $solv::Job::SOLVER_UPDATE ^ $solv::Job::SOLVER_INSTALL if $cmd eq 'up' && $job->isemptyupdate(); } -my $solver; +my $solver = $pool->Solver(); +$solver->set_flag($solv::Solver::SOLVER_FLAG_SPLITPROVIDES, 1); +$solver->set_flag($solv::Solver::SOLVER_FLAG_ALLOW_UNINSTALL, 1) if $cmd eq 'erase'; + while (1) { - $solver = $pool->Solver(); - $solver->set_flag($solv::Solver::SOLVER_FLAG_SPLITPROVIDES, 1); - $solver->set_flag($solv::Solver::SOLVER_FLAG_ALLOW_UNINSTALL, 1) if $cmd eq 'erase'; my @problems = $solver->solve(\@jobs); last unless @problems; for my $problem (@problems) { diff --git a/examples/pysolv b/examples/pysolv index d7fc9bd..18327d7 100755 --- a/examples/pysolv +++ b/examples/pysolv @@ -689,7 +689,7 @@ for arg in args: jobs.append(pool.Job(Job.SOLVER_SOLVABLE, cmdlinerepo['packages'][arg])) else: flags = Selection.SELECTION_NAME|Selection.SELECTION_PROVIDES|Selection.SELECTION_GLOB - flags |= Selection.SELECTION_CANON|Selection.SELECTION_DOTARCH|Selection.SELECTION_REL + flags |= Selection.SELECTION_CANON|Selection.SELECTION_DOTARCH|Selection.SELECTION_REL if len(arg) and arg[0] == '/': flags |= Selection.SELECTION_FILELIST if cmd == 'erase': @@ -752,12 +752,12 @@ for job in jobs: job.how |= Job.SOLVER_CLEANDEPS #pool.set_debuglevel(2) -solver = None +solver = pool.Solver() +solver.set_flag(Solver.SOLVER_FLAG_SPLITPROVIDES, 1); +if cmd == 'erase': + solver.set_flag(Solver.SOLVER_FLAG_ALLOW_UNINSTALL, 1); + while True: - solver = pool.Solver() - solver.set_flag(Solver.SOLVER_FLAG_SPLITPROVIDES, 1); - if cmd == 'erase': - solver.set_flag(Solver.SOLVER_FLAG_ALLOW_UNINSTALL, 1); problems = solver.solve(jobs) if not problems: break diff --git a/examples/rbsolv b/examples/rbsolv index b91bbae..3c87d3d 100755 --- a/examples/rbsolv +++ b/examples/rbsolv @@ -629,12 +629,12 @@ for job in jobs job.how ^= Solv::Job::SOLVER_UPDATE ^ Solv::Job::SOLVER_INSTALL if cmd == 'up' and job.isemptyupdate? end -solver = nil +solver = pool.Solver +solver.set_flag(Solv::Solver::SOLVER_FLAG_SPLITPROVIDES, 1) +solver.set_flag(Solv::Solver::SOLVER_FLAG_ALLOW_UNINSTALL, 1) if cmd == 'erase' #pool.set_debuglevel(1) + while true - solver = pool.Solver - solver.set_flag(Solv::Solver::SOLVER_FLAG_SPLITPROVIDES, 1) - solver.set_flag(Solv::Solver::SOLVER_FLAG_ALLOW_UNINSTALL, 1) if cmd == 'erase' problems = solver.solve(jobs) break if problems.empty? for problem in problems diff --git a/examples/solv.c b/examples/solv.c index 0ef5daa..4daa572 100644 --- a/examples/solv.c +++ b/examples/solv.c @@ -2833,17 +2833,17 @@ main(int argc, char **argv) #if defined(ENABLE_RPMDB) && (defined(SUSE) || defined(FEDORA)) rerunsolver: #endif + solv = solver_create(pool); + solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1); + if (mainmode == MODE_ERASE) + solver_set_flag(solv, SOLVER_FLAG_ALLOW_UNINSTALL, 1); /* don't nag */ + solver_set_flag(solv, SOLVER_FLAG_BEST_OBEY_POLICY, 1); + for (;;) { Id problem, solution; int pcnt, scnt; - solv = solver_create(pool); - solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1); - if (mainmode == MODE_ERASE) - solver_set_flag(solv, SOLVER_FLAG_ALLOW_UNINSTALL, 1); /* don't nag */ - solver_set_flag(solv, SOLVER_FLAG_BEST_OBEY_POLICY, 1); - if (!solver_solve(solv, &job)) break; pcnt = solver_problem_count(solv); @@ -2894,8 +2894,6 @@ rerunsolver: continue; solver_take_solution(solv, problem, take, &job); } - solver_free(solv); - solv = 0; } trans = solver_create_transaction(solv); @@ -3149,8 +3147,8 @@ rerunsolver: fclose(newpkgsfps[i]); newpkgsfps = solv_free(newpkgsfps); solver_free(solv); + solv = 0; pool_add_fileconflicts_deps(pool, &conflicts); - pool_createwhatprovides(pool); /* Hmm... */ goto rerunsolver; } } diff --git a/ext/repo_arch.c b/ext/repo_arch.c index ebf42d3..835899e 100644 --- a/ext/repo_arch.c +++ b/ext/repo_arch.c @@ -196,14 +196,14 @@ static int gettarhead(struct tarhead *th) char *data, *pp; if (length < 1 || length >= 1024 * 1024) return -1; - l = length; - data = pp = solv_malloc(l + 512); - for (; l > 0; l -= 512, pp += 512) + data = pp = solv_malloc(length + 512); + for (l = length; l > 0; l -= 512, pp += 512) if (readblock(th->fp, (unsigned char *)pp)) { solv_free(data); return -1; } + data[length] = 0; type = 3; /* extension */ if (th->blk[156] == 'L') { @@ -216,7 +216,6 @@ static int gettarhead(struct tarhead *th) while (length > 0) { int ll = 0; - int l; for (l = 0; l < length && pp[l] >= '0' && pp[l] <= '9'; l++) ll = ll * 10 + (pp[l] - '0'); if (l == length || pp[l] != ' ' || ll < 1 || ll > length || pp[ll - 1] != '\n') diff --git a/ext/repo_helix.c b/ext/repo_helix.c index 7415b29..0da7c2a 100644 --- a/ext/repo_helix.c +++ b/ext/repo_helix.c @@ -629,7 +629,7 @@ endElement(void *userData, const char *name) s->evr = evr2id(pool, pd, pd->epoch ? pd->evrspace + pd->epoch : 0, pd->version ? pd->evrspace + pd->version : 0, - pd->release ? pd->evrspace + pd->release : 0); + pd->release ? pd->evrspace + pd->release : ""); /* ensure self-provides */ if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c index 7ea6913..8efaa16 100644 --- a/ext/repo_rpmdb.c +++ b/ext/repo_rpmdb.c @@ -86,6 +86,9 @@ #define TAG_TRIGGERNAME 1066 #define TAG_TRIGGERVERSION 1067 #define TAG_TRIGGERFLAGS 1068 +#define TAG_CHANGELOGTIME 1080 +#define TAG_CHANGELOGNAME 1081 +#define TAG_CHANGELOGTEXT 1082 #define TAG_OBSOLETENAME 1090 #define TAG_FILEDEVICES 1095 #define TAG_FILEINODES 1096 @@ -834,6 +837,46 @@ addfileprovides(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rp return olddeps; } +static void +addchangelog(Repodata *data, Id handle, RpmHead *rpmhead) +{ + char **cn; + char **cx; + unsigned int *ct; + int i, cnc, cxc, ctc; + Queue hq; + + ct = headint32array(rpmhead, TAG_CHANGELOGTIME, &ctc); + cx = headstringarray(rpmhead, TAG_CHANGELOGTEXT, &cxc); + cn = headstringarray(rpmhead, TAG_CHANGELOGNAME, &cnc); + if (!ct || !cx || !cn || !ctc || ctc != cxc || ctc != cnc) + { + solv_free(ct); + solv_free(cx); + solv_free(cn); + return; + } + queue_init(&hq); + for (i = 0; i < ctc; i++) + { + Id h = repodata_new_handle(data); + if (ct[i]) + repodata_set_num(data, h, SOLVABLE_CHANGELOG_TIME, ct[i]); + if (cn[i]) + repodata_set_str(data, h, SOLVABLE_CHANGELOG_AUTHOR, cn[i]); + if (cx[i]) + repodata_set_str(data, h, SOLVABLE_CHANGELOG_TEXT, cx[i]); + queue_push(&hq, h); + } + for (i = 0; i < hq.count; i++) + repodata_add_flexarray(data, handle, SOLVABLE_CHANGELOG, hq.elements[i]); + queue_free(&hq); + solv_free(ct); + solv_free(cx); + solv_free(cn); +} + + static int rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead, int flags) { @@ -1005,6 +1048,8 @@ rpm2solv(Pool *pool, Repo *repo, Repodata *data, Solvable *s, RpmHead *rpmhead, lastid = id; } } + if ((flags & RPM_ADD_WITH_CHANGELOG) != 0) + addchangelog(data, handle, rpmhead); } solv_free(evr); return 1; @@ -1095,6 +1140,7 @@ copydir_complex(Pool *pool, Repodata *data, Stringpool *fromspool, Repodata *fro struct solvable_copy_cbdata { Repodata *data; Id handle; + Id subhandle; Id *dircache; }; @@ -1156,6 +1202,22 @@ solvable_copy_cb(void *vcbdata, Solvable *r, Repodata *fromdata, Repokey *key, K id = copydir(pool, data, fromspool, fromdata, id, cbdata->dircache); repodata_add_dirstr(data, handle, keyname, id, kv->str); break; + case REPOKEY_TYPE_FLEXARRAY: + if (kv->eof == 2) + { + assert(cbdata->subhandle); + cbdata->handle = cbdata->subhandle; + cbdata->subhandle = 0; + break; + } + if (!kv->entry) + { + assert(!cbdata->subhandle); + cbdata->subhandle = cbdata->handle; + } + cbdata->handle = repodata_new_handle(data); + repodata_add_flexarray(data, cbdata->subhandle, keyname, cbdata->handle); + break; default: break; } @@ -1203,8 +1265,9 @@ solvable_copy(Solvable *s, Solvable *r, Repodata *data, Id *dircache) return; cbdata.data = data; cbdata.handle = s - pool->solvables; + cbdata.subhandle = 0; cbdata.dircache = dircache; - repo_search(fromrepo, (r - fromrepo->pool->solvables), 0, 0, SEARCH_NO_STORAGE_SOLVABLE, solvable_copy_cb, &cbdata); + repo_search(fromrepo, (r - fromrepo->pool->solvables), 0, 0, SEARCH_NO_STORAGE_SOLVABLE | SEARCH_SUB | SEARCH_ARRAYSENTINEL, solvable_copy_cb, &cbdata); } /* used to sort entries returned in some database order */ @@ -1792,7 +1855,7 @@ getu32(const unsigned char *dp) Id repo_add_rpm(Repo *repo, const char *rpm, int flags) { - int sigdsize, sigcnt, l; + unsigned int sigdsize, sigcnt, l; Pool *pool = repo->pool; Solvable *s; RpmHead *rpmhead = 0; @@ -1957,7 +2020,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags) } sigcnt = getu32(lead + 8); sigdsize = getu32(lead + 12); - if (sigcnt >= 0x100000 || sigdsize >= 0x800000) + if (sigcnt >= 0x100000 || sigdsize >= 0x2000000) { pool_error(pool, -1, "%s: bad header", rpm); fclose(fp); @@ -2521,7 +2584,7 @@ rpm_byfp(FILE *fp, const char *name, void **statep) struct rpm_by_state *state = *statep; /* int headerstart, headerend; */ RpmHead *rpmhead; - int sigdsize, sigcnt, l; + unsigned int sigdsize, sigcnt, l; unsigned char lead[4096]; int forcebinary = 0; @@ -2581,7 +2644,7 @@ rpm_byfp(FILE *fp, const char *name, void **statep) } sigcnt = getu32(lead + 8); sigdsize = getu32(lead + 12); - if (sigcnt >= 0x100000 || sigdsize >= 0x800000) + if (sigcnt >= 0x100000 || sigdsize >= 0x2000000) { fprintf(stderr, "%s: bad header\n", name); fclose(fp); @@ -2615,7 +2678,7 @@ rpm_byrpmh(Header h, void **statep) { struct rpm_by_state *state = *statep; const unsigned char *uh; - int sigdsize, sigcnt, l; + unsigned int sigdsize, sigcnt, l; RpmHead *rpmhead; #ifndef RPM5 diff --git a/ext/repo_rpmdb.h b/ext/repo_rpmdb.h index 1e12de7..fdc6120 100644 --- a/ext/repo_rpmdb.h +++ b/ext/repo_rpmdb.h @@ -24,6 +24,7 @@ extern Id repo_add_pubkey(Repo *repo, const char *key, int flags); #define RPM_ADD_TRIGGERS (1 << 14) #define RPM_ADD_WITH_HDRID (1 << 15) #define RPM_ADD_WITH_LEADSIGID (1 << 16) +#define RPM_ADD_WITH_CHANGELOG (1 << 17) #define RPM_ITERATE_FILELIST_ONLYDIRS (1 << 0) #define RPM_ITERATE_FILELIST_WITHMD5 (1 << 1) diff --git a/ext/repo_rpmmd.c b/ext/repo_rpmmd.c index b765e5b..603b27b 100644 --- a/ext/repo_rpmmd.c +++ b/ext/repo_rpmmd.c @@ -114,6 +114,8 @@ enum state { STATE_FILE, + STATE_CHANGELOG, + /* general */ NUMSTATES }; @@ -203,6 +205,7 @@ static struct stateswitch stateswitches[] = { { STATE_SOLVABLE, "rpm:sourcerpm", STATE_SOURCERPM, 1 }, { STATE_SOLVABLE, "rpm:header-range", STATE_HEADERRANGE, 0 }, { STATE_SOLVABLE, "file", STATE_FILE, 1 }, + { STATE_SOLVABLE, "changelog", STATE_CHANGELOG, 1 }, /* extended Novell/SUSE diskusage attributes (susedata.xml) */ { STATE_DISKUSAGE, "dirs", STATE_DIRS, 0 }, @@ -224,11 +227,6 @@ static struct stateswitch stateswitches[] = { { NUMSTATES} }; -/* maxmum initial size of - the checksum cache */ -#define MAX_CSCACHE 32768 -#define CSREALLOC_STEP 1024 - struct parsedata { int ret; Pool *pool; @@ -261,6 +259,8 @@ struct parsedata { char *lastdirstr; int lastdirstrl; + Id changelog_handle; + /** Hash to maps checksums to solv */ Stringpool cspool; /** Cache of known checksums to solvable id */ @@ -833,6 +833,13 @@ startElement(void *userData, const char *name, const char **atts) pd->ndirs++; break; } + case STATE_CHANGELOG: + pd->changelog_handle = repodata_new_handle(pd->data); + if ((str = find_attr("date", atts)) != 0) + repodata_set_num(pd->data, pd->changelog_handle, SOLVABLE_CHANGELOG_TIME, strtoull(str, 0, 10)); + if ((str = find_attr("author", atts)) != 0) + repodata_set_str(pd->data, pd->changelog_handle, SOLVABLE_CHANGELOG_AUTHOR, str); + break; default: break; } @@ -1044,6 +1051,12 @@ endElement(void *userData, const char *name) case STATE_ORDER: if (pd->content[0]) repodata_set_str(pd->data, pd->handle, SOLVABLE_ORDER, pd->content); + break; + case STATE_CHANGELOG: + repodata_set_str(pd->data, pd->changelog_handle, SOLVABLE_CHANGELOG_TEXT, pd->content); + repodata_add_flexarray(pd->data, pd->handle, SOLVABLE_CHANGELOG, pd->changelog_handle); + pd->changelog_handle = 0; + break; default: break; } diff --git a/ext/testcase.c b/ext/testcase.c index 7d8e191..48e4c21 100644 --- a/ext/testcase.c +++ b/ext/testcase.c @@ -23,6 +23,7 @@ #include "solverdebug.h" #include "chksum.h" #include "testcase.h" +#include "selection.h" #include "solv_xfopen.h" #define DISABLE_JOIN2 @@ -120,9 +121,29 @@ static struct disttype2str { { DISTTYPE_RPM, "rpm" }, { DISTTYPE_DEB, "deb" }, { DISTTYPE_ARCH, "arch" }, - { 0, 0 }, + { 0, 0 } +}; + +static struct selflags2str { + Id flag; + const char *str; +} selflags2str[] = { + { SELECTION_NAME, "name" }, + { SELECTION_PROVIDES, "provides" }, + { SELECTION_FILELIST, "filelist" }, + { SELECTION_CANON, "canon" }, + { SELECTION_DOTARCH, "dotarch" }, + { SELECTION_REL, "rel" }, + { SELECTION_INSTALLED_ONLY, "installedonly" }, + { SELECTION_GLOB, "glob" }, + { SELECTION_FLAT, "flat" }, + { SELECTION_NOCASE, "nocase" }, + { SELECTION_SOURCE_ONLY, "sourceonly" }, + { SELECTION_WITH_SOURCE, "withsource" }, + { 0, 0 } }; + typedef struct strqueue { char **str; int nstr; @@ -561,6 +582,50 @@ testcase_job2str(Pool *pool, Id how, Id what) return ret; } +static int +str2selflags(Pool *pool, char *s) /* modifies the string! */ +{ + int i, selflags = 0; + while (s) + { + char *se = strchr(s, ','); + if (se) + *se++ = 0; + for (i = 0; selflags2str[i].str; i++) + if (!strcmp(s, selflags2str[i].str)) + { + selflags |= selflags2str[i].flag; + break; + } + if (!selflags2str[i].str) + pool_debug(pool, SOLV_ERROR, "str2job: unknown selection flag '%s'\n", s); + s = se; + } + return selflags; +} + +static int +str2jobflags(Pool *pool, char *s) /* modifies the string */ +{ + int i, jobflags = 0; + while (s) + { + char *se = strchr(s, ','); + if (se) + *se++ = 0; + for (i = 0; jobflags2str[i].str; i++) + if (!strcmp(s, jobflags2str[i].str)) + { + jobflags |= jobflags2str[i].flag; + break; + } + if (!jobflags2str[i].str) + pool_debug(pool, SOLV_ERROR, "str2job: unknown job flag '%s'\n", s); + s = se; + } + return jobflags; +} + Id testcase_str2job(Pool *pool, const char *str, Id *whatp) { @@ -592,7 +657,7 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp) { pool_debug(pool, SOLV_ERROR, "str2job: bad line '%s'\n", str); solv_free(pieces); - return 0; + return -1; } for (i = 0; job2str[i].str; i++) @@ -602,35 +667,19 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp) { pool_debug(pool, SOLV_ERROR, "str2job: unknown job '%s'\n", str); solv_free(pieces); - return 0; + return -1; } job = job2str[i].job; + what = 0; if (npieces > 3) { char *flags = pieces[npieces - 1]; - char *nf; if (*flags == '[' && flags[strlen(flags) - 1] == ']') { npieces--; flags++; - flags[strlen(flags) - 1] = ','; - while (*flags) - { - for (nf = flags; *nf != ','; nf++) - ; - *nf++ = 0; - for (i = 0; jobflags2str[i].str; i++) - if (!strcmp(flags, jobflags2str[i].str)) - break; - if (!jobflags2str[i].str) - { - pool_debug(pool, SOLV_ERROR, "str2job: unknown jobflags in '%s'\n", str); - solv_free(pieces); - return 0; - } - job |= jobflags2str[i].flag; - flags = nf; - } + flags[strlen(flags) - 1] = 0; + job |= str2jobflags(pool, flags); } } if (!strcmp(pieces[1], "pkg")) @@ -639,7 +688,7 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp) { pool_debug(pool, SOLV_ERROR, "str2job: bad pkg selector in '%s'\n", str); solv_free(pieces); - return 0; + return -1; } job |= SOLVER_SOLVABLE; what = testcase_str2solvid(pool, pieces[2]); @@ -647,7 +696,7 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp) { pool_debug(pool, SOLV_ERROR, "str2job: unknown package '%s'\n", pieces[2]); solv_free(pieces); - return 0; + return -1; } } else if (!strcmp(pieces[1], "name") || !strcmp(pieces[1], "provides")) @@ -696,7 +745,7 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp) pool_debug(pool, SOLV_ERROR, "str2job: unknown package '%s'\n", pieces[i]); queue_free(&q); solv_free(pieces); - return 0; + return -1; } queue_push(&q, p); } @@ -711,14 +760,14 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp) { pool_debug(pool, SOLV_ERROR, "str2job: bad line '%s'\n", str); solv_free(pieces); - return 0; + return -1; } repo = testcase_str2repo(pool, pieces[2]); if (!repo) { pool_debug(pool, SOLV_ERROR, "str2job: unknown repo '%s'\n", pieces[2]); solv_free(pieces); - return 0; + return -1; } job |= SOLVER_SOLVABLE_REPO; what = repo->repoid; @@ -729,7 +778,7 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp) { pool_debug(pool, SOLV_ERROR, "str2job: bad line '%s'\n", str); solv_free(pieces); - return 0; + return -1; } job |= SOLVER_SOLVABLE_ALL; what = 0; @@ -738,13 +787,55 @@ testcase_str2job(Pool *pool, const char *str, Id *whatp) { pool_debug(pool, SOLV_ERROR, "str2job: unknown selection in '%s'\n", str); solv_free(pieces); - return 0; + return -1; } *whatp = what; solv_free(pieces); return job; } +int +addselectionjob(Pool *pool, char **pieces, int npieces, Queue *jobqueue) +{ + Id job; + int i, r; + int selflags; + Queue sel; + + for (i = 0; job2str[i].str; i++) + if (!strcmp(pieces[0], job2str[i].str)) + break; + if (!job2str[i].str) + { + pool_debug(pool, SOLV_ERROR, "selstr2job: unknown job '%s'\n", pieces[0]); + return -1; + } + job = job2str[i].job; + if (npieces > 3) + { + char *flags = pieces[npieces - 1]; + if (*flags == '[' && flags[strlen(flags) - 1] == ']') + { + npieces--; + flags++; + flags[strlen(flags) - 1] = 0; + job |= str2jobflags(pool, flags); + } + } + if (npieces < 4) + { + pool_debug(pool, SOLV_ERROR, "selstr2job: no selection flags\n"); + return -1; + } + selflags = str2selflags(pool, pieces[3]); + queue_init(&sel); + r = selection_make(pool, &sel, pieces[2], selflags); + for (i = 0; i < sel.count; i += 2) + queue_push2(jobqueue, job | sel.elements[i], sel.elements[i + 1]); + queue_free(&sel); + return r; +} + static void writedeps(Repo *repo, FILE *fp, const char *tag, Id key, Solvable *s, Offset off) { @@ -1743,6 +1834,28 @@ read_file(FILE *fp) return result; } +static int +str2resultflags(Pool *pool, char *s) /* modifies the string! */ +{ + int i, resultflags = 0; + while (s) + { + char *se = strchr(s, ','); + if (se) + *se++ = 0; + for (i = 0; resultflags2str[i].str; i++) + if (!strcmp(s, resultflags2str[i].str)) + { + resultflags |= resultflags2str[i].flag; + break; + } + if (!resultflags2str[i].str) + pool_debug(pool, SOLV_ERROR, "result: unknown flag '%s'\n", s); + s = se; + } + return resultflags; +} + Solver * testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, int *resultflagsp) { @@ -1860,6 +1973,13 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, repo_add_solv(repo, rfp, 0); fclose(rfp); } +#if 0 + else if (!strcmp(repotype, "helix")) + { + repo_add_helix(repo, rfp, 0); + fclose(rfp); + } +#endif else { fclose(rfp); @@ -1908,6 +2028,11 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, pool_createwhatprovides(pool); prepared = 1; } + if (npieces >= 3 && !strcmp(pieces[2], "selection")) + { + addselectionjob(pool, pieces + 1, npieces - 1, job); + continue; + } /* rejoin */ for (sp = pieces[1]; sp < pieces[npieces - 1]; sp++) if (*sp == 0) @@ -1977,28 +2102,9 @@ testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, } else if (!strcmp(pieces[0], "result") && npieces > 2) { - const char *rdata; char *result = 0; - int resultflags = 0; - char *s = pieces[1]; - int i; - while (s) - { - char *se = strchr(s, ','); - if (se) - *se++ = 0; - for (i = 0; resultflags2str[i].str; i++) - if (!strcmp(s, resultflags2str[i].str)) - { - resultflags |= resultflags2str[i].flag; - break; - } - if (!resultflags2str[i].str) - pool_debug(pool, SOLV_ERROR, "result: unknown flag '%s'\n", s); - s = se; - } - - rdata = pool_tmpjoin(pool, testcasedir, pieces[2], 0); + int resultflags = str2resultflags(pool, pieces[1]); + const char *rdata = pool_tmpjoin(pool, testcasedir, pieces[2], 0); if (!strcmp(pieces[2], "")) result = read_inline_file(fp, &buf, &bufp, &bufl); else diff --git a/package/libsolv.changes b/package/libsolv.changes index aee838a..1169b9a 100644 --- a/package/libsolv.changes +++ b/package/libsolv.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Wed Mar 6 16:55:57 CET 2013 - mls@suse.de + +- fix dataiterator returning random data in some cases +- add changelog parser +- fix nasty bug in selection_filter_rel +- allow re-run of an existing solver +- bump version to 0.3.0 + ------------------------------------------------------------------- Mon Jan 14 16:01:04 CET 2013 - mls@suse.de diff --git a/src/dataiterator.h b/src/dataiterator.h index 6f8fd32..a77d902 100644 --- a/src/dataiterator.h +++ b/src/dataiterator.h @@ -132,6 +132,16 @@ typedef struct _Dataiterator } parents[3]; int nparents; + /* vertical data */ + unsigned char *vert_ddp; + Id vert_off; + Id vert_len; + Id vert_storestate; + + /* strdup data */ + char *dupstr; + int dupstrn; + } Dataiterator; @@ -165,6 +175,7 @@ void dataiterator_jump_to_repo(Dataiterator *di, struct _Repo *repo); void dataiterator_entersub(Dataiterator *di); void dataiterator_clonepos(Dataiterator *di, Dataiterator *from); void dataiterator_seek(Dataiterator *di, int whence); +void dataiterator_strdup(Dataiterator *di); #define DI_SEEK_STAY (1 << 16) #define DI_SEEK_CHILD 1 diff --git a/src/knownid.h b/src/knownid.h index ad8b4a4..83b943e 100644 --- a/src/knownid.h +++ b/src/knownid.h @@ -58,6 +58,7 @@ KNOWNID(ARCH_SRC, "src"), KNOWNID(ARCH_NOSRC, "nosrc"), KNOWNID(ARCH_NOARCH, "noarch"), KNOWNID(ARCH_ALL, "all"), +KNOWNID(ARCH_ANY, "any"), KNOWNID(REPOSITORY_SOLVABLES, "repository:solvables"), KNOWNID(REPOSITORY_DELTAINFO, "repository:deltainfo"), @@ -133,6 +134,11 @@ KNOWNID(SOLVABLE_LEADSIGID, "solvable:leadsigid"), /* leadsigid: md5sum over l KNOWNID(SOLVABLE_PATCHCATEGORY, "solvable:patchcategory"), KNOWNID(SOLVABLE_HEADEREND, "solvable:headerend"), +KNOWNID(SOLVABLE_CHANGELOG, "solvable:changelog"), +KNOWNID(SOLVABLE_CHANGELOG_AUTHOR, "solvable:changelog:author"), +KNOWNID(SOLVABLE_CHANGELOG_TIME, "solvable:changelog:time"), +KNOWNID(SOLVABLE_CHANGELOG_TEXT, "solvable:changelog:text"), + /* stuff for solvables of type pattern */ KNOWNID(SOLVABLE_CATEGORY, "solvable:category"), @@ -184,6 +190,10 @@ KNOWNID(SUSETAGS_FILE, "susetags:file"), KNOWNID(SUSETAGS_FILE_NAME, "susetags:file:name"), KNOWNID(SUSETAGS_FILE_TYPE, "susetags:file:type"), KNOWNID(SUSETAGS_FILE_CHECKSUM, "susetags:file:checksum"), +KNOWNID(SUSETAGS_SHARE_NAME, "susetags:share:name"), +KNOWNID(SUSETAGS_SHARE_EVR, "susetags:share:evr"), +KNOWNID(SUSETAGS_SHARE_ARCH, "susetags:share:arch"), + /* timestamp then the repository was generated */ KNOWNID(REPOSITORY_TIMESTAMP, "repository:timestamp"), @@ -200,11 +210,13 @@ KNOWNID(REPOSITORY_UPDATES, "repository:updates"), KNOWNID(REPOSITORY_DISTROS, "repository:distros"), KNOWNID(REPOSITORY_PRODUCT_LABEL, "repository:product:label"), KNOWNID(REPOSITORY_PRODUCT_CPEID, "repository:product:cpeid"), +KNOWNID(REPOSITORY_REPOID, "repository:repoid"), /* obsolete? */ /* keyword (tags) for this repository */ KNOWNID(REPOSITORY_KEYWORDS, "repository:keywords"), /* revision of the repository. arbitrary string */ KNOWNID(REPOSITORY_REVISION, "repository:revision"), +KNOWNID(REPOSITORY_TOOLVERSION, "repository:toolversion"), KNOWNID(DELTA_PACKAGE_NAME, "delta:pkgname"), KNOWNID(DELTA_PACKAGE_EVR, "delta:pkgevr"), @@ -229,23 +241,13 @@ KNOWNID(REPOSITORY_REPOMD_LOCATION, "repository:repomd:location"), KNOWNID(REPOSITORY_REPOMD_TIMESTAMP, "repository:repomd:timestamp"), KNOWNID(REPOSITORY_REPOMD_CHECKSUM, "repository:repomd:checksum"), KNOWNID(REPOSITORY_REPOMD_OPENCHECKSUM, "repository:repomd:openchecksum"), +KNOWNID(REPOSITORY_REPOMD_SIZE, "repository:repomd:size"), KNOWNID(PUBKEY_KEYID, "pubkey:keyid"), KNOWNID(PUBKEY_FINGERPRINT, "pubkey:fingerprint"), KNOWNID(PUBKEY_EXPIRES, "pubkey:expires"), KNOWNID(PUBKEY_SIGNATURES, "pubkey:signatures"), -KNOWNID(REPOSITORY_TOOLVERSION, "repository:toolversion"), -KNOWNID(REPOSITORY_REPOID, "repository:repoid"), - -KNOWNID(SUSETAGS_SHARE_NAME, "susetags:share:name"), -KNOWNID(SUSETAGS_SHARE_EVR, "susetags:share:evr"), -KNOWNID(SUSETAGS_SHARE_ARCH, "susetags:share:arch"), - -KNOWNID(ARCH_ANY, "any"), - -KNOWNID(REPOSITORY_REPOMD_SIZE, "repository:repomd:size"), - KNOWNID(ID_NUM_INTERNAL, 0) #ifdef KNOWNID_INITIALIZE diff --git a/src/libsolv.ver b/src/libsolv.ver index bc487ce..52b51da 100644 --- a/src/libsolv.ver +++ b/src/libsolv.ver @@ -19,6 +19,7 @@ SOLV_1.0 { dataiterator_skip_repo; dataiterator_skip_solvable; dataiterator_step; + dataiterator_strdup; datamatcher_free; datamatcher_init; datamatcher_match; @@ -89,6 +90,7 @@ SOLV_1.0 { pool_rel2id; pool_search; pool_selection2str; + pool_set_custom_vendorcheck; pool_set_flag; pool_set_installed; pool_set_languages; diff --git a/src/policy.c b/src/policy.c index abd07e5..916590c 100644 --- a/src/policy.c +++ b/src/policy.c @@ -601,11 +601,6 @@ prune_to_best_version(Pool *pool, Queue *plist) static void prune_best_arch_name_version(const Solver *solv, Pool *pool, Queue *plist) { - if (solv && solv->bestSolvableCb) - { /* The application is responsible for */ - return solv->bestSolvableCb(solv->pool, plist); - } - if (plist->count > 1) prune_to_best_arch(pool, plist); if (plist->count > 1) @@ -675,11 +670,6 @@ policy_illegal_archchange(Solver *solv, Solvable *s1, Solvable *s2) Pool *pool = solv->pool; Id a1 = s1->arch, a2 = s2->arch; - if (solv && solv->archCheckCb) - { /* The application is responsible for */ - return solv->archCheckCb(solv->pool, s1, s2); - } - /* we allow changes to/from noarch */ if (a1 == a2 || a1 == pool->noarchid || a2 == pool->noarchid) return 0; @@ -701,10 +691,9 @@ policy_illegal_vendorchange(Solver *solv, Solvable *s1, Solvable *s2) Id v1, v2; Id vendormask1, vendormask2; - if (solv->vendorCheckCb) - { /* The application is responsible for */ - return solv->vendorCheckCb(pool, s1, s2); - } + if (pool->custom_vendorcheck) + return pool->custom_vendorcheck(pool, s1, s2); + /* treat a missing vendor as empty string */ v1 = s1->vendor ? s1->vendor : ID_EMPTY; v2 = s2->vendor ? s2->vendor : ID_EMPTY; @@ -768,6 +757,8 @@ policy_create_obsolete_index(Solver *solv) Id p, pp, obs, *obsp, *obsoletes, *obsoletes_data; int i, n, cnt; + solv->obsoletes = solv_free(solv->obsoletes); + solv->obsoletes_data = solv_free(solv->obsoletes_data); if (!installed || installed->start == installed->end) return; cnt = installed->end - installed->start; @@ -867,11 +858,6 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all) queue_empty(qs); - if (solv && solv->updateCandidateCb) - { /* The application is responsible for */ - return solv->updateCandidateCb(solv->pool, s, qs); - } - n = s - pool->solvables; /* diff --git a/src/pool.c b/src/pool.c index d8eb040..3b27318 100644 --- a/src/pool.c +++ b/src/pool.c @@ -758,6 +758,8 @@ pool_addrelproviders(Pool *pool, Id d) continue; if (s->arch != evr && s->arch != ARCH_NOSRC) continue; + if (pool_disabled_solvable(pool, s)) + continue; if (pool_match_nevr(pool, s, name)) queue_push(&plist, p); } @@ -2096,6 +2098,39 @@ pool_lookup_deltalocation(Pool *pool, Id entry, unsigned int *medianrp) return loc; } +static void +add_new_provider(Pool *pool, Id id, Id p) +{ + Queue q; + Id *pp; + + while (ISRELDEP(id)) + { + Reldep *rd = GETRELDEP(pool, id); + id = rd->name; + } + + queue_init(&q); + for (pp = pool->whatprovidesdata + pool->whatprovides[id]; *pp; pp++) + { + if (*pp == p) + { + queue_free(&q); + return; + } + if (*pp > p) + { + queue_push(&q, p); + p = 0; + } + queue_push(&q, *pp); + } + if (p) + queue_push(&q, p); + pool->whatprovides[id] = pool_queuetowhatprovides(pool, &q); + queue_free(&q); +} + void pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts) { @@ -2107,7 +2142,6 @@ pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts) if (!conflicts->count) return; - pool_freewhatprovides(pool); for (i = 0; i < conflicts->count; i += 5) { fn = conflicts->elements[i]; @@ -2119,6 +2153,10 @@ pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts) if (!s->repo) 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 */ s = pool->solvables + q; if (!s->repo) continue; @@ -2161,4 +2199,11 @@ pool_get_rootdir(Pool *pool) return pool->rootdir; } +/* only used in libzypp */ +void +pool_set_custom_vendorcheck(Pool *pool, int (*vendorcheck)(Pool *, Solvable *, Solvable *)) +{ + pool->custom_vendorcheck = vendorcheck; +} + /* EOF */ diff --git a/src/pool.h b/src/pool.h index e785cd8..8e1a951 100644 --- a/src/pool.h +++ b/src/pool.h @@ -148,8 +148,8 @@ struct _Pool { char *rootdir; + int (*custom_vendorcheck)(struct _Pool *, Solvable *, Solvable *); #endif - }; #define DISTTYPE_RPM 0 @@ -223,6 +223,7 @@ extern void pool_debug(Pool *pool, int type, const char *format, ...) __attribut extern void pool_setdebugcallback(Pool *pool, void (*debugcallback)(struct _Pool *, void *data, int type, const char *str), void *debugcallbackdata); extern void pool_setdebugmask(Pool *pool, int mask); extern void pool_setloadcallback(Pool *pool, int (*cb)(struct _Pool *, struct _Repodata *, void *), void *loadcbdata); +extern void pool_set_custom_vendorcheck(Pool *pool, int (*vendorcheck)(struct _Pool *, Solvable *, Solvable *)); extern char *pool_alloctmpspace(Pool *pool, int len); @@ -265,8 +266,7 @@ Id pool_id2langid(Pool *pool, Id id, const char *lang, int create); int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap, Map *noobsoletesmap); int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed, Map *noobsoletesmap); int solvable_trivial_installable_queue(Solvable *s, Queue *installed, Map *noobsoletesmap); -struct _Solver; /* argh, needed for vendorchange callback FIXME */ -int solvable_is_irrelevant_patch(Solvable *s, Map *installedmap, struct _Solver *solv); +int solvable_is_irrelevant_patch(Solvable *s, Map *installedmap); void pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *conflictsmap); diff --git a/src/repo.h b/src/repo.h index 4f93d1e..a7a56ae 100644 --- a/src/repo.h +++ b/src/repo.h @@ -84,6 +84,19 @@ static inline Repo *pool_id2repo(Pool *pool, Id repoid) return repoid < pool->nrepos ? pool->repos[repoid] : 0; } +static inline int pool_disabled_solvable(const Pool *pool, Solvable *s) +{ + if (s->repo && s->repo->disabled) + return 1; + if (pool->considered) + { + Id id = s - pool->solvables; + if (!MAPTST(pool->considered, id)) + return 1; + } + return 0; +} + static inline int pool_installable(const Pool *pool, Solvable *s) { if (!s->arch || s->arch == ARCH_SRC || s->arch == ARCH_NOSRC) diff --git a/src/repo_write.c b/src/repo_write.c index f6e9fd6..fd8ff40 100644 --- a/src/repo_write.c +++ b/src/repo_write.c @@ -976,6 +976,8 @@ static Id verticals[] = { SOLVABLE_PKGID, SOLVABLE_HDRID, SOLVABLE_LEADSIGID, + SOLVABLE_CHANGELOG_AUTHOR, + SOLVABLE_CHANGELOG_TEXT, 0 }; diff --git a/src/repodata.c b/src/repodata.c index 9d3bb6b..2462c10 100644 --- a/src/repodata.c +++ b/src/repodata.c @@ -474,7 +474,7 @@ static unsigned char * get_vertical_data(Repodata *data, Repokey *key, Id off, Id len) { unsigned char *dp; - if (!len) + if (len <= 0) return 0; if (off >= data->lastverticaloffset) { @@ -489,6 +489,7 @@ get_vertical_data(Repodata *data, Repokey *key, Id off, Id len) off += data->verticaloffset[key - data->keys]; /* fprintf(stderr, "key %d page %d\n", key->name, off / REPOPAGE_BLOBSIZE); */ dp = repopagestore_load_page_range(&data->store, off / REPOPAGE_BLOBSIZE, (off + len - 1) / REPOPAGE_BLOBSIZE); + data->storestate++; if (dp) dp += off % REPOPAGE_BLOBSIZE; return dp; @@ -834,19 +835,21 @@ repodata_stringify(Pool *pool, Repodata *data, Repokey *key, KeyValue *kv, int f case REPOKEY_TYPE_DIRSTRARRAY: if (!(flags & SEARCH_FILES)) return 1; /* match just the basename */ + if (kv->num) + return 1; /* already stringified */ /* Put the full filename into kv->str. */ kv->str = repodata_dir2str(data, kv->id, kv->str); - /* And to compensate for that put the "empty" directory into - kv->id, so that later calls to repodata_dir2str on this data - come up with the same filename again. */ - kv->id = 0; + kv->num = 1; /* mark stringification */ return 1; case REPOKEY_TYPE_MD5: case REPOKEY_TYPE_SHA1: case REPOKEY_TYPE_SHA256: if (!(flags & SEARCH_CHECKSUMS)) return 0; /* skip em */ + if (kv->num) + return 1; /* already stringified */ kv->str = repodata_chk2str(data, key->type, (const unsigned char *)kv->str); + kv->num = 1; /* mark stringification */ return 1; default: return 0; @@ -1235,6 +1238,19 @@ void dataiterator_init_clone(Dataiterator *di, Dataiterator *from) { *di = *from; + if (di->dupstr) + { + if (di->dupstr == di->kv.str) + { + di->dupstr = solv_malloc(di->dupstrn); + memcpy(di->dupstr, from->dupstr, di->dupstrn); + } + else + { + di->dupstr = 0; + di->dupstrn = 0; + } + } memset(&di->matcher, 0, sizeof(di->matcher)); if (from->matcher.match) datamatcher_init(&di->matcher, from->matcher.match, from->matcher.flags); @@ -1319,6 +1335,8 @@ dataiterator_free(Dataiterator *di) { if (di->matcher.match) datamatcher_free(&di->matcher); + if (di->dupstr) + solv_free(di->dupstr); } static inline unsigned char * @@ -1366,6 +1384,15 @@ dataiterator_step(Dataiterator *di) { Id schema; + if (di->state == di_nextattr && di->key->storage == KEY_STORAGE_VERTICAL_OFFSET && di->vert_ddp && di->vert_storestate != di->data->storestate) { + unsigned int ddpoff = di->ddp - di->vert_ddp; + di->vert_off += ddpoff; + di->vert_len -= ddpoff; + di->ddp = di->vert_ddp = get_vertical_data(di->data, di->key, di->vert_off, di->vert_len); + di->vert_storestate = di->data->storestate; + if (!di->ddp) + di->state = di_nextkey; + } for (;;) { switch (di->state) @@ -1429,7 +1456,27 @@ dataiterator_step(Dataiterator *di) case di_enterkey: di_enterkey: di->kv.entry = -1; di->key = di->data->keys + *di->keyp; - di->ddp = get_data(di->data, di->key, &di->dp, di->keyp[1] && (!di->keyname || (di->flags & SEARCH_SUB) != 0) ? 1 : 0); + if (!di->dp) + goto di_nextkey; + /* this is get_data() modified to store vert_ data */ + if (di->key->storage == KEY_STORAGE_VERTICAL_OFFSET) + { + Id off, len; + di->dp = data_read_id(di->dp, &off); + di->dp = data_read_id(di->dp, &len); + di->vert_ddp = di->ddp = get_vertical_data(di->data, di->key, off, len); + di->vert_off = off; + di->vert_len = len; + di->vert_storestate = di->data->storestate; + } + else if (di->key->storage == KEY_STORAGE_INCORE) + { + di->ddp = di->dp; + if (di->keyp[1] && (!di->keyname || (di->flags & SEARCH_SUB) != 0)) + di->dp = data_skip_key(di->data, di->dp, di->key); + } + else + di->ddp = 0; if (!di->ddp) goto di_nextkey; if (di->key->type == REPOKEY_TYPE_DELETED) @@ -1683,6 +1730,14 @@ dataiterator_clonepos(Dataiterator *di, Dataiterator *from) di->parents[i].kv.parent = &di->parents[i - 1].kv; di->kv.parent = &di->parents[di->nparents - 1].kv; } + di->dupstr = 0; + di->dupstrn = 0; + if (from->dupstr && from->dupstr == from->kv.str) + { + di->dupstrn = from->dupstrn; + di->dupstr = solv_malloc(from->dupstrn); + memcpy(di->dupstr, from->dupstr, di->dupstrn); + } } void @@ -1829,6 +1884,60 @@ dataiterator_match(Dataiterator *di, Datamatcher *ma) return datamatcher_match(ma, di->kv.str); } +void +dataiterator_strdup(Dataiterator *di) +{ + int l = -1; + + if (!di->kv.str || di->kv.str == di->dupstr) + return; + switch (di->key->type) + { + case REPOKEY_TYPE_MD5: + case REPOKEY_TYPE_SHA1: + case REPOKEY_TYPE_SHA256: + case REPOKEY_TYPE_DIRSTRARRAY: + if (di->kv.num) /* was it stringified into tmp space? */ + l = strlen(di->kv.str) + 1; + break; + default: + break; + } + if (l < 0 && di->key->storage == KEY_STORAGE_VERTICAL_OFFSET) + { + switch (di->key->type) + { + case REPOKEY_TYPE_STR: + case REPOKEY_TYPE_DIRSTRARRAY: + l = strlen(di->kv.str) + 1; + break; + case REPOKEY_TYPE_MD5: + l = SIZEOF_MD5; + break; + case REPOKEY_TYPE_SHA1: + l = SIZEOF_SHA1; + break; + case REPOKEY_TYPE_SHA256: + l = SIZEOF_SHA256; + break; + case REPOKEY_TYPE_BINARY: + l = di->kv.num; + break; + } + } + if (l >= 0) + { + if (!di->dupstrn || di->dupstrn < l) + { + di->dupstrn = l + 16; + di->dupstr = solv_realloc(di->dupstr, di->dupstrn); + } + if (l) + memcpy(di->dupstr, di->kv.str, l); + di->kv.str = di->dupstr; + } +} + /************************************************************************ * data modify functions */ @@ -3071,7 +3180,10 @@ void repodata_disable_paging(Repodata *data) { if (maybe_load_repodata(data, 0)) - repopagestore_disable_paging(&data->store); + { + repopagestore_disable_paging(&data->store); + data->storestate++; + } } static void diff --git a/src/repodata.h b/src/repodata.h index 7ce415b..54fb3df 100644 --- a/src/repodata.h +++ b/src/repodata.h @@ -96,6 +96,7 @@ typedef struct _Repodata { Id lastverticaloffset; /* end of verticals */ Repopagestore store; /* our page store */ + Id storestate; /* incremented every time the store might change */ unsigned char *vincore; /* internal vertical data */ unsigned int vincorelen; /* data size */ diff --git a/src/repopack.h b/src/repopack.h index 81b7b88..d75e61a 100644 --- a/src/repopack.h +++ b/src/repopack.h @@ -164,12 +164,15 @@ data_fetch(unsigned char *dp, KeyValue *kv, Repokey *key) kv->num2 = 0; return data_read_u32(dp, &kv->num); case REPOKEY_TYPE_MD5: + kv->num = 0; /* not stringified yet */ kv->str = (const char *)dp; return dp + SIZEOF_MD5; case REPOKEY_TYPE_SHA1: + kv->num = 0; /* not stringified yet */ kv->str = (const char *)dp; return dp + SIZEOF_SHA1; case REPOKEY_TYPE_SHA256: + kv->num = 0; /* not stringified yet */ kv->str = (const char *)dp; return dp + SIZEOF_SHA256; case REPOKEY_TYPE_BINARY: @@ -180,6 +183,7 @@ data_fetch(unsigned char *dp, KeyValue *kv, Repokey *key) return data_read_ideof(dp, &kv->id, &kv->eof); case REPOKEY_TYPE_DIRSTRARRAY: dp = data_read_ideof(dp, &kv->id, &kv->eof); + kv->num = 0; /* not stringified yet */ kv->str = (const char *)dp; return dp + strlen(kv->str) + 1; case REPOKEY_TYPE_DIRNUMNUMARRAY: diff --git a/src/rules.c b/src/rules.c index f6facf4..1003878 100644 --- a/src/rules.c +++ b/src/rules.c @@ -377,6 +377,12 @@ solver_addrule(Solver *solv, Id p, Id d) return r; } +void +solver_shrinkrules(Solver *solv, int nrules) +{ + solv->nrules = nrules; + solv->rules = solv_extend_resize(solv->rules, solv->nrules, sizeof(Rule), RULES_BLOCK); +} /****************************************************************************** *** @@ -507,13 +513,15 @@ solver_addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) dontfix = 1; /* dont care about broken rpm deps */ } - if (!dontfix - && s->arch != ARCH_SRC - && s->arch != ARCH_NOSRC - && !pool_installable(pool, s)) + if (!dontfix) { - POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, "package %s [%d] is not installable\n", pool_solvable2str(pool, s), (Id)(s - pool->solvables)); - addrpmrule(solv, -n, 0, SOLVER_RULE_RPM_NOT_INSTALLABLE, 0); + if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC + ? pool_disabled_solvable(pool, s) + : !pool_installable(pool, s)) + { + POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, "package %s [%d] is not installable\n", pool_solvable2str(pool, s), (Id)(s - pool->solvables)); + addrpmrule(solv, -n, 0, SOLVER_RULE_RPM_NOT_INSTALLABLE, 0); + } } /* yet another SUSE hack, sigh */ @@ -1822,17 +1830,46 @@ void solver_reenablepolicyrules(Solver *solv, int jobidx) { Queue *job = &solv->job; - int i, j; + int i, j, k, ai; Queue q, allq; Rule *r; Id lastjob = -1; - Id qbuf[32], allqbuf[128]; + Id qbuf[32], allqbuf[32]; queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf)); - queue_init_buffer(&allq, allqbuf, sizeof(allqbuf)/sizeof(*allqbuf)); jobtodisablelist(solv, job->elements[jobidx - 1], job->elements[jobidx], &q); if (!q.count) - return; + { + queue_free(&q); + return; + } + /* now remove everything from q that is disabled by other jobs */ + + /* first remove cleandeps packages, they count as DISABLE_UPDATE */ + if (solv->cleandepsmap.size) + { + solver_createcleandepsmap(solv, &solv->cleandepsmap, 0); + for (j = k = 0; j < q.count; j += 2) + { + if (q.elements[j] == DISABLE_UPDATE) + { + Id p = q.elements[j + 1]; + if (p >= solv->installed->start && p < solv->installed->end && MAPTST(&solv->cleandepsmap, p - solv->installed->start)) + continue; /* remove element from q */ + } + q.elements[k++] = q.elements[j]; + q.elements[k++] = q.elements[j + 1]; + } + q.count = k; + if (!q.count) + { + queue_free(&q); + return; + } + } + + /* now go through the disable list of all other jobs */ + queue_init_buffer(&allq, allqbuf, sizeof(allqbuf)/sizeof(*allqbuf)); for (i = solv->jobrules; i < solv->jobrules_end; i++) { r = solv->rules + i; @@ -1843,22 +1880,35 @@ solver_reenablepolicyrules(Solver *solv, int jobidx) continue; lastjob = j; jobtodisablelist(solv, job->elements[j], job->elements[j + 1], &allq); + if (!allq.count) + continue; + /* remove all elements in allq from q */ + for (j = k = 0; j < q.count; j += 2) + { + Id type = q.elements[j], arg = q.elements[j + 1]; + for (ai = 0; ai < allq.count; ai += 2) + if (allq.elements[ai] == type && allq.elements[ai + 1] == arg) + break; + if (ai < allq.count) + continue; /* found it in allq, remove element from q */ + q.elements[k++] = q.elements[j]; + q.elements[k++] = q.elements[j + 1]; + } + q.count = k; + if (!q.count) + { + queue_free(&q); + queue_free(&allq); + return; + } + queue_empty(&allq); } - if (solv->cleandepsmap.size) - { - solver_createcleandepsmap(solv, &solv->cleandepsmap, 0); - for (i = solv->installed->start; i < solv->installed->end; i++) - if (MAPTST(&solv->cleandepsmap, i - solv->installed->start)) - queue_push2(&allq, DISABLE_UPDATE, i); - } + queue_free(&allq); + + /* now re-enable anything that's left in q */ for (j = 0; j < q.count; j += 2) { Id type = q.elements[j], arg = q.elements[j + 1]; - for (i = 0; i < allq.count; i += 2) - if (allq.elements[i] == type && allq.elements[i + 1] == arg) - break; - if (i < allq.count) - continue; /* still disabled */ switch(type) { case DISABLE_UPDATE: @@ -1872,7 +1922,6 @@ solver_reenablepolicyrules(Solver *solv, int jobidx) break; } } - queue_free(&allq); queue_free(&q); } diff --git a/src/rules.h b/src/rules.h index 144b683..4d6b8ad 100644 --- a/src/rules.h +++ b/src/rules.h @@ -99,6 +99,7 @@ solver_enablerule(struct _Solver *solv, Rule *r) extern Rule *solver_addrule(struct _Solver *solv, Id p, Id d); extern void solver_unifyrules(struct _Solver *solv); extern int solver_rulecmp(struct _Solver *solv, Rule *r1, Rule *r2); +extern void solver_shrinkrules(struct _Solver *solv, int nrules); /* rpm rules */ extern void solver_addrpmrulesforsolvable(struct _Solver *solv, Solvable *s, Map *m); diff --git a/src/selection.c b/src/selection.c index 2ef5e1e..c586a2c 100644 --- a/src/selection.c +++ b/src/selection.c @@ -121,7 +121,7 @@ selection_flatten(Pool *pool, Queue *selection) { Queue q; int i; - if (selection->count <= 1) + if (selection->count <= 2) return; for (i = 0; i < selection->count; i += 2) if ((selection->elements[i] & SOLVER_SELECTMASK) == SOLVER_SOLVABLE_ALL) @@ -155,6 +155,7 @@ static void selection_filter_rel(Pool *pool, Queue *selection, Id relflags, Id relevr) { int i; + for (i = 0; i < selection->count; i += 2) { Id select = selection->elements[i] & SOLVER_SELECTMASK; @@ -196,7 +197,7 @@ selection_filter_rel(Pool *pool, Queue *selection, Id relflags, Id relevr) } queue_free(&q); } - else if (select == SOLVER_SOLVABLE_NAME && select == SOLVER_SOLVABLE_PROVIDES) + else if (select == SOLVER_SOLVABLE_NAME || select == SOLVER_SOLVABLE_PROVIDES) { /* don't stack src reldeps */ if (relflags == REL_ARCH && (relevr == ARCH_SRC || relevr == ARCH_NOSRC) && ISRELDEP(id)) @@ -245,7 +246,11 @@ selection_addsrc(Pool *pool, Queue *selection, int flags) if (s->name != name) continue; if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC) - havesrc = 1; + { + if (pool_disabled_solvable(pool, s)) + continue; + havesrc = 1; + } else if (s->repo != pool->installed && !pool_installable(pool, s)) continue; queue_push(&q, p); @@ -316,6 +321,8 @@ 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 */ + if (pool_disabled_solvable(pool, s)) + continue; if ((flags & SELECTION_SOURCE_ONLY) != 0) id = pool_rel2id(pool, id, ARCH_SRC, REL_ARCH, 1); queue_push2(selection, SOLVER_SOLVABLE_NAME, id); @@ -377,8 +384,12 @@ selection_depglob(Pool *pool, Queue *selection, const char *name, int flags) { Solvable *s = pool->solvables + p; if (s->repo != pool->installed && !pool_installable(pool, s)) - if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)) - continue; + { + if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)) + continue; + if (pool_disabled_solvable(pool, s)) + continue; + } if ((flags & SELECTION_INSTALLED_ONLY) != 0 && s->repo != pool->installed) continue; id = s->name; @@ -476,8 +487,12 @@ selection_filelist(Pool *pool, Queue *selection, const char *name, int flags) if (!s->repo) continue; if (s->repo != pool->installed && !pool_installable(pool, s)) - if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)) - continue; + { + if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)) + continue; + if (pool_disabled_solvable(pool, s)) + continue; + } if ((flags & SELECTION_INSTALLED_ONLY) != 0 && s->repo != pool->installed) continue; queue_push(&q, di.solvid); @@ -722,7 +737,8 @@ selection_make(Pool *pool, Queue *selection, const char *name, int flags) ret = selection_depglob_arch(pool, selection, name, flags); if (!ret && (flags & SELECTION_CANON) != 0) ret = selection_canon(pool, selection, name, flags); - + if (ret && !selection->count) + ret = 0; /* no match -> always return zero */ if (ret && (flags & SELECTION_FLAT) != 0) selection_flatten(pool, selection); return ret; diff --git a/src/solvable.c b/src/solvable.c index 4594544..7ac79ee 100644 --- a/src/solvable.c +++ b/src/solvable.c @@ -462,7 +462,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm { if (providedbyinstalled(pool, installedmap, con, ispatch, noobsoletesmap)) { - if (ispatch && solvable_is_irrelevant_patch(s, installedmap, 0)) + if (ispatch && solvable_is_irrelevant_patch(s, installedmap)) return -1; return 0; } @@ -473,7 +473,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm interesting = 1; } } - if (ispatch && interesting && solvable_is_irrelevant_patch(s, installedmap, 0)) + if (ispatch && interesting && solvable_is_irrelevant_patch(s, installedmap)) interesting = 0; } #if 0 @@ -575,11 +575,33 @@ solvable_trivial_installable_repo(Solvable *s, Repo *installed, Map *noobsoletes return r; } +/* FIXME: this mirrors policy_illegal_vendorchange */ +static int +pool_illegal_vendorchange(Pool *pool, Solvable *s1, Solvable *s2) +{ + Id v1, v2; + Id vendormask1, vendormask2; + + if (pool->custom_vendorcheck) + return pool->custom_vendorcheck(pool, s1, s2); + /* treat a missing vendor as empty string */ + v1 = s1->vendor ? s1->vendor : ID_EMPTY; + v2 = s2->vendor ? s2->vendor : ID_EMPTY; + if (v1 == v2) + return 0; + vendormask1 = pool_vendor2mask(pool, v1); + if (!vendormask1) + return 1; /* can't match */ + vendormask2 = pool_vendor2mask(pool, v2); + if ((vendormask1 & vendormask2) != 0) + return 0; + return 1; /* no class matches */ +} /* check if this patch is relevant according to the vendor. To bad that patches * don't have a vendor, so we need to do some careful repo testing. */ int -solvable_is_irrelevant_patch(Solvable *s, Map *installedmap, Solver *solv) +solvable_is_irrelevant_patch(Solvable *s, Map *installedmap) { Pool *pool = s->repo->pool; Id con, *conp; @@ -618,23 +640,8 @@ solvable_is_irrelevant_patch(Solvable *s, Map *installedmap, Solver *solv) /* ok, we have a package from the patch repo that solves the conflict. check vendor */ if (si->vendor == s2->vendor) return 0; - /* FIXME: solv is only needed for the vendorchange callback */ - if (solv) - { - if (!policy_illegal_vendorchange(solv, si, s2)) - return 0; - } - else - { - Id v1 = si->vendor ? si->vendor : ID_EMPTY; - Id v2 = s2->vendor ? s2->vendor : ID_EMPTY; - if (v1 == v2) - return 0; - v1 = pool_vendor2mask(pool, v1); - v2 = pool_vendor2mask(pool, v2); - if ((v1 & v2) != 0) - return 0; - } + if (!pool_illegal_vendorchange(pool, si, s2)) + return 0; /* vendor change was illegal, ignore conflict */ } } diff --git a/src/solver.c b/src/solver.c index 43668d5..c1518db 100644 --- a/src/solver.c +++ b/src/solver.c @@ -965,11 +965,11 @@ solver_reset(Solver *solv) v = solv->decisionq.elements[i]; solv->decisionmap[v > 0 ? v : -v] = 0; } - solv->decisionq_why.count = 0; - solv->decisionq.count = 0; + queue_empty(&solv->decisionq_why); + queue_empty(&solv->decisionq); solv->recommends_index = -1; solv->propagate_index = 0; - solv->branches.count = 0; + queue_empty(&solv->branches); /* adapt learnt rule status to new set of enabled/disabled rules */ enabledisablelearntrules(solv); @@ -1436,6 +1436,7 @@ solver_create(Pool *pool) queue_init(&solv->branches); queue_init(&solv->weakruleq); queue_init(&solv->ruleassertions); + queue_init(&solv->addedmap_deduceq); queue_push(&solv->learnt_pool, 0); /* so that 0 does not describe a proof */ @@ -1473,6 +1474,7 @@ solver_free(Solver *solv) queue_free(&solv->branches); queue_free(&solv->weakruleq); queue_free(&solv->ruleassertions); + queue_free(&solv->addedmap_deduceq); if (solv->cleandeps_updatepkgs) { queue_free(solv->cleandeps_updatepkgs); @@ -2831,6 +2833,74 @@ transform_update_targets(Solver *solv) } +static void +addedmap2deduceq(Solver *solv, Map *addedmap) +{ + Pool *pool = solv->pool; + int i, j; + Id p; + Rule *r; + + queue_empty(&solv->addedmap_deduceq); + for (i = 2, j = solv->rpmrules_end - 1; i < pool->nsolvables && j > 0; j--) + { + r = solv->rules + j; + if (r->p >= 0) + continue; + if ((r->d == 0 || r->d == -1) && r->w2 < 0) + continue; + p = -r->p; + if (!MAPTST(addedmap, p)) + { + /* should never happen, but... */ + if (!solv->addedmap_deduceq.count || solv->addedmap_deduceq.elements[solv->addedmap_deduceq.count - 1] != -p) + queue_push(&solv->addedmap_deduceq, -p); + continue; + } + for (; i < p; i++) + if (MAPTST(addedmap, i)) + queue_push(&solv->addedmap_deduceq, i); + if (i == p) + i++; + } + for (; i < pool->nsolvables; i++) + if (MAPTST(addedmap, i)) + queue_push(&solv->addedmap_deduceq, i); + j = 0; + for (i = 2; i < pool->nsolvables; i++) + if (MAPTST(addedmap, i)) + j++; +} + +static void +deduceq2addedmap(Solver *solv, Map *addedmap) +{ + int j; + Id p; + Rule *r; + for (j = solv->rpmrules_end - 1; j > 0; j--) + { + r = solv->rules + j; + if (r->d < 0 && r->p) + solver_enablerule(solv, r); + if (r->p >= 0) + continue; + if ((r->d == 0 || r->d == -1) && r->w2 < 0) + continue; + p = -r->p; + MAPSET(addedmap, p); + } + for (j = 0; j < solv->addedmap_deduceq.count; j++) + { + p = solv->addedmap_deduceq.elements[j]; + if (p > 0) + MAPSET(addedmap, p); + else + MAPCLR(addedmap, p); + } +} + + /* * * solve job queue @@ -2843,7 +2913,7 @@ solver_solve(Solver *solv, Queue *job) Pool *pool = solv->pool; Repo *installed = solv->installed; int i; - int oldnrules; + int oldnrules, initialnrules; Map addedmap; /* '1' == have rpm-rules for solvable */ Map installcandidatemap; Id how, what, select, name, weak, p, pp, d; @@ -2893,6 +2963,81 @@ solver_solve(Solver *solv, Queue *job) queue_free(solv->cleandeps_updatepkgs); solv->cleandeps_updatepkgs = solv_free(solv->cleandeps_updatepkgs); } + queue_empty(&solv->ruleassertions); + solv->bestrules_pkg = solv_free(solv->bestrules_pkg); + solv->choicerules_ref = solv_free(solv->choicerules_ref); + if (solv->noupdate.size) + map_empty(&solv->noupdate); + if (solv->noobsoletes.size) + { + map_free(&solv->noobsoletes); + map_init(&solv->noobsoletes, 0); + } + solv->updatemap_all = 0; + if (solv->updatemap.size) + { + map_free(&solv->updatemap); + map_init(&solv->updatemap, 0); + } + solv->bestupdatemap_all = 0; + if (solv->bestupdatemap.size) + { + map_free(&solv->bestupdatemap); + map_init(&solv->bestupdatemap, 0); + } + solv->fixmap_all = 0; + if (solv->fixmap.size) + { + map_free(&solv->fixmap); + map_init(&solv->fixmap, 0); + } + solv->dupmap_all = 0; + if (solv->dupmap.size) + { + map_free(&solv->dupmap); + map_init(&solv->dupmap, 0); + } + if (solv->dupinvolvedmap.size) + { + map_free(&solv->dupinvolvedmap); + map_init(&solv->dupinvolvedmap, 0); + } + solv->droporphanedmap_all = 0; + if (solv->droporphanedmap.size) + { + map_free(&solv->droporphanedmap); + map_init(&solv->droporphanedmap, 0); + } + if (solv->cleandepsmap.size) + { + map_free(&solv->cleandepsmap); + map_init(&solv->cleandepsmap, 0); + } + + queue_empty(&solv->weakruleq); + solv->watches = solv_free(solv->watches); + queue_empty(&solv->ruletojob); + if (solv->decisionq.count) + memset(solv->decisionmap, 0, pool->nsolvables * sizeof(Id)); + queue_empty(&solv->decisionq); + queue_empty(&solv->decisionq_why); + solv->decisioncnt_update = solv->decisioncnt_keep = solv->decisioncnt_resolve = solv->decisioncnt_weak = solv->decisioncnt_orphan = 0; + queue_empty(&solv->learnt_why); + queue_empty(&solv->learnt_pool); + queue_empty(&solv->branches); + solv->propagate_index = 0; + queue_empty(&solv->problems); + queue_empty(&solv->solutions); + queue_empty(&solv->orphaned); + solv->stats_learned = solv->stats_unsolvable = 0; + if (solv->recommends_index) + { + map_empty(&solv->recommendsmap); + map_empty(&solv->suggestsmap); + solv->recommends_index = 0; + } + solv->multiversionupdaters = solv_free(solv->multiversionupdaters); + /* * create basic rule set of all involved packages @@ -2914,6 +3059,14 @@ solver_solve(Solver *solv, Queue *job) * so called: rpm rules * */ + initialnrules = solv->rpmrules_end ? solv->rpmrules_end : 1; + if (initialnrules > 1) + deduceq2addedmap(solv, &addedmap); + if (solv->nrules != initialnrules) + solver_shrinkrules(solv, initialnrules); + solv->nrules = initialnrules; + solv->rpmrules_end = 0; + if (installed) { /* check for update/verify jobs as they need to be known early */ @@ -3087,8 +3240,12 @@ solver_solve(Solver *solv, Queue *job) POOL_DEBUG(SOLV_DEBUG_STATS, "%d of %d installable solvables considered for solving\n", possible, installable); } - solver_unifyrules(solv); /* remove duplicate rpm rules */ - solv->rpmrules_end = solv->nrules; /* mark end of rpm rules */ + if (solv->nrules > initialnrules) + solver_unifyrules(solv); /* remove duplicate rpm rules */ + solv->rpmrules_end = solv->nrules; /* mark end of rpm rules */ + + if (solv->nrules > initialnrules) + addedmap2deduceq(solv, &addedmap); /* so that we can recreate the addedmap */ POOL_DEBUG(SOLV_DEBUG_STATS, "rpm rule memory used: %d K\n", solv->nrules * (int)sizeof(Rule) / 1024); POOL_DEBUG(SOLV_DEBUG_STATS, "rpm rule creation took %d ms\n", solv_timems(now)); @@ -3754,7 +3911,7 @@ solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res) if (res->elements[i] != -1) { Solvable *s = pool->solvables + pkgs->elements[i]; - if (!strncmp("patch:", pool_id2str(pool, s->name), 6) && solvable_is_irrelevant_patch(s, &installedmap, solv)) + if (!strncmp("patch:", pool_id2str(pool, s->name), 6) && solvable_is_irrelevant_patch(s, &installedmap)) res->elements[i] = -1; } map_free(&installedmap); diff --git a/src/solver.h b/src/solver.h index a134718..b735329 100644 --- a/src/solver.h +++ b/src/solver.h @@ -26,15 +26,6 @@ extern "C" { #include "rules.h" #include "problems.h" -/* - * Callback definitions in order to "overwrite" the policies by an external application. - */ - -typedef void (*BestSolvableCb) (Pool *pool, Queue *canditates); -typedef int (*ArchCheckCb) (Pool *pool, Solvable *solvable1, Solvable *solvable2); -typedef int (*VendorCheckCb) (Pool *pool, Solvable *solvable1, Solvable *solvable2); -typedef void (*UpdateCandidateCb) (Pool *pool, Solvable *solvable, Queue *canditates); - struct _Solver { Pool *pool; /* back pointer to pool */ @@ -43,46 +34,7 @@ struct _Solver { int (*solution_callback)(struct _Solver *solv, void *data); void *solution_callback_data; - /* Callbacks for defining the bahaviour of the solver */ - - /* Finding best candidate - * - * Callback definition: - * void bestSolvable (Pool *pool, Queue *canditates) - * candidates : List of canditates which has to be sorted by the function call - * return candidates: Sorted list of the candidates(first is the best). - */ - BestSolvableCb bestSolvableCb; - - /* Checking if two solvables has compatible architectures - * - * Callback definition: - * int archCheck (Pool *pool, Solvable *solvable1, Solvable *solvable2); - * - * return 0 it the two solvables has compatible architectures - */ - ArchCheckCb archCheckCb; - - /* Checking if two solvables has compatible vendors - * - * Callback definition: - * int vendorCheck (Pool *pool, Solvable *solvable1, Solvable *solvable2); - * - * return 0 it the two solvables has compatible architectures - */ - VendorCheckCb vendorCheckCb; - - /* Evaluate update candidate - * - * Callback definition: - * void UpdateCandidateCb (Pool *pool, Solvable *solvable, Queue *canditates) - * solvable : for which updates should be search - * candidates : List of candidates (This list depends on other - * restrictions like architecture and vendor policies too) - */ - UpdateCandidateCb updateCandidateCb; - - int pooljobcnt; /* number of pooljob entries in job queue */ + int pooljobcnt; /* number of pooljob entries in job queue */ #ifdef LIBSOLV_INTERNAL Repo *installed; /* copy of pool->installed */ @@ -229,6 +181,8 @@ struct _Solver { Queue *update_targets; /* update to specific packages */ Queue *installsuppdepq; /* deps from the install namespace provides hack */ + + Queue addedmap_deduceq; /* deduce addedmap from rpm rules */ #endif /* LIBSOLV_INTERNAL */ }; diff --git a/tools/common_write.c b/tools/common_write.c index 75c75b5..6de8a69 100644 --- a/tools/common_write.c +++ b/tools/common_write.c @@ -27,6 +27,8 @@ static Id verticals[] = { SOLVABLE_EULA, SOLVABLE_DISKUSAGE, SOLVABLE_FILELIST, + SOLVABLE_CHANGELOG_AUTHOR, + SOLVABLE_CHANGELOG_TEXT, 0 }; diff --git a/tools/installcheck.c b/tools/installcheck.c index 4859bc2..a0513ea 100644 --- a/tools/installcheck.c +++ b/tools/installcheck.c @@ -250,10 +250,11 @@ main(int argc, char **argv) } } + solv = solver_create(pool); + /* prune cand by doing weak installs */ while (cand.count) { - solv = solver_create(pool); queue_empty(&job); for (i = 0; i < cand.count; i++) { @@ -326,7 +327,6 @@ main(int argc, char **argv) continue; } s = pool->solvables + p; - solv = solver_create(pool); queue_empty(&job); queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE); queue_push(&job, p); @@ -442,7 +442,7 @@ main(int argc, char **argv) } } #endif - solver_free(solv); } + solver_free(solv); exit(status); } -- cgit v1.2.3