summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/apk_package.h20
-rw-r--r--src/del.c71
-rw-r--r--src/package.c33
-rw-r--r--src/search.c11
4 files changed, 64 insertions, 71 deletions
diff --git a/src/apk_package.h b/src/apk_package.h
index b04bd79..979de5e 100644
--- a/src/apk_package.h
+++ b/src/apk_package.h
@@ -37,11 +37,12 @@ struct apk_provider;
#define APK_SIGN_GENERATE 4
#define APK_SIGN_VERIFY_AND_GENERATE 5
-#define APK_DEP_IRRELEVANT 0x00001
-#define APK_DEP_SATISFIES 0x00002
-#define APK_DEP_CONFLICTS 0x00004
-#define APK_FOREACH_INSTALLED 0x10000
-#define APK_FOREACH_MARKED 0x20000
+#define APK_DEP_IRRELEVANT 0x01
+#define APK_DEP_SATISFIES 0x02
+#define APK_DEP_CONFLICTS 0x04
+#define APK_FOREACH_INSTALLED 0x10
+#define APK_FOREACH_MARKED 0x20
+#define APK_FOREACH_GENID_MASK 0xffffff00
struct apk_sign_ctx {
int keys_fd;
@@ -95,7 +96,8 @@ struct apk_package {
union {
struct apk_solver_package_state ss;
struct {
- int marked;
+ unsigned int marked;
+ unsigned int foreach_genid;
union {
int state_int;
void *state_ptr;
@@ -185,12 +187,14 @@ 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);
+unsigned int apk_foreach_genid(void);
void apk_pkg_foreach_matching_dependency(
- struct apk_package *pkg, struct apk_dependency_array *deps, int match, struct apk_package *mpkg,
+ struct apk_package *pkg, struct apk_dependency_array *deps,
+ unsigned 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,
+ struct apk_package *pkg, unsigned int match,
void cb(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *ctx),
void *ctx);
diff --git a/src/del.c b/src/del.c
index 704245a..2e7de8b 100644
--- a/src/del.c
+++ b/src/del.c
@@ -35,29 +35,10 @@ static int del_parse(void *pctx, struct apk_db_options *db,
return 0;
}
-static void foreach_reverse_dependency(
- struct apk_name *name, 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_provider *p0;
- struct apk_package *pkg0;
-
- foreach_array_item(p0, name->providers) {
- pkg0 = p0->pkg;
- if (installed && pkg0->ipkg == NULL)
- continue;
- if (marked && !pkg0->marked)
- continue;
- apk_pkg_foreach_reverse_dependency(pkg0, match, cb, ctx);
- }
-}
-
struct not_deleted_ctx {
struct apk_indent indent;
- struct apk_package *pkg;
+ struct apk_name *name;
+ unsigned int matches;
int header;
};
@@ -67,25 +48,17 @@ static void print_not_deleted_message(
{
struct not_deleted_ctx *ctx = (struct not_deleted_ctx *) pctx;
- if (pkg == NULL)
- return;
- if (pkg->state_ptr == ctx->pkg)
- return;
- pkg->state_ptr = ctx->pkg;
-
if (!ctx->header) {
apk_message("World updated, but the following packages are not removed due to:");
ctx->header = 1;
}
if (!ctx->indent.indent) {
- ctx->indent.x = printf(" %s:", ctx->pkg->name->name);
+ ctx->indent.x = printf(" %s:", ctx->name->name);
ctx->indent.indent = ctx->indent.x + 1;
}
- apk_print_indented(&ctx->indent, APK_BLOB_STR(pkg->name->name));
- apk_pkg_foreach_reverse_dependency(
- pkg0, APK_FOREACH_MARKED | APK_DEP_SATISFIES,
- print_not_deleted_message, pctx);
+ apk_print_indented(&ctx->indent, APK_BLOB_STR(pkg0->name->name));
+ apk_pkg_foreach_reverse_dependency(pkg0, ctx->matches, print_not_deleted_message, pctx);
}
static void delete_from_world(
@@ -95,17 +68,21 @@ static void delete_from_world(
struct del_ctx *ctx = (struct del_ctx *) pctx;
apk_deps_del(&ctx->world, pkg0->name);
- apk_pkg_foreach_reverse_dependency(
- pkg0, APK_FOREACH_INSTALLED | APK_DEP_SATISFIES,
- delete_from_world, pctx);
+
+ if (ctx->recursive_delete)
+ 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)
{
struct del_ctx *ctx = (struct del_ctx *) pctx;
+ struct not_deleted_ctx ndctx = {};
struct apk_name **name;
struct apk_changeset changeset = {};
- struct not_deleted_ctx ndctx = {};
+ struct apk_change *change;
+ struct apk_provider *p;
int i, r = 0;
apk_dependency_array_copy(&ctx->world, db->world);
@@ -113,33 +90,27 @@ static int del_main(void *pctx, struct apk_database *db, int argc, char **argv)
name = alloca(argc * sizeof(struct apk_name*));
for (i = 0; i < argc; i++) {
name[i] = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
- apk_deps_del(&ctx->world, name[i]);
- if (ctx->recursive_delete)
- foreach_reverse_dependency(
- name[i], APK_FOREACH_INSTALLED | APK_DEP_SATISFIES,
- delete_from_world, ctx);
+ delete_from_world(apk_pkg_get_installed(name[i]), NULL, NULL, ctx);
}
r = apk_solver_solve(db, 0, ctx->world, &changeset);
if (r == 0) {
/* check for non-deleted package names */
- struct apk_change *change;
foreach_array_item(change, changeset.changes) {
struct apk_package *pkg = change->new_pkg;
- struct apk_dependency *p;
if (pkg == NULL)
continue;
pkg->marked = 1;
- pkg->name->state_ptr = pkg;
- foreach_array_item(p, pkg->provides)
- p->name->state_ptr = pkg;
}
for (i = 0; i < argc; i++) {
- ndctx.pkg = name[i]->state_ptr;
ndctx.indent.indent = 0;
- foreach_reverse_dependency(
- name[i], APK_FOREACH_MARKED | APK_DEP_SATISFIES,
- print_not_deleted_message, &ndctx);
+ ndctx.name = name[i];
+ ndctx.matches = apk_foreach_genid() | APK_FOREACH_MARKED | APK_DEP_SATISFIES;
+ foreach_array_item(p, name[i]->providers) {
+ if (!p->pkg->marked)
+ continue;
+ print_not_deleted_message(p->pkg, NULL, NULL, &ndctx);
+ }
if (ndctx.indent.indent)
printf("\n");
}
diff --git a/src/package.c b/src/package.c
index 31321e7..0fca1db 100644
--- a/src/package.c
+++ b/src/package.c
@@ -1190,28 +1190,46 @@ int apk_pkg_version_compare(struct apk_package *a, struct apk_package *b)
return apk_version_compare_blob(*a->version, *b->version);
}
+unsigned int apk_foreach_genid(void)
+{
+ static unsigned int foreach_genid;
+ foreach_genid += (~APK_FOREACH_GENID_MASK) + 1;
+ return foreach_genid;
+}
+
void apk_pkg_foreach_matching_dependency(
- struct apk_package *pkg, struct apk_dependency_array *deps, int match, struct apk_package *mpkg,
+ struct apk_package *pkg, struct apk_dependency_array *deps,
+ unsigned int match, struct apk_package *mpkg,
void cb(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *ctx),
void *ctx)
{
+ unsigned int genid = match & APK_FOREACH_GENID_MASK;
struct apk_dependency *d;
+ if (genid && pkg->foreach_genid >= genid)
+ return;
+ if (pkg)
+ pkg->foreach_genid = genid;
+
foreach_array_item(d, deps) {
- if (apk_dep_analyze(d, mpkg) & match)
+ if (apk_dep_analyze(d, mpkg) & match) {
cb(pkg, d, mpkg, ctx);
+ if (genid)
+ break;
+ }
}
}
static void foreach_reverse_dependency(
struct apk_package *pkg,
struct apk_name_array *rdepends,
- int match,
+ unsigned 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;
+ unsigned int installed = match & APK_FOREACH_INSTALLED;
+ unsigned int marked = match & APK_FOREACH_MARKED;
+ unsigned int genid = match & APK_FOREACH_GENID_MASK;
struct apk_name **pname0, *name0;
struct apk_provider *p0;
struct apk_package *pkg0;
@@ -1225,6 +1243,9 @@ static void foreach_reverse_dependency(
continue;
if (marked && !pkg0->marked)
continue;
+ if (genid && pkg0->foreach_genid >= genid)
+ continue;
+ pkg0->foreach_genid = genid;
foreach_array_item(d0, pkg0->depends) {
if (apk_dep_analyze(d0, pkg) & match)
cb(pkg0, d0, pkg, ctx);
@@ -1234,7 +1255,7 @@ static void foreach_reverse_dependency(
}
void apk_pkg_foreach_reverse_dependency(
- struct apk_package *pkg, int match,
+ struct apk_package *pkg, unsigned int match,
void cb(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *ctx),
void *ctx)
{
diff --git a/src/search.c b/src/search.c
index 2f39f38..410becd 100644
--- a/src/search.c
+++ b/src/search.c
@@ -23,8 +23,8 @@ struct search_ctx {
int show_all : 1;
int search_exact : 1;
int search_description : 1;
- int rdep_generation;
+ unsigned int matches;
int argc;
char **argv;
};
@@ -53,19 +53,16 @@ static void print_origin_name(struct search_ctx *ctx, struct apk_package *pkg)
static void print_rdep_pkg(struct apk_package *pkg0, struct apk_dependency *dep0, struct apk_package *pkg, void *pctx)
{
struct search_ctx *ctx = (struct search_ctx *) pctx;
- if (pkg0->state_int == ctx->rdep_generation)
- return;
- pkg0->state_int = ctx->rdep_generation;
ctx->print_package(ctx, pkg0);
}
static void print_rdepends(struct search_ctx *ctx, struct apk_package *pkg)
{
if (apk_verbosity > 0) {
- ctx->rdep_generation++;
+ ctx->matches = apk_foreach_genid() | APK_DEP_SATISFIES;
printf(PKG_VER_FMT " is required by:\n", PKG_VER_PRINTF(pkg));
}
- apk_pkg_foreach_reverse_dependency(pkg, APK_DEP_SATISFIES, print_rdep_pkg, ctx);
+ apk_pkg_foreach_reverse_dependency(pkg, ctx->matches, print_rdep_pkg, ctx);
}
static int search_parse(void *ctx, struct apk_db_options *dbopts,
@@ -160,7 +157,7 @@ static int search_main(void *pctx, struct apk_database *db, int argc, char **arg
char s[256];
int i, l;
- ctx->rdep_generation = 1;
+ ctx->matches = apk_foreach_genid() | APK_DEP_SATISFIES;
if (ctx->print_package == NULL)
ctx->print_package = print_package_name;
if (ctx->print_result == NULL)