From 01ec60f718c388f620598c39bdc0816a0dbe09ac Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Tue, 18 Jun 2013 08:03:40 +0300 Subject: errors: improve analysis for virtual packages if all packages named N provide the virtual package, list only the name N instead of all packages providing it. --- src/commit.c | 35 ++++++++++++++++++++++++----------- src/solver.c | 10 ++++------ test/provides.repo | 6 ++++++ test/provides2.test | 2 +- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/commit.c b/src/commit.c index 6279e53..01ac4a8 100644 --- a/src/commit.c +++ b/src/commit.c @@ -334,9 +334,9 @@ all_done: } enum { - STATE_UNSET = 0, - STATE_PRESENT, - STATE_MISSING + STATE_PRESENT = 0x80000000, + STATE_MISSING = 0x40000000, + STATE_COUNT_MASK = 0x0000ffff, }; struct print_state { @@ -460,16 +460,27 @@ static void analyze_name(struct print_state *ps, struct apk_name *name) struct apk_provider *p0; struct apk_dependency *d0; char tmp[256]; + int refs; if (name->providers->num) { snprintf(tmp, sizeof(tmp), "%s (virtual)", name->name); ps->label = tmp; label_start(ps, "provided by:"); + foreach_array_item(p0, name->providers) + p0->pkg->name->state_int++; foreach_array_item(p0, name->providers) { - /* FIXME: print only name if all pkgs provide it */ - struct apk_package *pkg = p0->pkg; - apk_print_indented_fmt(&ps->i, PKG_VER_FMT, PKG_VER_PRINTF(pkg)); + name0 = p0->pkg->name; + refs = (name0->state_int & STATE_COUNT_MASK); + if (refs == name0->providers->num) { + /* name only */ + apk_print_indented(&ps->i, APK_BLOB_STR(name0->name)); + name0->state_int &= ~STATE_COUNT_MASK; + } else if (refs > 0) { + /* individual package */ + apk_print_indented_fmt(&ps->i, PKG_VER_FMT, PKG_VER_PRINTF(p0->pkg)); + name0->state_int--; + } } label_end(ps); } else { @@ -508,12 +519,14 @@ static void analyze_name(struct print_state *ps, struct apk_name *name) static void analyze_deps(struct print_state *ps, struct apk_dependency_array *deps) { struct apk_dependency *d0; + struct apk_name *name0; foreach_array_item(d0, deps) { - if (d0->name->state_int != STATE_UNSET) + name0 = d0->name; + if ((name0->state_int & (STATE_PRESENT | STATE_MISSING)) != 0) continue; - d0->name->state_int = STATE_MISSING; - analyze_name(ps, d0->name); + name0->state_int |= STATE_MISSING; + analyze_name(ps, name0); } } @@ -570,9 +583,9 @@ void apk_solver_print_errors(struct apk_database *db, if (pkg == NULL) continue; pkg->marked = 1; - pkg->name->state_int = STATE_PRESENT; + pkg->name->state_int |= STATE_PRESENT; foreach_array_item(p, pkg->provides) - p->name->state_int = STATE_PRESENT; + p->name->state_int |= STATE_PRESENT; } /* Analyze is package, and missing names referred to */ diff --git a/src/solver.c b/src/solver.c index 279d1f6..b1a078c 100644 --- a/src/solver.c +++ b/src/solver.c @@ -529,10 +529,14 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name) if (name->ss.requirers || name->ss.has_iif) { foreach_array_item(p, name->providers) { + /* Ensure valid pinning and install-if trigger */ if (name->ss.requirers == 0 && (!p->pkg->ss.iif_triggered || !p->pkg->ss.tag_ok)) continue; + /* Virtual packages cannot be autoselected */ + if (p->version == &apk_null_blob && p->pkg->name->ss.requirers == 0) + continue; if (compare_providers(ss, p, &chosen) > 0) chosen = *p; } @@ -540,12 +544,6 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name) pkg = chosen.pkg; if (pkg) { - if (chosen.version == &apk_null_blob) { - /* Pure virtual package */ - assign_name(ss, name, provider_none); - ss->errors += (name->ss.requirers > 0); - return; - } if (!pkg->ss.available || !pkg->ss.tag_ok) { /* Selecting broken or unallowed package */ mark_error(ss, pkg); diff --git a/test/provides.repo b/test/provides.repo index a3dfec4..6418f18 100644 --- a/test/provides.repo +++ b/test/provides.repo @@ -26,6 +26,12 @@ S:1 I:1 D:so:foo.so.2 +C:Q1EyN5AdpAOBJWKMR89ppC66EEEEj= +P:mymailreader +V:0.1 +S:1 +I:1 + C:Q1EyN5AdpAOBJWKMR89pp/C66FFFF= P:mymailreader V:1 diff --git a/test/provides2.test b/test/provides2.test index 9d3a2e4..37fc9d8 100644 --- a/test/provides2.test +++ b/test/provides2.test @@ -4,5 +4,5 @@ add mail-reader @EXPECT ERROR: unsatisfiable constraints: mail-reader (virtual): - provided by: mymailreader-1 mailreadplus-1 + provided by: mymailreader-1 mailreadplus required by: world[mail-reader] -- cgit v1.2.3-70-g09d2