Commit 99145e2c authored by Timo Teräs's avatar Timo Teräs

all: introduce apk_provides and use it in apk_name

in preparation for provides support. implements also some
dependency satisfaction helper routines.

ref #574.
parent 97d44b5a
...@@ -78,6 +78,15 @@ struct apk_db_dir_instance { ...@@ -78,6 +78,15 @@ struct apk_db_dir_instance {
gid_t gid; 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 { struct apk_name {
apk_hash_node hash_node; apk_hash_node hash_node;
union { union {
...@@ -85,7 +94,7 @@ struct apk_name { ...@@ -85,7 +94,7 @@ struct apk_name {
void *state_ptr; void *state_ptr;
}; };
char *name; char *name;
struct apk_package_array *pkgs; struct apk_provider_array *providers;
struct apk_name_array *rdepends; struct apk_name_array *rdepends;
struct apk_name_array *rinstall_if; struct apk_name_array *rinstall_if;
}; };
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
struct apk_database; struct apk_database;
struct apk_name; struct apk_name;
struct apk_provider;
#define APK_SCRIPT_INVALID -1 #define APK_SCRIPT_INVALID -1
#define APK_SCRIPT_PRE_INSTALL 0 #define APK_SCRIPT_PRE_INSTALL 0
...@@ -103,6 +104,9 @@ struct apk_package { ...@@ -103,6 +104,9 @@ struct apk_package {
}; };
APK_ARRAY(apk_package_array, 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_FMT "%s-" BLOB_FMT
#define PKG_VER_PRINTF(pkg) pkg->name->name, BLOB_PRINTF(*pkg->version) #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); ...@@ -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, void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db,
struct apk_package *pkg); 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_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); 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, ...@@ -137,6 +143,8 @@ void apk_deps_del(struct apk_dependency_array **deps,
struct apk_name *name); struct apk_name *name);
int apk_script_type(const char *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_plain(struct apk_package *pkg, apk_blob_t to);
void apk_pkg_format_cache(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); struct apk_package *apk_pkg_new(void);
......
...@@ -99,7 +99,7 @@ static apk_blob_t pkg_name_get_key(apk_hash_item item) ...@@ -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) static void pkg_name_free(struct apk_name *name)
{ {
free(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->rdepends);
apk_name_array_free(&name->rinstall_if); apk_name_array_free(&name->rinstall_if);
free(name); free(name);
...@@ -211,7 +211,7 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name) ...@@ -211,7 +211,7 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name)
return NULL; return NULL;
pn->name = apk_blob_cstr(name); 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->rdepends);
apk_name_array_init(&pn->rinstall_if); apk_name_array_init(&pn->rinstall_if);
apk_hash_insert_hashed(&db->available.names, pn, hash); 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 * ...@@ -529,7 +529,8 @@ struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *
if (idb == NULL) { if (idb == NULL) {
idb = pkg; idb = pkg;
apk_hash_insert(&db->available.packages, 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); apk_db_pkg_rdepends(db, pkg);
} else { } else {
idb->repos |= pkg->repos; idb->repos |= pkg->repos;
...@@ -1761,8 +1762,12 @@ static int foreach_cache_file(void *pctx, int dirfd, const char *name) ...@@ -1761,8 +1762,12 @@ static int foreach_cache_file(void *pctx, int dirfd, const char *name)
char tmp[PATH_MAX]; char tmp[PATH_MAX];
if (name == NULL) if (name == NULL)
goto no_pkg; 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)); apk_pkg_format_cache(pkg0, APK_BLOB_BUF(tmp));
if (apk_blob_compare(b, APK_BLOB_STR(tmp)) == 0) { if (apk_blob_compare(b, APK_BLOB_STR(tmp)) == 0) {
...@@ -2226,14 +2231,14 @@ static int apk_db_install_archive_entry(void *_ctx, ...@@ -2226,14 +2231,14 @@ static int apk_db_install_archive_entry(void *_ctx,
break; break;
/* Does the original package replace the new one? */ /* Does the original package replace the new one? */
for (i = 0; i < opkg->ipkg->replaces->num; i++) { 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; opkg_prio = opkg->ipkg->replaces_priority;
break; break;
} }
} }
/* Does the new package replace the original one? */ /* Does the new package replace the original one? */
for (i = 0; i < ctx->ipkg->replaces->num; i++) { 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; pkg_prio = ctx->ipkg->replaces_priority;
break; break;
} }
......
...@@ -15,6 +15,11 @@ ...@@ -15,6 +15,11 @@
#include "apk_print.h" #include "apk_print.h"
#include "apk_solver.h" #include "apk_solver.h"
enum {
INSTALLED_PACKAGES,
MARKED_PACKAGES,
};
struct del_ctx { struct del_ctx {
int recursive_delete : 1; int recursive_delete : 1;
struct apk_dependency_array *world; struct apk_dependency_array *world;
...@@ -35,7 +40,7 @@ static int del_parse(void *pctx, struct apk_db_options *db, ...@@ -35,7 +40,7 @@ static int del_parse(void *pctx, struct apk_db_options *db,
return 0; return 0;
} }
static void foreach_installed_reverse_dependency( static void foreach_package_reverse_dependency(
struct apk_package *pkg, struct apk_package *pkg,
void (*cb)(struct apk_package *rdepend, void *ctx), void *ctx) void (*cb)(struct apk_package *rdepend, void *ctx), void *ctx)
{ {
...@@ -46,19 +51,18 @@ static void foreach_installed_reverse_dependency( ...@@ -46,19 +51,18 @@ static void foreach_installed_reverse_dependency(
return; return;
name = pkg->name; name = pkg->name;
for (i = 0; i < pkg->name->rdepends->num; i++) { for (i = 0; i < name->rdepends->num; i++) {
struct apk_name *name0 = pkg->name->rdepends->item[i]; struct apk_name *name0 = name->rdepends->item[i];
for (j = 0; j < name0->pkgs->num; j++) { for (j = 0; j < name0->providers->num; j++) {
struct apk_package *pkg0 = name0->pkgs->item[j]; struct apk_package *pkg0 = name0->providers->item[j].pkg;
if (pkg0->ipkg == NULL) if (pkg0->ipkg == NULL)
continue; continue;
for (k = 0; k < pkg0->depends->num; k++) { for (k = 0; k < pkg0->depends->num; k++) {
struct apk_dependency *dep = &pkg0->depends->item[k]; struct apk_dependency *dep = &pkg0->depends->item[k];
if (dep->name == name && if (apk_dep_is_materialized_or_provided(dep, pkg))
apk_dep_is_satisfied(dep, pkg))
break; break;
} }
if (k >= pkg0->depends->num) if (k >= pkg0->depends->num)
...@@ -69,6 +73,24 @@ static void foreach_installed_reverse_dependency( ...@@ -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 not_deleted_ctx {
struct apk_indent indent; struct apk_indent indent;
struct apk_package *pkg; struct apk_package *pkg;
...@@ -82,7 +104,6 @@ static void print_not_deleted_message(struct apk_package *pkg, ...@@ -82,7 +104,6 @@ static void print_not_deleted_message(struct apk_package *pkg,
if (pkg == NULL) if (pkg == NULL)
return; return;
if (pkg->state_ptr == ctx->pkg) if (pkg->state_ptr == ctx->pkg)
return; return;
pkg->state_ptr = ctx->pkg; pkg->state_ptr = ctx->pkg;
...@@ -97,19 +118,7 @@ static void print_not_deleted_message(struct apk_package *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)); apk_print_indented(&ctx->indent, APK_BLOB_STR(pkg->name->name));
foreach_installed_reverse_dependency(pkg, print_not_deleted_message, pctx); foreach_package_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;
} }
static void delete_from_world(struct apk_package *pkg, void *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) ...@@ -117,7 +126,7 @@ static void delete_from_world(struct apk_package *pkg, void *pctx)
struct del_ctx *ctx = (struct del_ctx *) pctx; struct del_ctx *ctx = (struct del_ctx *) pctx;
apk_deps_del(&ctx->world, pkg->name); 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) 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) ...@@ -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])); name[i] = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
apk_deps_del(&ctx->world, name[i]); apk_deps_del(&ctx->world, name[i]);
if (ctx->recursive_delete) if (ctx->recursive_delete)
foreach_installed_reverse_dependency( foreach_reverse_dependency(
name_to_pkg(name[i]), name[i], INSTALLED_PACKAGES,
delete_from_world, ctx); delete_from_world, ctx);
} }
r = apk_solver_solve(db, 0, ctx->world, &solution, &changeset); 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) ...@@ -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++) { for (i = 0; i < solution->num; i++) {
struct apk_package *pkg = solution->item[i].pkg; struct apk_package *pkg = solution->item[i].pkg;
pkg->name->state_ptr = pkg; pkg->name->state_ptr = pkg;
pkg->state_int = 0; pkg->state_int = 1;
} }
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
ndctx.pkg = name[i]->state_ptr; ndctx.pkg = name[i]->state_ptr;
ndctx.indent.indent = 0; ndctx.indent.indent = 0;
foreach_installed_reverse_dependency( foreach_reverse_dependency(
name[i]->state_ptr, name[i], MARKED_PACKAGES,
print_not_deleted_message, &ndctx); print_not_deleted_message, &ndctx);
if (ndctx.indent.indent) if (ndctx.indent.indent)
printf("\n"); printf("\n");
} }
......
...@@ -66,7 +66,7 @@ static int dump_pkg(struct dot_ctx *ctx, struct apk_package *pkg) ...@@ -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_dependency *dep = &pkg->depends->item[i];
struct apk_name *name = dep->name; struct apk_name *name = dep->name;
if (name->pkgs->num == 0) { if (name->providers->num == 0) {
start_graph(ctx); start_graph(ctx);
printf(" \"" PKG_VER_FMT "\" -> \"%s\" [color=red];\n", printf(" \"" PKG_VER_FMT "\" -> \"%s\" [color=red];\n",
PKG_VER_PRINTF(pkg), PKG_VER_PRINTF(pkg),
...@@ -77,19 +77,27 @@ static int dump_pkg(struct dot_ctx *ctx, struct apk_package *pkg) ...@@ -77,19 +77,27 @@ static int dump_pkg(struct dot_ctx *ctx, struct apk_package *pkg)
name->state_int = 1; name->state_int = 1;
} }
} else { } else {
for (j = 0; j < name->pkgs->num; j++) { for (j = 0; j < name->providers->num; j++) {
struct apk_package *pkg0 = name->pkgs->item[j]; struct apk_provider *p0 = &name->providers->item[j];
if (!apk_dep_is_satisfied(dep, pkg0)) if (!apk_dep_is_provided(dep, p0))
continue; continue;
r = dump_pkg(ctx, pkg0); r = dump_pkg(ctx, p0->pkg);
ret += r; ret += r;
if (r || (!ctx->errors_only)) { if (r || (!ctx->errors_only)) {
start_graph(ctx); 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(pkg),
PKG_VER_PRINTF(pkg0), PROVIDER_PRINTF(p0),
r ? "[color=red]" : ""); r ? "[color=red]" : "");
} }
} }
...@@ -117,8 +125,8 @@ static int dot_main(void *pctx, struct apk_database *db, int argc, char **argv) ...@@ -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])); struct apk_name *name = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
if (!name) if (!name)
continue; continue;
for (j = 0; j < name->pkgs->num; j++) for (j = 0; j < name->providers->num; j++)
dump_pkg(ctx, name->pkgs->item[j]); dump_pkg(ctx, name->providers->item[j].pkg);
} }
} else { } else {
apk_hash_foreach(&db->available.packages, foreach_pkg, pctx); 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) ...@@ -202,12 +202,12 @@ static int fetch_main(void *ctx, struct apk_database *db, int argc, char **argv)
} else { } else {
struct apk_package *pkg = NULL; 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 || if (pkg == NULL ||
apk_pkg_version_compare(dep.name->pkgs->item[j], apk_pkg_version_compare(dep.name->providers->item[j].pkg,
pkg) pkg)
== APK_VERSION_GREATER) == APK_VERSION_GREATER)
pkg = dep.name->pkgs->item[j]; pkg = dep.name->providers->item[j].pkg;
if (pkg == NULL) { if (pkg == NULL) {
apk_message("Unable to get '%s'", dep.name->name); 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) ...@@ -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 fix_ctx *ctx = (struct fix_ctx *) pctx;
struct apk_name *name; struct apk_name *name;
struct apk_package *pkg; struct apk_package *pkg;
int r = 0, i, j; int r = 0, i;
if (!ctx->solver_flags) if (!ctx->solver_flags)
ctx->solver_flags = APK_SOLVERF_REINSTALL; ctx->solver_flags = APK_SOLVERF_REINSTALL;
...@@ -83,12 +83,7 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv) ...@@ -83,12 +83,7 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
name = pkg->name; name = pkg->name;
} else { } else {
name = apk_db_get_name(db, APK_BLOB_STR(argv[i])); name = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
for (j = 0; j < name->pkgs->num; j++) { pkg = apk_pkg_get_installed(name);
if (name->pkgs->item[j]->ipkg != NULL) {
pkg = name->pkgs->item[j];
break;
}
}
} }
if (pkg == NULL || pkg->ipkg == NULL) { if (pkg == NULL || pkg->ipkg == NULL) {
apk_error("%s is not installed", name->name); apk_error("%s is not installed", name->name);
......
...@@ -72,7 +72,7 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx) ...@@ -72,7 +72,7 @@ static int warn_if_no_providers(apk_hash_item item, void *ctx)
struct counts *counts = (struct counts *) ctx; struct counts *counts = (struct counts *) ctx;
struct apk_name *name = (struct apk_name *) item; struct apk_name *name = (struct apk_name *) item;
if (name->pkgs->num == 0) { if (name->providers->num == 0) {
if (++counts->unsatisfied < 10) { if (++counts->unsatisfied < 10) {
apk_warning("No provider for dependency '%s'", apk_warning("No provider for dependency '%s'",
name->name); name->name);
...@@ -143,8 +143,10 @@ static int index_main(void *ctx, struct apk_database *db, int argc, char **argv) ...@@ -143,8 +143,10 @@ static int index_main(void *ctx, struct apk_database *db, int argc, char **argv)
if (name == NULL) if (name == NULL)
break; break;
for (j = 0; j < name->pkgs->num; j++) { for (j = 0; j < name->providers->num; j++) {
pkg = name->pkgs->item[j]; pkg = name->providers->item[j].pkg;
if (pkg->name != name)
continue;
if (apk_blob_compare(bver, *pkg->version) != 0) if (apk_blob_compare(bver, *pkg->version) != 0)
continue; continue;
if (pkg->size != fi.size) if (pkg->size != fi.size)
......
...@@ -69,7 +69,6 @@ static int info_exists(struct info_ctx *ctx, struct apk_database *db, ...@@ -69,7 +69,6 @@ static int info_exists(struct info_ctx *ctx, struct apk_database *db,
int argc, char **argv) int argc, char **argv)
{ {
struct apk_name *name; struct apk_name *name;
struct apk_package *pkg = NULL;
struct apk_dependency dep; struct apk_dependency dep;
int i, j, ok = 0; int i, j, ok = 0;
...@@ -84,18 +83,14 @@ static int info_exists(struct info_ctx *ctx, struct apk_database *db, ...@@ -84,18 +83,14 @@ static int info_exists(struct info_ctx *ctx, struct apk_database *db,
if (name == NULL) if (name == NULL)
continue; continue;
for (j = 0; j < name->pkgs->num; j++) { for (j = 0; j < name->providers->num; j++) {
pkg = name->pkgs->item[j]; struct apk_provider *p = &name->providers->item[j];
if (pkg->ipkg != NULL) if (p->pkg->ipkg == NULL)
break; 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++; ok++;
} }
...@@ -196,7 +191,7 @@ static void info_print_depends(struct apk_database *db, struct apk_package *pkg) ...@@ -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) 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"; char *separator = apk_verbosity > 1 ? " " : "\n";
if (apk_verbosity == 1) if (apk_verbosity == 1)
...@@ -205,23 +200,23 @@ static void info_print_required_by(struct apk_database *db, struct apk_package * ...@@ -205,23 +200,23 @@ static void info_print_required_by(struct apk_database *db, struct apk_package *
if (apk_verbosity > 1) if (apk_verbosity > 1)
printf("%s: ", pkg->name->name); printf("%s: ", pkg->name->name);
for (i = 0; i < pkg->name->rdepends->num; i++) { 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 /* Check only the package that is installed, and that
* it actually has this package as dependency. */ * it actually has this package as dependency. */
for (j = 0; j < name0->pkgs->num; j++) { name0 = pkg->name->rdepends->item[i];
struct apk_package *pkg0 = name0->pkgs->item[j]; 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; continue;
for (k = 0; k < pkg0->depends->num; k++) { printf(PKG_VER_FMT "%s",
if (pkg0->depends->item[k].name != pkg->name) PKG_VER_PRINTF(pkg0),
continue; separator);
printf(PKG_VER_FMT "%s", break;
PKG_VER_PRINTF(pkg0),
separator);
break;
}
} }
} }
} }
...@@ -248,7 +243,7 @@ static void info_print_install_if(struct apk_database *db, struct apk_package *p ...@@ -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) 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"; char *separator = apk_verbosity > 1 ? " " : "\n";
if (apk_verbosity == 1) if (apk_verbosity == 1)
...@@ -257,23 +252,23 @@ static void info_print_rinstall_if(struct apk_database *db, struct apk_package * ...@@ -257,23 +252,23 @@ static void info_print_rinstall_if(struct apk_database *db, struct apk_package *
if (apk_verbosity > 1) if (apk_verbosity > 1)
printf("%s: ", pkg->name->name); printf("%s: ", pkg->name->name);
for (i = 0; i < pkg->name->rinstall_if->num; i++) { 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 /* Check only the package that is installed, and that
* it actually has this package in install_if. */ * it actually has this package in install_if. */
for (j = 0; j < name0->pkgs->num; j++) { name0 = pkg->name->rinstall_if->item[i];
struct apk_package *pkg0 = name0->pkgs->item[j]; 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; continue;
for (k = 0; k < pkg0->install_if->num; k++) { printf(PKG_VER_FMT "%s",
if (pkg0->install_if->item[k].name != pkg->name) PKG_VER_PRINTF(pkg0),
continue; separator);
printf(PKG_VER_FMT "%s", break;
PKG_VER_PRINTF(pkg0),
separator);
break;
}
} }
} }
} }
...@@ -376,12 +371,12 @@ static int info_package(struct info_ctx *ctx, struct apk_database *db, ...@@ -376,12 +371,12 @@ static int info_package(struct info_ctx *ctx, struct apk_database *db,
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
name = apk_db_query_name(db, APK_BLOB_STR(argv[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]); apk_error("Not found: %s", argv[i]);
return 1; return 1;
} }
for (j = 0; j < name->pkgs->num; j++) for (j = 0; j < name->providers->num; j++)
info_subaction(ctx, name->pkgs->item[j]); info_subaction(ctx, name->providers->item[j].pkg);
} }
return 0; return 0;
} }
......
...@@ -38,6 +38,21 @@ static const apk_spn_match_def apk_spn_dependency_separator = { ...@@ -38,6 +38,21 @@ static const apk_spn_match_def apk_spn_dependency_separator = {
[4] = (1<<0) /* */, [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)