all: introduce apk_provides and use it in apk_name
in preparation for provides support. implements also some dependency satisfaction helper routines. ref #574.cute-signatures
parent
97d44b5a00
commit
99145e2c0d
|
@ -78,6 +78,15 @@ struct apk_db_dir_instance {
|
|||
gid_t gid;
|
||||
};
|
||||
|
||||
#define PROVIDER_FMT "%s-"BLOB_FMT
|
||||
#define PROVIDER_PRINTF(p) (p)->pkg->name->name, BLOB_PRINTF(*(p)->version)
|
||||
|
||||
struct apk_provider {
|
||||
struct apk_package *pkg;
|
||||
apk_blob_t *version;
|
||||
};
|
||||
APK_ARRAY(apk_provider_array, struct apk_provider);
|
||||
|
||||
struct apk_name {
|
||||
apk_hash_node hash_node;
|
||||
union {
|
||||
|
@ -85,7 +94,7 @@ struct apk_name {
|
|||
void *state_ptr;
|
||||
};
|
||||
char *name;
|
||||
struct apk_package_array *pkgs;
|
||||
struct apk_provider_array *providers;
|
||||
struct apk_name_array *rdepends;
|
||||
struct apk_name_array *rinstall_if;
|
||||
};
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
struct apk_database;
|
||||
struct apk_name;
|
||||
struct apk_provider;
|
||||
|
||||
#define APK_SCRIPT_INVALID -1
|
||||
#define APK_SCRIPT_PRE_INSTALL 0
|
||||
|
@ -103,6 +104,9 @@ struct apk_package {
|
|||
};
|
||||
APK_ARRAY(apk_package_array, struct apk_package *);
|
||||
|
||||
#define APK_PROVIDER_FROM_PACKAGE(pkg) (struct apk_provider){(pkg),(pkg)->version}
|
||||
#define APK_PROVIDER_FROM_PROVIDES(pkg,p) (struct apk_provider){(pkg),(p)->version}
|
||||
|
||||
#define PKG_VER_FMT "%s-" BLOB_FMT
|
||||
#define PKG_VER_PRINTF(pkg) pkg->name->name, BLOB_PRINTF(*pkg->version)
|
||||
|
||||
|
@ -121,7 +125,9 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t blob);
|
|||
|
||||
void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db,
|
||||
struct apk_package *pkg);
|
||||
int apk_dep_is_satisfied(struct apk_dependency *dep, struct apk_package *pkg);
|
||||
int apk_dep_is_materialized(struct apk_dependency *dep, struct apk_package *pkg);
|
||||
int apk_dep_is_materialized_or_provided(struct apk_dependency *dep, struct apk_package *pkg);
|
||||
int apk_dep_is_provided(struct apk_dependency *dep, struct apk_provider *p);
|
||||
|
||||
void apk_blob_push_dep(apk_blob_t *to, struct apk_database *, struct apk_dependency *dep);
|
||||
void apk_blob_push_deps(apk_blob_t *to, struct apk_database *, struct apk_dependency_array *deps);
|
||||
|
@ -137,6 +143,8 @@ void apk_deps_del(struct apk_dependency_array **deps,
|
|||
struct apk_name *name);
|
||||
int apk_script_type(const char *name);
|
||||
|
||||
struct apk_package *apk_pkg_get_installed(struct apk_name *name);
|
||||
|
||||
void apk_pkg_format_plain(struct apk_package *pkg, apk_blob_t to);
|
||||
void apk_pkg_format_cache(struct apk_package *pkg, apk_blob_t to);
|
||||
struct apk_package *apk_pkg_new(void);
|
||||
|
|
|
@ -99,7 +99,7 @@ static apk_blob_t pkg_name_get_key(apk_hash_item item)
|
|||
static void pkg_name_free(struct apk_name *name)
|
||||
{
|
||||
free(name->name);
|
||||
apk_package_array_free(&name->pkgs);
|
||||
apk_provider_array_free(&name->providers);
|
||||
apk_name_array_free(&name->rdepends);
|
||||
apk_name_array_free(&name->rinstall_if);
|
||||
free(name);
|
||||
|
@ -211,7 +211,7 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name)
|
|||
return NULL;
|
||||
|
||||
pn->name = apk_blob_cstr(name);
|
||||
apk_package_array_init(&pn->pkgs);
|
||||
apk_provider_array_init(&pn->providers);
|
||||
apk_name_array_init(&pn->rdepends);
|
||||
apk_name_array_init(&pn->rinstall_if);
|
||||
apk_hash_insert_hashed(&db->available.names, pn, hash);
|
||||
|
@ -529,7 +529,8 @@ struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *
|
|||
if (idb == NULL) {
|
||||
idb = pkg;
|
||||
apk_hash_insert(&db->available.packages, pkg);
|
||||
*apk_package_array_add(&pkg->name->pkgs) = pkg;
|
||||
*apk_provider_array_add(&pkg->name->providers) =
|
||||
APK_PROVIDER_FROM_PACKAGE(pkg);
|
||||
apk_db_pkg_rdepends(db, pkg);
|
||||
} else {
|
||||
idb->repos |= pkg->repos;
|
||||
|
@ -1761,8 +1762,12 @@ static int foreach_cache_file(void *pctx, int dirfd, const char *name)
|
|||
char tmp[PATH_MAX];
|
||||
if (name == NULL)
|
||||
goto no_pkg;
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
struct apk_package *pkg0 = name->pkgs->item[i];
|
||||
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
struct apk_package *pkg0 = name->providers->item[i].pkg;
|
||||
|
||||
if (pkg0->name != name)
|
||||
continue;
|
||||
|
||||
apk_pkg_format_cache(pkg0, APK_BLOB_BUF(tmp));
|
||||
if (apk_blob_compare(b, APK_BLOB_STR(tmp)) == 0) {
|
||||
|
@ -2226,14 +2231,14 @@ static int apk_db_install_archive_entry(void *_ctx,
|
|||
break;
|
||||
/* Does the original package replace the new one? */
|
||||
for (i = 0; i < opkg->ipkg->replaces->num; i++) {
|
||||
if (apk_dep_is_satisfied(&opkg->ipkg->replaces->item[i], pkg)) {
|
||||
if (apk_dep_is_materialized(&opkg->ipkg->replaces->item[i], pkg)) {
|
||||
opkg_prio = opkg->ipkg->replaces_priority;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Does the new package replace the original one? */
|
||||
for (i = 0; i < ctx->ipkg->replaces->num; i++) {
|
||||
if (apk_dep_is_satisfied(&ctx->ipkg->replaces->item[i], opkg)) {
|
||||
if (apk_dep_is_materialized(&ctx->ipkg->replaces->item[i], opkg)) {
|
||||
pkg_prio = ctx->ipkg->replaces_priority;
|
||||
break;
|
||||
}
|
||||
|
|
67
src/del.c
67
src/del.c
|
@ -15,6 +15,11 @@
|
|||
#include "apk_print.h"
|
||||
#include "apk_solver.h"
|
||||
|
||||
enum {
|
||||
INSTALLED_PACKAGES,
|
||||
MARKED_PACKAGES,
|
||||
};
|
||||
|
||||
struct del_ctx {
|
||||
int recursive_delete : 1;
|
||||
struct apk_dependency_array *world;
|
||||
|
@ -35,7 +40,7 @@ static int del_parse(void *pctx, struct apk_db_options *db,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void foreach_installed_reverse_dependency(
|
||||
static void foreach_package_reverse_dependency(
|
||||
struct apk_package *pkg,
|
||||
void (*cb)(struct apk_package *rdepend, void *ctx), void *ctx)
|
||||
{
|
||||
|
@ -46,19 +51,18 @@ static void foreach_installed_reverse_dependency(
|
|||
return;
|
||||
|
||||
name = pkg->name;
|
||||
for (i = 0; i < pkg->name->rdepends->num; i++) {
|
||||
struct apk_name *name0 = pkg->name->rdepends->item[i];
|
||||
for (i = 0; i < name->rdepends->num; i++) {
|
||||
struct apk_name *name0 = name->rdepends->item[i];
|
||||
|
||||
for (j = 0; j < name0->pkgs->num; j++) {
|
||||
struct apk_package *pkg0 = name0->pkgs->item[j];
|
||||
for (j = 0; j < name0->providers->num; j++) {
|
||||
struct apk_package *pkg0 = name0->providers->item[j].pkg;
|
||||
|
||||
if (pkg0->ipkg == NULL)
|
||||
continue;
|
||||
|
||||
for (k = 0; k < pkg0->depends->num; k++) {
|
||||
struct apk_dependency *dep = &pkg0->depends->item[k];
|
||||
if (dep->name == name &&
|
||||
apk_dep_is_satisfied(dep, pkg))
|
||||
if (apk_dep_is_materialized_or_provided(dep, pkg))
|
||||
break;
|
||||
}
|
||||
if (k >= pkg0->depends->num)
|
||||
|
@ -69,6 +73,24 @@ static void foreach_installed_reverse_dependency(
|
|||
}
|
||||
}
|
||||
|
||||
static void foreach_reverse_dependency(
|
||||
struct apk_name *name, int mode,
|
||||
void (*cb)(struct apk_package *rdepend, void *ctx), void *ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
struct apk_package *pkg0 = name->providers->item[i].pkg;
|
||||
|
||||
if (mode == INSTALLED_PACKAGES && pkg0->ipkg == NULL)
|
||||
continue;
|
||||
else if (mode == MARKED_PACKAGES && pkg0->state_int == 0)
|
||||
continue;
|
||||
|
||||
foreach_package_reverse_dependency(pkg0, cb, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
struct not_deleted_ctx {
|
||||
struct apk_indent indent;
|
||||
struct apk_package *pkg;
|
||||
|
@ -82,7 +104,6 @@ static void print_not_deleted_message(struct apk_package *pkg,
|
|||
|
||||
if (pkg == NULL)
|
||||
return;
|
||||
|
||||
if (pkg->state_ptr == ctx->pkg)
|
||||
return;
|
||||
pkg->state_ptr = ctx->pkg;
|
||||
|
@ -97,19 +118,7 @@ static void print_not_deleted_message(struct apk_package *pkg,
|
|||
}
|
||||
|
||||
apk_print_indented(&ctx->indent, APK_BLOB_STR(pkg->name->name));
|
||||
foreach_installed_reverse_dependency(pkg, print_not_deleted_message, pctx);
|
||||
}
|
||||
|
||||
static struct apk_package *name_to_pkg(struct apk_name *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
if (name->pkgs->item[i]->ipkg != NULL)
|
||||
return name->pkgs->item[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
foreach_package_reverse_dependency(pkg, print_not_deleted_message, pctx);
|
||||
}
|
||||
|
||||
static void delete_from_world(struct apk_package *pkg, void *pctx)
|
||||
|
@ -117,7 +126,7 @@ static void delete_from_world(struct apk_package *pkg, void *pctx)
|
|||
struct del_ctx *ctx = (struct del_ctx *) pctx;
|
||||
|
||||
apk_deps_del(&ctx->world, pkg->name);
|
||||
foreach_installed_reverse_dependency(pkg, delete_from_world, pctx);
|
||||
foreach_package_reverse_dependency(pkg, delete_from_world, pctx);
|
||||
}
|
||||
|
||||
static int del_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
||||
|
@ -136,9 +145,9 @@ static int del_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
|||
name[i] = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
|
||||
apk_deps_del(&ctx->world, name[i]);
|
||||
if (ctx->recursive_delete)
|
||||
foreach_installed_reverse_dependency(
|
||||
name_to_pkg(name[i]),
|
||||
delete_from_world, ctx);
|
||||
foreach_reverse_dependency(
|
||||
name[i], INSTALLED_PACKAGES,
|
||||
delete_from_world, ctx);
|
||||
}
|
||||
|
||||
r = apk_solver_solve(db, 0, ctx->world, &solution, &changeset);
|
||||
|
@ -147,14 +156,14 @@ static int del_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
|||
for (i = 0; i < solution->num; i++) {
|
||||
struct apk_package *pkg = solution->item[i].pkg;
|
||||
pkg->name->state_ptr = pkg;
|
||||
pkg->state_int = 0;
|
||||
pkg->state_int = 1;
|
||||
}
|
||||
for (i = 0; i < argc; i++) {
|
||||
ndctx.pkg = name[i]->state_ptr;
|
||||
ndctx.indent.indent = 0;
|
||||
foreach_installed_reverse_dependency(
|
||||
name[i]->state_ptr,
|
||||
print_not_deleted_message, &ndctx);
|
||||
foreach_reverse_dependency(
|
||||
name[i], MARKED_PACKAGES,
|
||||
print_not_deleted_message, &ndctx);
|
||||
if (ndctx.indent.indent)
|
||||
printf("\n");
|
||||
}
|
||||
|
|
26
src/dot.c
26
src/dot.c
|
@ -66,7 +66,7 @@ static int dump_pkg(struct dot_ctx *ctx, struct apk_package *pkg)
|
|||
struct apk_dependency *dep = &pkg->depends->item[i];
|
||||
struct apk_name *name = dep->name;
|
||||
|
||||
if (name->pkgs->num == 0) {
|
||||
if (name->providers->num == 0) {
|
||||
start_graph(ctx);
|
||||
printf(" \"" PKG_VER_FMT "\" -> \"%s\" [color=red];\n",
|
||||
PKG_VER_PRINTF(pkg),
|
||||
|
@ -77,19 +77,27 @@ static int dump_pkg(struct dot_ctx *ctx, struct apk_package *pkg)
|
|||
name->state_int = 1;
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < name->pkgs->num; j++) {
|
||||
struct apk_package *pkg0 = name->pkgs->item[j];
|
||||
for (j = 0; j < name->providers->num; j++) {
|
||||
struct apk_provider *p0 = &name->providers->item[j];
|
||||
|
||||
if (!apk_dep_is_satisfied(dep, pkg0))
|
||||
if (!apk_dep_is_provided(dep, p0))
|
||||
continue;
|
||||
|
||||
r = dump_pkg(ctx, pkg0);
|
||||
r = dump_pkg(ctx, p0->pkg);
|
||||
ret += r;
|
||||
if (r || (!ctx->errors_only)) {
|
||||
start_graph(ctx);
|
||||
printf(" \"" PKG_VER_FMT "\" -> \"" PKG_VER_FMT "\"%s;\n",
|
||||
|
||||
if (p0->pkg->name != dep->name) {
|
||||
/* provided package */
|
||||
printf(" \"" PROVIDER_FMT "\" -> \"" PKG_VER_FMT "\"[arrowhead=inv,color=green];\n",
|
||||
PROVIDER_PRINTF(p0),
|
||||
PKG_VER_PRINTF(p0->pkg));
|
||||
}
|
||||
|
||||
printf(" \"" PKG_VER_FMT "\" -> \"" PROVIDER_FMT "\"%s;\n",
|
||||
PKG_VER_PRINTF(pkg),
|
||||
PKG_VER_PRINTF(pkg0),
|
||||
PROVIDER_PRINTF(p0),
|
||||
r ? "[color=red]" : "");
|
||||
}
|
||||
}
|
||||
|
@ -117,8 +125,8 @@ static int dot_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
|||
struct apk_name *name = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
|
||||
if (!name)
|
||||
continue;
|
||||
for (j = 0; j < name->pkgs->num; j++)
|
||||
dump_pkg(ctx, name->pkgs->item[j]);
|
||||
for (j = 0; j < name->providers->num; j++)
|
||||
dump_pkg(ctx, name->providers->item[j].pkg);
|
||||
}
|
||||
} else {
|
||||
apk_hash_foreach(&db->available.packages, foreach_pkg, pctx);
|
||||
|
|
|
@ -202,12 +202,12 @@ static int fetch_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
|||
} else {
|
||||
struct apk_package *pkg = NULL;
|
||||
|
||||
for (j = 0; j < dep.name->pkgs->num; j++)
|
||||
for (j = 0; j < dep.name->providers->num; j++)
|
||||
if (pkg == NULL ||
|
||||
apk_pkg_version_compare(dep.name->pkgs->item[j],
|
||||
apk_pkg_version_compare(dep.name->providers->item[j].pkg,
|
||||
pkg)
|
||||
== APK_VERSION_GREATER)
|
||||
pkg = dep.name->pkgs->item[j];
|
||||
pkg = dep.name->providers->item[j].pkg;
|
||||
|
||||
if (pkg == NULL) {
|
||||
apk_message("Unable to get '%s'", dep.name->name);
|
||||
|
|
|
@ -59,7 +59,7 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
|||
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
|
||||
struct apk_name *name;
|
||||
struct apk_package *pkg;
|
||||
int r = 0, i, j;
|
||||
int r = 0, i;
|
||||
|
||||
if (!ctx->solver_flags)
|
||||
ctx->solver_flags = APK_SOLVERF_REINSTALL;
|
||||
|
@ -83,12 +83,7 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
|||
name = pkg->name;
|
||||
} else {
|
||||
name = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
|
||||
for (j = 0; j < name->pkgs->num; j++) {
|
||||
if (name->pkgs->item[j]->ipkg != NULL) {
|
||||
pkg = name->pkgs->item[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
pkg = apk_pkg_get_installed(name);
|
||||
}
|
||||
if (pkg == NULL || pkg->ipkg == NULL) {
|
||||
apk_error("%s is not installed", name->name);
|
||||
|
|
|
@ -72,7 +72,7 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx)
|
|||
struct counts *counts = (struct counts *) ctx;
|
||||
struct apk_name *name = (struct apk_name *) item;
|
||||
|
||||
if (name->pkgs->num == 0) {
|
||||
if (name->providers->num == 0) {
|
||||
if (++counts->unsatisfied < 10) {
|
||||
apk_warning("No provider for dependency '%s'",
|
||||
name->name);
|
||||
|
@ -143,8 +143,10 @@ static int index_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
|||
if (name == NULL)
|
||||
break;
|
||||
|
||||
for (j = 0; j < name->pkgs->num; j++) {
|
||||
pkg = name->pkgs->item[j];
|
||||
for (j = 0; j < name->providers->num; j++) {
|
||||
pkg = name->providers->item[j].pkg;
|
||||
if (pkg->name != name)
|
||||
continue;
|
||||
if (apk_blob_compare(bver, *pkg->version) != 0)
|
||||
continue;
|
||||
if (pkg->size != fi.size)
|
||||
|
|
77
src/info.c
77
src/info.c
|
@ -69,7 +69,6 @@ static int info_exists(struct info_ctx *ctx, struct apk_database *db,
|
|||
int argc, char **argv)
|
||||
{
|
||||
struct apk_name *name;
|
||||
struct apk_package *pkg = NULL;
|
||||
struct apk_dependency dep;
|
||||
int i, j, ok = 0;
|
||||
|
||||
|
@ -84,18 +83,14 @@ static int info_exists(struct info_ctx *ctx, struct apk_database *db,
|
|||
if (name == NULL)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < name->pkgs->num; j++) {
|
||||
pkg = name->pkgs->item[j];
|
||||
if (pkg->ipkg != NULL)
|
||||
break;
|
||||
for (j = 0; j < name->providers->num; j++) {
|
||||
struct apk_provider *p = &name->providers->item[j];
|
||||
if (p->pkg->ipkg == NULL)
|
||||
continue;
|
||||
if (!apk_dep_is_provided(&dep, p))
|
||||
continue;
|
||||
verbose_print_pkg(p->pkg, 0);
|
||||
}
|
||||
if (j >= name->pkgs->num)
|
||||
continue;
|
||||
|
||||
if (!apk_dep_is_satisfied(&dep, pkg))
|
||||
continue;
|
||||
|
||||
verbose_print_pkg(pkg, 0);
|
||||
ok++;
|
||||
}
|
||||
|
||||
|
@ -196,7 +191,7 @@ static void info_print_depends(struct apk_database *db, struct apk_package *pkg)
|
|||
|
||||
static void info_print_required_by(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
int i, j, k;
|
||||
int i, j;
|
||||
char *separator = apk_verbosity > 1 ? " " : "\n";
|
||||
|
||||
if (apk_verbosity == 1)
|
||||
|
@ -205,23 +200,23 @@ static void info_print_required_by(struct apk_database *db, struct apk_package *
|
|||
if (apk_verbosity > 1)
|
||||
printf("%s: ", pkg->name->name);
|
||||
for (i = 0; i < pkg->name->rdepends->num; i++) {
|
||||
struct apk_name *name0 = pkg->name->rdepends->item[i];
|
||||
struct apk_name *name0;
|
||||
struct apk_package *pkg0;
|
||||
|
||||
/* Check only the package that is installed, and that
|
||||
* it actually has this package as dependency. */
|
||||
for (j = 0; j < name0->pkgs->num; j++) {
|
||||
struct apk_package *pkg0 = name0->pkgs->item[j];
|
||||
name0 = pkg->name->rdepends->item[i];
|
||||
pkg0 = apk_pkg_get_installed(name0);
|
||||
if (pkg0 == NULL)
|
||||
continue;
|
||||
|
||||
if (pkg0->ipkg == NULL)
|
||||
for (j = 0; j < pkg0->depends->num; j++) {
|
||||
if (pkg0->depends->item[j].name != pkg->name)
|
||||
continue;
|
||||
for (k = 0; k < pkg0->depends->num; k++) {
|
||||
if (pkg0->depends->item[k].name != pkg->name)
|
||||
continue;
|
||||
printf(PKG_VER_FMT "%s",
|
||||
PKG_VER_PRINTF(pkg0),
|
||||
separator);
|
||||
break;
|
||||
}
|
||||
printf(PKG_VER_FMT "%s",
|
||||
PKG_VER_PRINTF(pkg0),
|
||||
separator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +243,7 @@ static void info_print_install_if(struct apk_database *db, struct apk_package *p
|
|||
|
||||
static void info_print_rinstall_if(struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
int i, j, k;
|
||||
int i, j;
|
||||
char *separator = apk_verbosity > 1 ? " " : "\n";
|
||||
|
||||
if (apk_verbosity == 1)
|
||||
|
@ -257,23 +252,23 @@ static void info_print_rinstall_if(struct apk_database *db, struct apk_package *
|
|||
if (apk_verbosity > 1)
|
||||
printf("%s: ", pkg->name->name);
|
||||
for (i = 0; i < pkg->name->rinstall_if->num; i++) {
|
||||
struct apk_name *name0 = pkg->name->rinstall_if->item[i];
|
||||
struct apk_name *name0;
|
||||
struct apk_package *pkg0;
|
||||
|
||||
/* Check only the package that is installed, and that
|
||||
* it actually has this package in install_if. */
|
||||
for (j = 0; j < name0->pkgs->num; j++) {
|
||||
struct apk_package *pkg0 = name0->pkgs->item[j];
|
||||
name0 = pkg->name->rinstall_if->item[i];
|
||||
pkg0 = apk_pkg_get_installed(name0);
|
||||
if (pkg0 == NULL)
|
||||
continue;
|
||||
|
||||
if (pkg0->ipkg == NULL)
|
||||
for (j = 0; j < pkg0->install_if->num; j++) {
|
||||
if (pkg0->install_if->item[j].name != pkg->name)
|
||||
continue;
|
||||
for (k = 0; k < pkg0->install_if->num; k++) {
|
||||
if (pkg0->install_if->item[k].name != pkg->name)
|
||||
continue;
|
||||
printf(PKG_VER_FMT "%s",
|
||||
PKG_VER_PRINTF(pkg0),
|
||||
separator);
|
||||
break;
|
||||
}
|
||||
printf(PKG_VER_FMT "%s",
|
||||
PKG_VER_PRINTF(pkg0),
|
||||
separator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,12 +371,12 @@ static int info_package(struct info_ctx *ctx, struct apk_database *db,
|
|||
|
||||
for (i = 0; i < argc; i++) {
|
||||
name = apk_db_query_name(db, APK_BLOB_STR(argv[i]));
|
||||
if (name == NULL || name->pkgs->num == 0) {
|
||||
if (name == NULL || name->providers->num == 0) {
|
||||
apk_error("Not found: %s", argv[i]);
|
||||
return 1;
|
||||
}
|
||||
for (j = 0; j < name->pkgs->num; j++)
|
||||
info_subaction(ctx, name->pkgs->item[j]);
|
||||
for (j = 0; j < name->providers->num; j++)
|
||||
info_subaction(ctx, name->providers->item[j].pkg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,21 @@ static const apk_spn_match_def apk_spn_dependency_separator = {
|
|||
[4] = (1<<0) /* */,
|
||||
};
|
||||
|
||||
struct apk_package *apk_pkg_get_installed(struct apk_name *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
struct apk_package *pkg = name->providers->item[i].pkg;
|
||||
if (pkg->name != name)
|
||||
continue;
|
||||
if (pkg->ipkg == NULL)
|
||||
continue;
|
||||
return pkg;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void apk_pkg_format_plain(struct apk_package *pkg, apk_blob_t to)
|
||||
{
|
||||
/* pkgname-1.0.apk */
|
||||
|
@ -311,7 +326,40 @@ void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db,
|
|||
};
|
||||
}
|
||||
|
||||
int apk_dep_is_satisfied(struct apk_dependency *dep, struct apk_package *pkg)
|
||||
static int apk_dep_match_checksum(struct apk_dependency *dep, struct apk_package *pkg)
|
||||
{
|
||||
struct apk_checksum csum;
|
||||
apk_blob_t b = *dep->version;
|
||||
|
||||
apk_blob_pull_csum(&b, &csum);
|
||||
if (apk_checksum_compare(&csum, &pkg->csum) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int apk_dep_is_provided(struct apk_dependency *dep, struct apk_provider *p)
|
||||
{
|
||||
if (p == NULL)
|
||||
return dep->optional;
|
||||
|
||||
switch (dep->result_mask) {
|
||||
case APK_DEPMASK_CHECKSUM:
|
||||
return apk_dep_match_checksum(dep, p->pkg);
|
||||
case APK_DEPMASK_CONFLICT:
|
||||
return 0;
|
||||
case APK_DEPMASK_REQUIRE:
|
||||
return 1;
|
||||
default:
|
||||
if (apk_version_compare_blob(*p->version, *dep->version)
|
||||
& dep->result_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int apk_dep_is_materialized(struct apk_dependency *dep, struct apk_package *pkg)
|
||||
{
|
||||
if (pkg == NULL)
|
||||
return dep->optional;
|
||||
|
@ -319,15 +367,8 @@ int apk_dep_is_satisfied(struct apk_dependency *dep, struct apk_package *pkg)
|
|||
return 0;
|
||||
|
||||
switch (dep->result_mask) {
|
||||
case APK_DEPMASK_CHECKSUM: {
|
||||
struct apk_checksum csum;
|
||||
apk_blob_t b = *dep->version;
|
||||
|
||||
apk_blob_pull_csum(&b, &csum);
|
||||
if (apk_checksum_compare(&csum, &pkg->csum) == 0)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
case APK_DEPMASK_CHECKSUM:
|
||||
return apk_dep_match_checksum(dep, pkg);
|
||||
case APK_DEPMASK_CONFLICT:
|
||||
return 0;
|
||||
case APK_DEPMASK_REQUIRE:
|
||||
|
@ -336,11 +377,33 @@ int apk_dep_is_satisfied(struct apk_dependency *dep, struct apk_package *pkg)
|
|||
if (apk_version_compare_blob(*pkg->version, *dep->version)
|
||||
& dep->result_mask)
|
||||
return 1;
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int apk_dep_is_materialized_or_provided(struct apk_dependency *dep, struct apk_package *pkg)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pkg == NULL)
|
||||
return dep->optional;
|
||||
|
||||
if (dep->name == pkg->name)
|
||||
return apk_dep_is_materialized(dep, pkg);
|
||||
|
||||
for (i = 0; i < pkg->provides->num; i++) {
|
||||
struct apk_provider p;
|
||||
|
||||
if (pkg->provides->item[i].name != dep->name)
|
||||
continue;
|
||||
p = APK_PROVIDER_FROM_PROVIDES(pkg, &pkg->provides->item[i]);
|
||||
return apk_dep_is_provided(dep, &p);
|
||||
}
|
||||
|
||||
return dep->optional;
|
||||
}
|
||||
|
||||
void apk_blob_push_dep(apk_blob_t *to, struct apk_database *db, struct apk_dependency *dep)
|
||||
{
|
||||
int result_mask = dep->result_mask;
|
||||
|
|
21
src/search.c
21
src/search.c
|
@ -59,12 +59,12 @@ static void print_rdepends(struct search_ctx *ctx, struct apk_package *pkg)
|
|||
printf(PKG_VER_FMT ":", PKG_VER_PRINTF(pkg));
|
||||
for (i = 0; i < name->rdepends->num; i++) {
|
||||
name0 = name->rdepends->item[i];
|
||||
for (j = 0; j < name0->pkgs->num; j++) {
|
||||
pkg0 = name0->pkgs->item[j];
|
||||
|
||||
for (j = 0; j < name0->providers->num; j++) {
|
||||
pkg0 = name0->providers->item[j].pkg;
|
||||
for (k = 0; k < pkg0->depends->num; k++) {
|
||||
dep = &pkg0->depends->item[k];
|
||||
if (name == dep->name &&
|
||||
apk_dep_is_satisfied(dep, pkg)) {
|
||||
if (apk_dep_is_materialized_or_provided(dep, pkg)) {
|
||||
printf(" ");
|
||||
ctx->print_package(ctx, pkg0);
|
||||
}
|
||||
|
@ -138,15 +138,16 @@ static int match_names(apk_hash_item item, void *ctx)
|
|||
}
|
||||
|
||||
if (ictx->show_all) {
|
||||
for (i = 0; i < name->pkgs->num; i++)
|
||||
print_result(ictx, name->pkgs->item[i]);
|
||||
for (i = 0; i < name->providers->num; i++)
|
||||
print_result(ictx, name->providers->item[i].pkg);
|
||||
} else {
|
||||
struct apk_package *pkg = NULL;
|
||||
apk_blob_t *version = NULL;
|
||||
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
if (pkg == NULL ||
|
||||
apk_pkg_version_compare(name->pkgs->item[i], pkg) == APK_VERSION_GREATER)
|
||||
pkg = name->pkgs->item[i];
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
if (version == NULL ||
|
||||
apk_version_compare_blob(*name->providers->item[i].version, *version) == APK_VERSION_GREATER)
|
||||
pkg = name->providers->item[i].pkg;
|
||||
}
|
||||
print_result(ictx, pkg);
|
||||
}
|
||||
|
|
152
src/solver.c
152
src/solver.c
|
@ -93,10 +93,12 @@ struct apk_package_state {
|
|||
unsigned locked : 1;
|
||||
};
|
||||
|
||||
#define CHOSEN_NONE (struct apk_provider) { .pkg = NULL, .version = NULL }
|
||||
|
||||
struct apk_name_state {
|
||||
struct list_head unsolved_list;
|
||||
struct apk_name *name;
|
||||
struct apk_package *chosen;
|
||||
struct apk_provider chosen;
|
||||
|
||||
struct apk_score minimum_penalty;
|
||||
unsigned short requirers;
|
||||
|
@ -244,8 +246,8 @@ static struct apk_name_state *name_to_ns_alloc(struct apk_name *name)
|
|||
if (name->state_ptr == NULL) {
|
||||
ns = calloc(1, sizeof(struct apk_name_state));
|
||||
ns->name = name;
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
if (name->pkgs->item[i]->repos != 0) {
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
if (name->providers->item[i].pkg->repos != 0) {
|
||||
ns->has_available_pkgs = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -282,14 +284,14 @@ static void foreach_dependency_pkg(
|
|||
struct apk_dependency *dep = &depends->item[i];
|
||||
struct apk_name *name0 = dep->name;
|
||||
|
||||
for (j = 0; j < name0->pkgs->num; j++) {
|
||||
struct apk_package *pkg0 = name0->pkgs->item[j];
|
||||
for (j = 0; j < name0->providers->num; j++) {
|
||||
struct apk_provider *p0 = &name0->providers->item[j];
|
||||
|
||||
/* conflict depends on all to be not installed */
|
||||
if (!apk_dep_is_satisfied(dep, pkg0))
|
||||
if (!apk_dep_is_provided(dep, p0))
|
||||
continue;
|
||||
|
||||
cb(ss, pkg0);
|
||||
cb(ss, p0->pkg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,20 +309,21 @@ static void foreach_rinstall_if_pkg(
|
|||
dbg_printf(PKG_VER_FMT ": rinstall_if %s\n",
|
||||
PKG_VER_PRINTF(pkg), name0->name);
|
||||
|
||||
for (j = 0; j < name0->pkgs->num; j++) {
|
||||
struct apk_package *pkg0 = name0->pkgs->item[j];
|
||||
for (j = 0; j < name0->providers->num; j++) {
|
||||
struct apk_provider *p0 = &name0->providers->item[j];
|
||||
|
||||
for (k = 0; k < p0->pkg->install_if->num; k++) {
|
||||
struct apk_dependency *dep = &p0->pkg->install_if->item[k];
|
||||
|
||||
for (k = 0; k < pkg0->install_if->num; k++) {
|
||||
struct apk_dependency *dep = &pkg0->install_if->item[k];
|
||||
if (dep->name == name &&
|
||||
apk_dep_is_satisfied(dep, pkg))
|
||||
apk_dep_is_provided(dep, p0))
|
||||
break;
|
||||
}
|
||||
if (k >= pkg0->install_if->num)
|
||||
if (k >= p0->pkg->install_if->num)
|
||||
continue;
|
||||
|
||||
/* pkg depends (via install_if) on pkg0 */
|
||||
cb(ss, pkg0);
|
||||
cb(ss, p0->pkg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -413,8 +416,8 @@ static int is_topology_optimum(struct apk_solver_state *ss,
|
|||
int i;
|
||||
|
||||
get_topology_score(ss, ns, pkg, &score);
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
struct apk_package *pkg0 = name->pkgs->item[i];
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
struct apk_package *pkg0 = name->providers->item[i].pkg;
|
||||
struct apk_package_state *ps0 = pkg_to_ps(pkg0);
|
||||
struct apk_score score0;
|
||||
|
||||
|
@ -434,9 +437,12 @@ static int is_topology_optimum(struct apk_solver_state *ss,
|
|||
}
|
||||
|
||||
static int compare_absolute_package_preference(
|
||||
struct apk_package *pkgA,
|
||||
struct apk_package *pkgB)
|
||||
struct apk_provider *pA,
|
||||
struct apk_provider *pB)
|
||||
{
|
||||
struct apk_package *pkgA = pA->pkg;
|
||||
struct apk_package *pkgB = pB->pkg;
|
||||
|
||||
/* specified on command line directly */
|
||||
if (pkgA->filename && !pkgB->filename)
|
||||
return 1;
|
||||
|
@ -445,7 +451,7 @@ static int compare_absolute_package_preference(
|
|||
|
||||
/* upgrading, or neither of the package is installed, so
|
||||
* we just fall back comparing to versions */
|
||||
switch (apk_pkg_version_compare(pkgA, pkgB)) {
|
||||
switch (apk_version_compare_blob(*pA->version, *pB->version)) {
|
||||
case APK_VERSION_GREATER:
|
||||
return 1;
|
||||
case APK_VERSION_LESS:
|
||||
|
@ -466,15 +472,17 @@ static void calculate_pkg_preference(struct apk_package *pkg)
|
|||
{
|
||||
struct apk_name *name = pkg->name;
|
||||
struct apk_package_state *ps = pkg_to_ps(pkg);
|
||||
struct apk_provider p = APK_PROVIDER_FROM_PACKAGE(pkg);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
struct apk_package *pkg0 = name->pkgs->item[i];
|
||||
if (pkg == pkg0)
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
struct apk_provider *p0 = &name->providers->item[i];
|
||||
if (pkg == p0->pkg)
|
||||
continue;
|
||||
if (compare_absolute_package_preference(pkg, pkg0) < 0)
|
||||
if (compare_absolute_package_preference(&p, p0) < 0)
|
||||
ps->preference++;
|
||||
}
|
||||
/* FIXME: consider all provided names too */
|
||||
}
|
||||
|
||||
static void count_name(struct apk_solver_state *ss, struct apk_name_state *ns)
|
||||
|
@ -552,8 +560,8 @@ static void recalculate_maybe(struct apk_solver_state *ss, struct apk_name *name
|
|||
if (!propagate)
|
||||
return;
|
||||
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
struct apk_package *pkg = name->pkgs->item[i];
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
struct apk_package *pkg = name->providers->item[i].pkg;
|
||||
|
||||
for (j = 0; j < pkg->depends->num; j++) {
|
||||
struct apk_dependency *dep = &pkg->depends->item[j];
|
||||
|
@ -573,8 +581,8 @@ static void sort_name(struct apk_solver_state *ss, struct apk_name *name)
|
|||
struct apk_name_state *ns = name_to_ns_alloc(name);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < name->pkgs->num; i++)
|
||||
sort_soft_dependencies(ss, name->pkgs->item[i]);
|
||||
for (i = 0; i < name->providers->num; i++)
|
||||
sort_soft_dependencies(ss, name->providers->item[i].pkg);
|
||||
|
||||
count_name(ss, ns);
|
||||
recalculate_maybe(ss, name,
|
||||
|
@ -602,7 +610,8 @@ static int install_if_missing(struct apk_solver_state *ss, struct apk_package *p
|
|||
|
||||
/* ns can be NULL, if the install_if has a name with
|
||||
* no packages */
|
||||
if (ns == NULL || !ns->locked || !apk_dep_is_satisfied(dep, ns->chosen))
|
||||
if (ns == NULL || !ns->locked ||
|
||||
!apk_dep_is_provided(dep, &ns->chosen))
|
||||
missing++;
|
||||
}
|
||||
|
||||
|
@ -615,7 +624,7 @@ static void get_unassigned_score(struct apk_name *name, struct apk_score *score)
|
|||
|
||||
*score = (struct apk_score){
|
||||
.conflicts = ns->requirers,
|
||||
.preference = name->pkgs->num,
|
||||
.preference = name->providers->num,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -645,7 +654,7 @@ static void demote_name(struct apk_solver_state *ss, struct apk_name *name)
|
|||
/* remove cached information */
|
||||
subscore(&ss->minimum_penalty, &ns->minimum_penalty);
|
||||
ns->minimum_penalty = (struct apk_score) { .score = 0 };
|
||||
ns->chosen = NULL;
|
||||
ns->chosen = CHOSEN_NONE;
|
||||
|
||||
/* and remove list, or request refresh */
|
||||
if (ns->requirers == 0 && ns->install_ifs == 0) {
|
||||
|
@ -791,7 +800,7 @@ static solver_result_t apply_decision(struct apk_solver_state *ss,
|
|||
}
|
||||
|
||||
ss->assigned_names++;
|
||||
ns->chosen = pkg;
|
||||
ns->chosen = APK_PROVIDER_FROM_PACKAGE(pkg);
|
||||
|
||||
list_del(&ns->unsolved_list);
|
||||
list_init(&ns->unsolved_list);
|
||||
|
@ -811,7 +820,7 @@ static solver_result_t apply_decision(struct apk_solver_state *ss,
|
|||
get_unassigned_score(name, &score);
|
||||
addscore(&ss->score, &score);
|
||||
|
||||
ns->chosen = NULL;
|
||||
ns->chosen = CHOSEN_NONE;
|
||||
ns->locked = 1;
|
||||
list_del(&ns->unsolved_list);
|
||||
list_init(&ns->unsolved_list);
|
||||
|
@ -880,7 +889,7 @@ static void undo_decision(struct apk_solver_state *ss,
|
|||
}
|
||||
|
||||
ns->locked = 0;
|
||||
ns->chosen = NULL;
|
||||
ns->chosen = CHOSEN_NONE;
|
||||
|
||||
/* Put back the name to unsolved list */
|
||||
promote_name(ss, name);
|
||||
|
@ -974,17 +983,17 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_dependency
|
|||
}
|
||||
|
||||
if (ns->locked) {
|
||||
if (ns->chosen)
|
||||
if (ns->chosen.pkg)
|
||||
dbg_printf("%s: locked to " PKG_VER_FMT " already\n",
|
||||
name->name, PKG_VER_PRINTF(ns->chosen));
|
||||
name->name, PKG_VER_PRINTF(ns->chosen.pkg));
|
||||
else
|
||||
dbg_printf("%s: locked to empty\n",
|
||||
name->name);
|
||||
if (!apk_dep_is_satisfied(dep, ns->chosen))
|
||||
if (!apk_dep_is_provided(dep, &ns->chosen))
|
||||
ss->score.conflicts += strength;
|
||||
return;
|
||||
}
|
||||
if (name->pkgs->num == 0) {
|
||||
if (name->providers->num == 0) {
|
||||
if (!dep->optional)
|
||||
ss->score.conflicts += strength;
|
||||
return;
|
||||
|
@ -1007,15 +1016,16 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_dependency
|
|||
ns->last_touched_decision = ss->num_decisions;
|
||||
}
|
||||
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
struct apk_package *pkg0 = name->pkgs->item[i];
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
struct apk_provider *p0 = &name->providers->item[i];
|
||||
struct apk_package *pkg0 = p0->pkg;
|
||||
struct apk_package_state *ps0 = pkg_to_ps(pkg0);
|
||||
|
||||
if (ps0 == NULL || ps0->locked ||
|
||||
ss->topology_position < pkg0->topology_hard)
|
||||
continue;
|
||||
|
||||
if (!apk_dep_is_satisfied(dep, pkg0)) {
|
||||
if (!apk_dep_is_provided(dep, p0)) {
|
||||
ps0->conflicts++;
|
||||
dbg_printf(PKG_VER_FMT ": conflicts++ -> %d\n",
|
||||
PKG_VER_PRINTF(pkg0),
|
||||
|
@ -1044,18 +1054,18 @@ static void undo_constraint(struct apk_solver_state *ss, struct apk_dependency *
|
|||
}
|
||||
|
||||
if (ns->locked) {
|
||||
if (ns->chosen != NULL) {
|
||||
if (ns->chosen.pkg != NULL) {
|
||||
dbg_printf(PKG_VER_FMT " selected already for %s\n",
|
||||
PKG_VER_PRINTF(ns->chosen), name->name);
|
||||
PKG_VER_PRINTF(ns->chosen.pkg), name->name);
|
||||
} else {
|
||||
dbg_printf("%s selected to not be satisfied\n",
|
||||
name->name);
|
||||
}
|
||||
if (!apk_dep_is_satisfied(dep, ns->chosen))
|
||||
if (!apk_dep_is_provided(dep, &ns->chosen))
|
||||
ss->score.conflicts -= strength;
|
||||
return;
|
||||
}
|
||||
if (name->pkgs->num == 0) {
|
||||
if (name->providers->num == 0) {
|
||||
if (!dep->optional)
|
||||
ss->score.conflicts -= strength;
|
||||
return;
|
||||
|
@ -1074,15 +1084,16 @@ static void undo_constraint(struct apk_solver_state *ss, struct apk_dependency *
|
|||
ns->last_touched_decision = ss->num_decisions;
|
||||
}
|
||||
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
struct apk_package *pkg0 = name->pkgs->item[i];
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
struct apk_provider *p0 = &name->providers->item[i];
|
||||
struct apk_package *pkg0 = p0->pkg;
|
||||
struct apk_package_state *ps0 = pkg_to_ps(pkg0);
|
||||
|
||||
if (ps0 == NULL || ps0->locked ||
|
||||
ss->topology_position < pkg0->topology_hard)
|
||||
continue;
|
||||
|
||||
if (!apk_dep_is_satisfied(dep, pkg0)) {
|
||||
if (!apk_dep_is_provided(dep, p0)) {
|
||||
ps0->conflicts--;
|
||||
dbg_printf(PKG_VER_FMT ": conflicts-- -> %d\n",
|
||||
PKG_VER_PRINTF(pkg0),
|
||||
|
@ -1100,7 +1111,7 @@ static int reconsider_name(struct apk_solver_state *ss, struct apk_name *name)
|
|||
{
|
||||
struct apk_name_state *ns = name_to_ns(name);
|
||||
struct apk_score minscore, score;
|
||||
struct apk_package *next_pkg = NULL;
|
||||
struct apk_provider *next_p = NULL;
|
||||
unsigned int next_topology = 0, options = 0;
|
||||
int i, score_locked = FALSE;
|
||||
|
||||
|
@ -1124,8 +1135,9 @@ static int reconsider_name(struct apk_solver_state *ss, struct apk_name *name)
|
|||
minscore.score = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
struct apk_package *pkg0 = name->pkgs->item[i];
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
struct apk_provider *p0 = &name->providers->item[i];
|
||||
struct apk_package *pkg0 = p0->pkg;
|
||||
struct apk_package_state *ps0 = pkg_to_ps(pkg0);
|
||||
struct apk_score pkg0_score;
|
||||
|
||||
|
@ -1147,9 +1159,9 @@ static int reconsider_name(struct apk_solver_state *ss, struct apk_name *name)
|
|||
/* next in topology order - next to get locked in */
|
||||
if (ps0->topology_soft < ss->topology_position &&
|
||||
ps0->topology_soft > next_topology)
|
||||
next_pkg = pkg0, next_topology = ps0->topology_soft;
|
||||
next_p = p0, next_topology = ps0->topology_soft;
|
||||
else if (pkg0->topology_hard > next_topology)
|
||||
next_pkg = pkg0, next_topology = pkg0->topology_hard;
|
||||
next_p = p0, next_topology = pkg0->topology_hard;
|
||||
|
||||
options++;
|
||||
}
|
||||
|
@ -1164,15 +1176,15 @@ static int reconsider_name(struct apk_solver_state *ss, struct apk_name *name)
|
|||
} else if (options == 1 && score_locked && ns->none_excluded) {
|
||||
dbg_printf("reconsider_name: %s: only one choice left with known score, locking.\n",
|
||||
name->name);
|
||||
return push_decision(ss, name, next_pkg, DECISION_ASSIGN, BRANCH_NO, FALSE);
|
||||
return push_decision(ss, name, next_p->pkg, DECISION_ASSIGN, BRANCH_NO, FALSE);
|
||||
}
|
||||
|
||||
ns->chosen = next_pkg;
|
||||
ns->chosen = *next_p;
|
||||
ns->minimum_penalty = minscore;
|
||||
addscore(&ss->minimum_penalty, &ns->minimum_penalty);
|
||||
|
||||
dbg_printf("reconsider_name: %s: min penalty " SCORE_FMT ", next_pkg=%p\n",
|
||||
name->name, SCORE_PRINTF(&minscore), next_pkg);
|
||||
name->name, SCORE_PRINTF(&minscore), next_p->pkg);
|
||||
|
||||
return SOLVERR_SOLUTION;
|
||||
}
|
||||
|
@ -1197,11 +1209,11 @@ static int expand_branch(struct apk_solver_state *ss)
|
|||
return r;
|
||||
ns->name_touched = 0;
|
||||
}
|
||||
if (pkg_to_ps(ns->chosen)->topology_soft < ss->topology_position &&
|
||||
pkg_to_ps(ns->chosen)->topology_soft > topology0)
|
||||
pkg0 = ns->chosen, topology0 = pkg_to_ps(pkg0)->topology_soft;
|
||||
else if (ns->chosen->topology_hard > topology0)
|
||||
pkg0 = ns->chosen, topology0 = pkg0->topology_hard;
|
||||
if (pkg_to_ps(ns->chosen.pkg)->topology_soft < ss->topology_position &&
|
||||
pkg_to_ps(ns->chosen.pkg)->topology_soft > topology0)
|
||||
pkg0 = ns->chosen.pkg, topology0 = pkg_to_ps(pkg0)->topology_soft;
|
||||
else if (ns->chosen.pkg->topology_hard > topology0)
|
||||
pkg0 = ns->chosen.pkg, topology0 = pkg0->topology_hard;
|
||||
}
|
||||
if (pkg0 == NULL) {
|
||||
dbg_printf("expand_branch: solution with score "SCORE_FMT"\n",
|
||||
|
@ -1355,15 +1367,15 @@ static int generate_changeset(struct apk_database *db,
|
|||
{
|
||||
struct apk_name *name;
|
||||
struct apk_name_state *ns;
|
||||
struct apk_package *pkg, *pkg0;
|
||||
struct apk_package *pkg;
|
||||
struct apk_installed_package *ipkg;
|
||||
int i, j, num_installs = 0, num_removed = 0, ci = 0;
|
||||
int i, num_installs = 0, num_removed = 0, ci = 0;
|
||||
|
||||
/* calculate change set size */
|
||||
for (i = 0; i < solution->num; i++) {
|
||||
pkg = solution->item[i].pkg;
|
||||
ns = name_to_ns(pkg->name);
|
||||
ns->chosen = pkg;
|
||||
ns->chosen = APK_PROVIDER_FROM_PACKAGE(pkg);
|
||||
ns->in_changeset = 1;
|
||||
if ((pkg->ipkg == NULL) ||
|
||||
solution->item[i].reinstall ||
|
||||
|
@ -1373,7 +1385,7 @@ static int generate_changeset(struct apk_database *db,
|
|||
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
|
||||
name = ipkg->pkg->name;
|
||||
ns = name_to_ns(name);
|
||||
if ((ns->chosen == NULL) || !ns->in_changeset)
|
||||
if ((ns->chosen.pkg == NULL) || !ns->in_changeset)
|
||||
num_removed++;
|
||||
}
|
||||
|
||||
|
@ -1382,7 +1394,7 @@ static int generate_changeset(struct apk_database *db,
|
|||
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
|
||||
name = ipkg->pkg->name;
|
||||
ns = name_to_ns(name);
|
||||
if ((ns->chosen == NULL) || !ns->in_changeset) {
|
||||
if ((ns->chosen.pkg == NULL) || !ns->in_changeset) {
|
||||
changeset->changes->item[ci].oldpkg = ipkg->pkg;
|
||||
ci++;
|
||||
}
|
||||
|
@ -1395,13 +1407,7 @@ static int generate_changeset(struct apk_database *db,
|
|||
if ((pkg->ipkg == NULL) ||
|
||||
solution->item[i].reinstall ||
|
||||
solution->item[i].repository_tag != pkg->ipkg->repository_tag){
|
||||
for (j = 0; j < name->pkgs->num; j++) {
|
||||
pkg0 = name->pkgs->item[j];
|
||||
if (pkg0->ipkg == NULL)
|
||||
continue;
|
||||
changeset->changes->item[ci].oldpkg = pkg0;
|
||||
break;
|
||||
}
|
||||
changeset->changes->item[ci].oldpkg = apk_pkg_get_installed(name);
|
||||
changeset->changes->item[ci].newpkg = pkg;
|
||||
changeset->changes->item[ci].repository_tag = solution->item[i].repository_tag;
|
||||
changeset->changes->item[ci].reinstall = solution->item[i].reinstall;
|
||||
|
@ -1887,7 +1893,7 @@ static void print_dep_errors(struct apk_database *db, char *label, struct apk_de
|
|||
struct apk_dependency *dep = &deps->item[i];
|
||||
struct apk_package *pkg = (struct apk_package*) dep->name->state_ptr;
|
||||
|
||||
if (apk_dep_is_satisfied(dep, pkg))
|
||||
if (apk_dep_is_materialized_or_provided(dep, pkg))
|
||||
continue;
|
||||
|
||||
if (print_label) {
|
||||
|
|
28
src/ver.c
28
src/ver.c
|
@ -97,7 +97,6 @@ static int ver_parse(void *ctx, struct apk_db_options *dbopts,
|
|||
static void ver_print_package_status(struct ver_ctx *ictx, struct apk_database *db, struct apk_package *pkg)
|
||||
{
|
||||
struct apk_name *name;
|
||||
struct apk_package *tmp;
|
||||
char pkgname[256];
|
||||
const char *opstr;
|
||||
apk_blob_t *latest = apk_blob_atomize(APK_BLOB_STR(""));
|
||||
|
@ -109,20 +108,20 @@ static void ver_print_package_status(struct ver_ctx *ictx, struct apk_database *
|
|||
allowed_repos = db->repo_tags[tag].allowed_repos;
|
||||
|
||||
name = pkg->name;
|
||||
for (i = 0; i < name->pkgs->num; i++) {
|
||||
tmp = name->pkgs->item[i];
|
||||
if (tmp->name != name || tmp->repos == 0)
|
||||
for (i = 0; i < name->providers->num; i++) {
|
||||
struct apk_package *pkg0 = name->providers->item[i].pkg;
|
||||
if (pkg0->name != name || pkg0->repos == 0)
|
||||
continue;
|
||||
if (!(ictx->all_tags || (tmp->repos & allowed_repos)))
|
||||
if (!(ictx->all_tags || (pkg0->repos & allowed_repos)))
|
||||
continue;
|
||||
r = apk_version_compare_blob(*tmp->version, *latest);
|
||||
r = apk_version_compare_blob(*pkg0->version, *latest);
|
||||
switch (r) {
|
||||
case APK_VERSION_GREATER:
|
||||
latest = tmp->version;
|
||||
latest_repos = tmp->repos;
|
||||
latest = pkg0->version;
|
||||
latest_repos = pkg0->repos;
|
||||
break;
|
||||
case APK_VERSION_EQUAL:
|
||||
latest_repos |= tmp->repos;
|
||||
latest_repos |= pkg0->repos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +150,8 @@ static int ver_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
|||
struct ver_ctx *ictx = (struct ver_ctx *) ctx;
|
||||
struct apk_installed_package *ipkg;
|
||||
struct apk_name *name;
|
||||
int i, j, ret = 0;
|
||||
struct apk_package *pkg;
|
||||
int i, ret = 0;
|
||||
|
||||
if (ictx->limchars) {
|
||||
if (strlen(ictx->limchars) == 0)
|
||||
|
@ -181,11 +181,9 @@ static int ver_main(void *ctx, struct apk_database *db, int argc, char **argv)
|
|||
ret = 1;
|
||||
goto ver_exit;
|
||||
}
|
||||
for (j = 0; j < name->pkgs->num; j++) {
|
||||
struct apk_package *pkg = name->pkgs->item[j];
|
||||
if (pkg->ipkg != NULL)
|
||||
ver_print_package_status(ictx, db, pkg);
|
||||
}
|
||||
pkg = apk_pkg_get_installed(name);
|
||||
if (pkg != NULL)
|
||||
ver_print_package_status(ictx, db, pkg);
|
||||
}
|
||||
|
||||
ver_exit:
|
||||
|
|
Loading…
Reference in New Issue