diff options
-rw-r--r-- | src/apk_package.h | 20 | ||||
-rw-r--r-- | src/del.c | 71 | ||||
-rw-r--r-- | src/package.c | 33 | ||||
-rw-r--r-- | src/search.c | 11 |
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); @@ -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) |