pkg: add global reverse dependency iterator helpers and use them
... in the error printing and the package deletion.cute-signatures
parent
e51232e710
commit
bcda66bf08
|
@ -37,9 +37,11 @@ struct apk_provider;
|
||||||
#define APK_SIGN_GENERATE 4
|
#define APK_SIGN_GENERATE 4
|
||||||
#define APK_SIGN_VERIFY_AND_GENERATE 5
|
#define APK_SIGN_VERIFY_AND_GENERATE 5
|
||||||
|
|
||||||
#define APK_DEP_IRRELEVANT 0
|
#define APK_DEP_IRRELEVANT 0x00001
|
||||||
#define APK_DEP_SATISFIED 1
|
#define APK_DEP_SATISFIES 0x00002
|
||||||
#define APK_DEP_CONFLICTED 2
|
#define APK_DEP_CONFLICTS 0x00004
|
||||||
|
#define APK_FOREACH_INSTALLED 0x10000
|
||||||
|
#define APK_FOREACH_MARKED 0x20000
|
||||||
|
|
||||||
struct apk_sign_ctx {
|
struct apk_sign_ctx {
|
||||||
int keys_fd;
|
int keys_fd;
|
||||||
|
@ -92,8 +94,13 @@ struct apk_package {
|
||||||
apk_hash_node hash_node;
|
apk_hash_node hash_node;
|
||||||
union {
|
union {
|
||||||
struct apk_solver_package_state ss;
|
struct apk_solver_package_state ss;
|
||||||
int state_int;
|
struct {
|
||||||
void *state_ptr;
|
int marked;
|
||||||
|
union {
|
||||||
|
int state_int;
|
||||||
|
void *state_ptr;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
struct apk_name *name;
|
struct apk_name *name;
|
||||||
struct apk_installed_package *ipkg;
|
struct apk_installed_package *ipkg;
|
||||||
|
@ -179,4 +186,13 @@ int apk_pkg_write_index_entry(struct apk_package *pkg, struct apk_ostream *os);
|
||||||
|
|
||||||
int apk_pkg_version_compare(struct apk_package *a, struct apk_package *b);
|
int apk_pkg_version_compare(struct apk_package *a, struct apk_package *b);
|
||||||
|
|
||||||
|
void apk_pkg_foreach_matching_dependency(
|
||||||
|
struct apk_package *pkg, struct apk_dependency_array *deps, int match, struct apk_package *mpkg,
|
||||||
|
void cb(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *ctx),
|
||||||
|
void *ctx);
|
||||||
|
void apk_pkg_foreach_reverse_dependency(
|
||||||
|
struct apk_package *pkg, int match,
|
||||||
|
void cb(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *ctx),
|
||||||
|
void *ctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
68
src/commit.c
68
src/commit.c
|
@ -18,46 +18,6 @@
|
||||||
|
|
||||||
#include "apk_print.h"
|
#include "apk_print.h"
|
||||||
|
|
||||||
static void foreach_package_reverse_dependency2(
|
|
||||||
struct apk_package *pkg,
|
|
||||||
struct apk_name_array *rdepends,
|
|
||||||
int match,
|
|
||||||
void cb(struct apk_package *pkg0, struct apk_dependency *d0, void *ctx),
|
|
||||||
void *ctx)
|
|
||||||
{
|
|
||||||
int i, j, k;
|
|
||||||
|
|
||||||
for (i = 0; i < rdepends->num; i++) {
|
|
||||||
struct apk_name *name0 = rdepends->item[i];
|
|
||||||
|
|
||||||
for (j = 0; j < name0->providers->num; j++) {
|
|
||||||
struct apk_package *pkg0 = name0->providers->item[j].pkg;
|
|
||||||
|
|
||||||
for (k = 0; k < pkg0->depends->num; k++) {
|
|
||||||
struct apk_dependency *d0 = &pkg0->depends->item[k];
|
|
||||||
if (apk_dep_analyze(d0, pkg) == match)
|
|
||||||
cb(pkg0, d0, ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void foreach_package_reverse_dependency(
|
|
||||||
struct apk_package *pkg,
|
|
||||||
int match,
|
|
||||||
void cb(struct apk_package *pkg0, struct apk_dependency *d0, void *ctx),
|
|
||||||
void *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (pkg == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach_package_reverse_dependency2(pkg, pkg->name->rdepends, match, cb, ctx);
|
|
||||||
for (i = 0; i < pkg->provides->num; i++)
|
|
||||||
foreach_package_reverse_dependency2(pkg, pkg->provides->item[i].name->rdepends, match, cb, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int pkg_available(struct apk_database *db, struct apk_package *pkg)
|
static inline int pkg_available(struct apk_database *db, struct apk_package *pkg)
|
||||||
{
|
{
|
||||||
if (pkg->repos & db->available_repos)
|
if (pkg->repos & db->available_repos)
|
||||||
|
@ -472,14 +432,14 @@ static void print_conflicts(struct print_state *ps, struct apk_package *pkg)
|
||||||
struct apk_dependency *d;
|
struct apk_dependency *d;
|
||||||
|
|
||||||
foreach_array_item(p, pkg->name->providers) {
|
foreach_array_item(p, pkg->name->providers) {
|
||||||
if (p->pkg == pkg || p->pkg->state_ptr == STATE_UNSET)
|
if (p->pkg == pkg || !p->pkg->marked)
|
||||||
continue;
|
continue;
|
||||||
label_start(ps, "conflicts:");
|
label_start(ps, "conflicts:");
|
||||||
apk_print_indented_fmt(&ps->i, PKG_VER_FMT, PKG_VER_PRINTF(p->pkg));
|
apk_print_indented_fmt(&ps->i, PKG_VER_FMT, PKG_VER_PRINTF(p->pkg));
|
||||||
}
|
}
|
||||||
foreach_array_item(d, pkg->provides) {
|
foreach_array_item(d, pkg->provides) {
|
||||||
foreach_array_item(p, d->name->providers) {
|
foreach_array_item(p, d->name->providers) {
|
||||||
if (p->pkg == pkg || p->pkg->state_ptr == STATE_UNSET)
|
if (p->pkg == pkg || !p->pkg->marked)
|
||||||
continue;
|
continue;
|
||||||
label_start(ps, "conflicts:");
|
label_start(ps, "conflicts:");
|
||||||
apk_print_indented_fmt(
|
apk_print_indented_fmt(
|
||||||
|
@ -492,15 +452,12 @@ static void print_conflicts(struct print_state *ps, struct apk_package *pkg)
|
||||||
label_end(ps);
|
label_end(ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_dep(struct apk_package *pkg0, struct apk_dependency *d0, void *ctx)
|
static void print_dep(struct apk_package *pkg0, struct apk_dependency *d0, struct apk_package *pkg, void *ctx)
|
||||||
{
|
{
|
||||||
struct print_state *ps = (struct print_state *) ctx;
|
struct print_state *ps = (struct print_state *) ctx;
|
||||||
const char *label = (ps->match == APK_DEP_SATISFIED) ? "satisfies:" : "breaks:";
|
const char *label = (ps->match & APK_DEP_SATISFIES) ? "satisfies:" : "breaks:";
|
||||||
char tmp[256];
|
char tmp[256];
|
||||||
|
|
||||||
if (pkg0 != NULL && pkg0->state_ptr == STATE_UNSET)
|
|
||||||
return;
|
|
||||||
|
|
||||||
label_start(ps, label);
|
label_start(ps, label);
|
||||||
if (pkg0 == NULL)
|
if (pkg0 == NULL)
|
||||||
apk_print_indented_fmt(&ps->i, "world[%s]", apk_dep_snprintf(tmp, sizeof(tmp), d0));
|
apk_print_indented_fmt(&ps->i, "world[%s]", apk_dep_snprintf(tmp, sizeof(tmp), d0));
|
||||||
|
@ -512,14 +469,9 @@ static void print_dep(struct apk_package *pkg0, struct apk_dependency *d0, void
|
||||||
|
|
||||||
static void print_deps(struct print_state *ps, struct apk_package *pkg, int match)
|
static void print_deps(struct print_state *ps, struct apk_package *pkg, int match)
|
||||||
{
|
{
|
||||||
struct apk_dependency *d0;
|
|
||||||
|
|
||||||
ps->match = match;
|
ps->match = match;
|
||||||
foreach_array_item(d0, ps->world) {
|
apk_pkg_foreach_matching_dependency(NULL, ps->world, ps->match, pkg, print_dep, ps);
|
||||||
if (apk_dep_analyze(d0, pkg) == match)
|
apk_pkg_foreach_reverse_dependency(pkg, ps->match, print_dep, ps);
|
||||||
print_dep(NULL, d0, ps);
|
|
||||||
}
|
|
||||||
foreach_package_reverse_dependency(pkg, ps->match, print_dep, ps);
|
|
||||||
label_end(ps);
|
label_end(ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,9 +484,9 @@ static void analyze_package(struct print_state *ps, struct apk_package *pkg, uns
|
||||||
|
|
||||||
print_pinning_errors(ps, pkg, tag);
|
print_pinning_errors(ps, pkg, tag);
|
||||||
print_conflicts(ps, pkg);
|
print_conflicts(ps, pkg);
|
||||||
print_deps(ps, pkg, APK_DEP_CONFLICTED);
|
print_deps(ps, pkg, APK_DEP_CONFLICTS | APK_FOREACH_MARKED);
|
||||||
if (ps->label == NULL)
|
if (ps->label == NULL)
|
||||||
print_deps(ps, pkg, APK_DEP_SATISFIED);
|
print_deps(ps, pkg, APK_DEP_SATISFIES | APK_FOREACH_MARKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void analyze_name(struct print_state *ps, struct apk_name *name)
|
static void analyze_name(struct print_state *ps, struct apk_name *name)
|
||||||
|
@ -570,7 +522,7 @@ static void analyze_name(struct print_state *ps, struct apk_name *name)
|
||||||
foreach_array_item(pname0, name->rdepends) {
|
foreach_array_item(pname0, name->rdepends) {
|
||||||
name0 = *pname0;
|
name0 = *pname0;
|
||||||
foreach_array_item(p0, name0->providers) {
|
foreach_array_item(p0, name0->providers) {
|
||||||
if (p0->pkg->state_ptr == STATE_UNSET)
|
if (!p0->pkg->marked)
|
||||||
continue;
|
continue;
|
||||||
foreach_array_item(d0, p0->pkg->depends) {
|
foreach_array_item(d0, p0->pkg->depends) {
|
||||||
if (d0->name != name || d0->conflict)
|
if (d0->name != name || d0->conflict)
|
||||||
|
@ -652,7 +604,7 @@ void apk_solver_print_errors(struct apk_database *db,
|
||||||
struct apk_package *pkg = change->new_pkg;
|
struct apk_package *pkg = change->new_pkg;
|
||||||
if (pkg == NULL)
|
if (pkg == NULL)
|
||||||
continue;
|
continue;
|
||||||
pkg->state_int = STATE_PRESENT;
|
pkg->marked = 1;
|
||||||
pkg->name->state_int = STATE_PRESENT;
|
pkg->name->state_int = STATE_PRESENT;
|
||||||
foreach_array_item(p, pkg->provides)
|
foreach_array_item(p, pkg->provides)
|
||||||
p->name->state_int = STATE_PRESENT;
|
p->name->state_int = STATE_PRESENT;
|
||||||
|
|
106
src/del.c
106
src/del.c
|
@ -15,11 +15,6 @@
|
||||||
#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;
|
||||||
|
@ -40,63 +35,23 @@ static int del_parse(void *pctx, struct apk_db_options *db,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void foreach_package_reverse_dependency2(
|
|
||||||
struct apk_package *pkg, struct apk_name_array *rdepends,
|
|
||||||
void (*cb)(struct apk_package *rdepend, void *ctx), void *ctx)
|
|
||||||
{
|
|
||||||
int i, j, k;
|
|
||||||
|
|
||||||
if (pkg == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < rdepends->num; i++) {
|
|
||||||
struct apk_name *name0 = rdepends->item[i];
|
|
||||||
|
|
||||||
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 (apk_dep_is_materialized_or_provided(dep, pkg))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (k >= pkg0->depends->num)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
cb(pkg0, ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void foreach_package_reverse_dependency(
|
|
||||||
struct apk_package *pkg,
|
|
||||||
void (*cb)(struct apk_package *rdepend, void *ctx), void *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
foreach_package_reverse_dependency2(pkg, pkg->name->rdepends, cb, ctx);
|
|
||||||
for (i = 0; i < pkg->provides->num; i++)
|
|
||||||
foreach_package_reverse_dependency2(pkg, pkg->provides->item[i].name->rdepends, cb, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void foreach_reverse_dependency(
|
static void foreach_reverse_dependency(
|
||||||
struct apk_name *name, int mode,
|
struct apk_name *name, int match,
|
||||||
void (*cb)(struct apk_package *rdepend, void *ctx), void *ctx)
|
void cb(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *ctx),
|
||||||
|
void *ctx)
|
||||||
{
|
{
|
||||||
int i;
|
int installed = match & APK_FOREACH_INSTALLED;
|
||||||
|
int marked = match & APK_FOREACH_MARKED;
|
||||||
|
struct apk_provider *p0;
|
||||||
|
struct apk_package *pkg0;
|
||||||
|
|
||||||
for (i = 0; i < name->providers->num; i++) {
|
foreach_array_item(p0, name->providers) {
|
||||||
struct apk_package *pkg0 = name->providers->item[i].pkg;
|
pkg0 = p0->pkg;
|
||||||
|
if (installed && pkg0->ipkg == NULL)
|
||||||
if (mode == INSTALLED_PACKAGES && pkg0->ipkg == NULL)
|
|
||||||
continue;
|
continue;
|
||||||
if (mode == MARKED_PACKAGES && pkg0->state_int == 0)
|
if (marked && !pkg0->marked)
|
||||||
continue;
|
continue;
|
||||||
|
apk_pkg_foreach_reverse_dependency(pkg0, match, cb, ctx);
|
||||||
foreach_package_reverse_dependency(pkg0, cb, ctx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +61,9 @@ struct not_deleted_ctx {
|
||||||
int header;
|
int header;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void print_not_deleted_message(struct apk_package *pkg,
|
static void print_not_deleted_message(
|
||||||
void *pctx)
|
struct apk_package *pkg0, struct apk_dependency *dep0,
|
||||||
|
struct apk_package *pkg, void *pctx)
|
||||||
{
|
{
|
||||||
struct not_deleted_ctx *ctx = (struct not_deleted_ctx *) pctx;
|
struct not_deleted_ctx *ctx = (struct not_deleted_ctx *) pctx;
|
||||||
|
|
||||||
|
@ -127,15 +83,21 @@ 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_package_reverse_dependency(pkg, print_not_deleted_message, pctx);
|
apk_pkg_foreach_reverse_dependency(
|
||||||
|
pkg0, APK_FOREACH_MARKED | APK_DEP_SATISFIES,
|
||||||
|
print_not_deleted_message, pctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void delete_from_world(struct apk_package *pkg, void *pctx)
|
static void delete_from_world(
|
||||||
|
struct apk_package *pkg0, struct apk_dependency *dep0,
|
||||||
|
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, pkg0->name);
|
||||||
foreach_package_reverse_dependency(pkg, delete_from_world, pctx);
|
apk_pkg_foreach_reverse_dependency(
|
||||||
|
pkg0, APK_FOREACH_INSTALLED | APK_DEP_SATISFIES,
|
||||||
|
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)
|
||||||
|
@ -144,7 +106,7 @@ static int del_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
||||||
struct apk_name **name;
|
struct apk_name **name;
|
||||||
struct apk_changeset changeset = {};
|
struct apk_changeset changeset = {};
|
||||||
struct not_deleted_ctx ndctx = {};
|
struct not_deleted_ctx ndctx = {};
|
||||||
int i, j, r = 0;
|
int i, r = 0;
|
||||||
|
|
||||||
apk_dependency_array_copy(&ctx->world, db->world);
|
apk_dependency_array_copy(&ctx->world, db->world);
|
||||||
|
|
||||||
|
@ -154,27 +116,29 @@ static int del_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
||||||
apk_deps_del(&ctx->world, name[i]);
|
apk_deps_del(&ctx->world, name[i]);
|
||||||
if (ctx->recursive_delete)
|
if (ctx->recursive_delete)
|
||||||
foreach_reverse_dependency(
|
foreach_reverse_dependency(
|
||||||
name[i], INSTALLED_PACKAGES,
|
name[i], APK_FOREACH_INSTALLED | APK_DEP_SATISFIES,
|
||||||
delete_from_world, ctx);
|
delete_from_world, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = apk_solver_solve(db, 0, ctx->world, &changeset);
|
r = apk_solver_solve(db, 0, ctx->world, &changeset);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
/* check for non-deleted package names */
|
/* check for non-deleted package names */
|
||||||
for (i = 0; i < changeset.changes->num; i++) {
|
struct apk_change *change;
|
||||||
struct apk_package *pkg = changeset.changes->item[i].new_pkg;
|
foreach_array_item(change, changeset.changes) {
|
||||||
|
struct apk_package *pkg = change->new_pkg;
|
||||||
|
struct apk_dependency *p;
|
||||||
if (pkg == NULL)
|
if (pkg == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
pkg->marked = 1;
|
||||||
pkg->name->state_ptr = pkg;
|
pkg->name->state_ptr = pkg;
|
||||||
for (j = 0; j < pkg->provides->num; j++)
|
foreach_array_item(p, pkg->provides)
|
||||||
pkg->provides->item[j].name->state_ptr = pkg;
|
p->name->state_ptr = pkg;
|
||||||
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_reverse_dependency(
|
foreach_reverse_dependency(
|
||||||
name[i], MARKED_PACKAGES,
|
name[i], APK_FOREACH_MARKED | APK_DEP_SATISFIES,
|
||||||
print_not_deleted_message, &ndctx);
|
print_not_deleted_message, &ndctx);
|
||||||
if (ndctx.indent.indent)
|
if (ndctx.indent.indent)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
|
@ -407,7 +407,7 @@ int apk_dep_analyze(struct apk_dependency *dep, struct apk_package *pkg)
|
||||||
return APK_DEP_IRRELEVANT;
|
return APK_DEP_IRRELEVANT;
|
||||||
|
|
||||||
if (dep->name == pkg->name)
|
if (dep->name == pkg->name)
|
||||||
return apk_dep_is_materialized(dep, pkg) ? APK_DEP_SATISFIED : APK_DEP_CONFLICTED;
|
return apk_dep_is_materialized(dep, pkg) ? APK_DEP_SATISFIES : APK_DEP_CONFLICTS;
|
||||||
|
|
||||||
for (i = 0; i < pkg->provides->num; i++) {
|
for (i = 0; i < pkg->provides->num; i++) {
|
||||||
struct apk_provider p;
|
struct apk_provider p;
|
||||||
|
@ -416,7 +416,7 @@ int apk_dep_analyze(struct apk_dependency *dep, struct apk_package *pkg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p = APK_PROVIDER_FROM_PROVIDES(pkg, &pkg->provides->item[i]);
|
p = APK_PROVIDER_FROM_PROVIDES(pkg, &pkg->provides->item[i]);
|
||||||
return apk_dep_is_provided(dep, &p) ? APK_DEP_SATISFIED : APK_DEP_CONFLICTED;
|
return apk_dep_is_provided(dep, &p) ? APK_DEP_SATISFIES : APK_DEP_CONFLICTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return APK_DEP_IRRELEVANT;
|
return APK_DEP_IRRELEVANT;
|
||||||
|
@ -1213,3 +1213,58 @@ int apk_pkg_version_compare(struct apk_package *a, struct apk_package *b)
|
||||||
|
|
||||||
return apk_version_compare_blob(*a->version, *b->version);
|
return apk_version_compare_blob(*a->version, *b->version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void apk_pkg_foreach_matching_dependency(
|
||||||
|
struct apk_package *pkg, struct apk_dependency_array *deps, int match, struct apk_package *mpkg,
|
||||||
|
void cb(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *ctx),
|
||||||
|
void *ctx)
|
||||||
|
{
|
||||||
|
struct apk_dependency *d;
|
||||||
|
|
||||||
|
foreach_array_item(d, deps) {
|
||||||
|
if (apk_dep_analyze(d, mpkg) & match)
|
||||||
|
cb(pkg, d, mpkg, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreach_reverse_dependency(
|
||||||
|
struct apk_package *pkg,
|
||||||
|
struct apk_name_array *rdepends,
|
||||||
|
int match,
|
||||||
|
void cb(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *ctx),
|
||||||
|
void *ctx)
|
||||||
|
{
|
||||||
|
int installed = match & APK_FOREACH_INSTALLED;
|
||||||
|
int marked = match & APK_FOREACH_MARKED;
|
||||||
|
struct apk_name **pname0, *name0;
|
||||||
|
struct apk_provider *p0;
|
||||||
|
struct apk_package *pkg0;
|
||||||
|
struct apk_dependency *d0;
|
||||||
|
|
||||||
|
foreach_array_item(pname0, rdepends) {
|
||||||
|
name0 = *pname0;
|
||||||
|
foreach_array_item(p0, name0->providers) {
|
||||||
|
pkg0 = p0->pkg;
|
||||||
|
if (installed && pkg0->ipkg == NULL)
|
||||||
|
continue;
|
||||||
|
if (marked && !pkg0->marked)
|
||||||
|
continue;
|
||||||
|
foreach_array_item(d0, pkg0->depends) {
|
||||||
|
if (apk_dep_analyze(d0, pkg) & match)
|
||||||
|
cb(pkg0, d0, pkg, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void apk_pkg_foreach_reverse_dependency(
|
||||||
|
struct apk_package *pkg, int match,
|
||||||
|
void cb(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *ctx),
|
||||||
|
void *ctx)
|
||||||
|
{
|
||||||
|
struct apk_dependency *p;
|
||||||
|
|
||||||
|
foreach_reverse_dependency(pkg, pkg->name->rdepends, match, cb, ctx);
|
||||||
|
foreach_array_item(p, pkg->provides)
|
||||||
|
foreach_reverse_dependency(pkg, p->name->rdepends, match, cb, ctx);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue