summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2013-04-11 09:58:42 -0700
committerAnas Nashif <anas.nashif@intel.com>2013-04-11 09:58:42 -0700
commit524f855df0f94933f1078098800c0a93a7f8e86e (patch)
tree57d0a22bddda2e6684160069ca8609198863c7de
parentda5983eb19fa9aa677fde925fdbd8e6d1f8f000a (diff)
downloadlibsolv-524f855df0f94933f1078098800c0a93a7f8e86e.tar.gz
libsolv-524f855df0f94933f1078098800c0a93a7f8e86e.tar.bz2
libsolv-524f855df0f94933f1078098800c0a93a7f8e86e.zip
merged 0.3.0
-rw-r--r--VERSION.cmake4
-rw-r--r--bindings/solv.i1
-rwxr-xr-xexamples/p5solv8
-rwxr-xr-xexamples/pysolv12
-rwxr-xr-xexamples/rbsolv8
-rw-r--r--examples/solv.c16
-rw-r--r--ext/repo_arch.c7
-rw-r--r--ext/repo_helix.c2
-rw-r--r--ext/repo_rpmdb.c75
-rw-r--r--ext/repo_rpmdb.h1
-rw-r--r--ext/repo_rpmmd.c23
-rw-r--r--ext/testcase.c206
-rw-r--r--package/libsolv.changes9
-rw-r--r--src/dataiterator.h11
-rw-r--r--src/knownid.h24
-rw-r--r--src/libsolv.ver2
-rw-r--r--src/policy.c24
-rw-r--r--src/pool.c47
-rw-r--r--src/pool.h6
-rw-r--r--src/repo.h13
-rw-r--r--src/repo_write.c2
-rw-r--r--src/repodata.c126
-rw-r--r--src/repodata.h1
-rw-r--r--src/repopack.h4
-rw-r--r--src/rules.c95
-rw-r--r--src/rules.h1
-rw-r--r--src/selection.c32
-rw-r--r--src/solvable.c47
-rw-r--r--src/solver.c171
-rw-r--r--src/solver.h52
-rw-r--r--tools/common_write.c2
-rw-r--r--tools/installcheck.c6
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], "<inline>"))
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,4 +1,13 @@
-------------------------------------------------------------------
+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
- trivial_installable: check vendor of affected package to see if
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);
}