diff options
author | Timo Teräs <timo.teras@iki.fi> | 2013-06-19 14:49:44 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2013-06-19 14:49:44 +0300 |
commit | 9c54ef726c624a4635c0b1a8160baab7b575df62 (patch) | |
tree | e048e0c62e066811b20b273c211f35fa77cc22bf | |
parent | a984fd3679ef83edd8bd98f55233e5eb12f0faf0 (diff) | |
download | apk-tools-9c54ef726c624a4635c0b1a8160baab7b575df62.tar.gz apk-tools-9c54ef726c624a4635c0b1a8160baab7b575df62.tar.bz2 apk-tools-9c54ef726c624a4635c0b1a8160baab7b575df62.tar.xz apk-tools-9c54ef726c624a4635c0b1a8160baab7b575df62.zip |
fetch, del: perform wildcard matching
ref #511
-rw-r--r-- | src/del.c | 86 | ||||
-rw-r--r-- | src/fetch.c | 94 |
2 files changed, 92 insertions, 88 deletions
@@ -42,9 +42,8 @@ struct not_deleted_ctx { int header; }; -static void print_not_deleted_message( - struct apk_package *pkg0, struct apk_dependency *dep0, - struct apk_package *pkg, void *pctx) +static void print_not_deleted_pkg(struct apk_package *pkg0, struct apk_dependency *dep0, + struct apk_package *pkg, void *pctx) { struct not_deleted_ctx *ctx = (struct not_deleted_ctx *) pctx; @@ -58,76 +57,73 @@ static void print_not_deleted_message( } apk_print_indented(&ctx->indent, APK_BLOB_STR(pkg0->name->name)); - apk_pkg_foreach_reverse_dependency(pkg0, ctx->matches, print_not_deleted_message, pctx); + apk_pkg_foreach_reverse_dependency(pkg0, ctx->matches, print_not_deleted_pkg, pctx); } -static void delete_from_world( - struct apk_package *pkg0, struct apk_dependency *dep0, - struct apk_package *pkg, void *pctx) +static void print_not_deleted_name(struct apk_database *db, const char *match, + struct apk_name *name, void *pctx) +{ + struct not_deleted_ctx *ctx = (struct not_deleted_ctx *) pctx; + struct apk_provider *p; + + ctx->indent.indent = 0; + ctx->name = name; + ctx->matches = apk_foreach_genid() | APK_FOREACH_MARKED | APK_DEP_SATISFIES; + foreach_array_item(p, name->providers) + if (p->pkg->marked) + print_not_deleted_pkg(p->pkg, NULL, NULL, ctx); + if (ctx->indent.indent) + printf("\n"); +} + +static void delete_pkg(struct apk_package *pkg0, struct apk_dependency *dep0, + struct apk_package *pkg, void *pctx) { struct del_ctx *ctx = (struct del_ctx *) pctx; apk_deps_del(&ctx->world, pkg0->name); - if (ctx->recursive_delete) apk_pkg_foreach_reverse_dependency( pkg0, APK_FOREACH_INSTALLED | APK_DEP_SATISFIES, - delete_from_world, pctx); + delete_pkg, pctx); +} + +static void delete_name(struct apk_database *db, const char *match, + struct apk_name *name, void *pctx) +{ + struct apk_package *pkg; + + pkg = apk_pkg_get_installed(name); + if (pkg != NULL) + delete_pkg(pkg, NULL, NULL, pctx); } static int del_main(void *pctx, struct apk_database *db, struct apk_string_array *args) { struct del_ctx *ctx = (struct del_ctx *) pctx; struct not_deleted_ctx ndctx = {}; - struct apk_name_array *names; - struct apk_name **pname; - struct apk_package *pkg; struct apk_changeset changeset = {}; struct apk_change *change; - struct apk_provider *p; - int r = 0, i; + int r = 0; - apk_name_array_init(&names); - apk_name_array_resize(&names, args->num); apk_dependency_array_copy(&ctx->world, db->world); - - for (i = 0; i < args->num; i++) { - names->item[i] = apk_db_get_name(db, APK_BLOB_STR(args->item[i])); - pkg = apk_pkg_get_installed(names->item[i]); - if (pkg != NULL) - delete_from_world(pkg, NULL, NULL, ctx); - } - + apk_name_foreach_matching(db, args, apk_foreach_genid(), delete_name, ctx); r = apk_solver_solve(db, 0, ctx->world, &changeset); if (r == 0) { /* check for non-deleted package names */ - foreach_array_item(change, changeset.changes) { - struct apk_package *pkg = change->new_pkg; - if (pkg == NULL) - continue; - pkg->marked = 1; - } - foreach_array_item(pname, names) { - ndctx.indent.indent = 0; - ndctx.name = *pname; - ndctx.matches = apk_foreach_genid() | APK_FOREACH_MARKED | APK_DEP_SATISFIES; - foreach_array_item(p, (*pname)->providers) { - if (!p->pkg->marked) - continue; - print_not_deleted_message(p->pkg, NULL, NULL, &ndctx); - } - if (ndctx.indent.indent) - printf("\n"); - } + foreach_array_item(change, changeset.changes) + if (change->new_pkg != NULL) + change->new_pkg->marked = 1; + apk_name_foreach_matching(db, args, apk_foreach_genid(), + print_not_deleted_name, &ndctx); if (ndctx.header) printf("\n"); - apk_solver_commit_changeset(db, &changeset, ctx->world); - r = 0; + + r = apk_solver_commit_changeset(db, &changeset, ctx->world); } else { apk_solver_print_errors(db, &changeset, ctx->world); } apk_dependency_array_free(&ctx->world); - apk_name_array_free(&names); return r; } diff --git a/src/fetch.c b/src/fetch.c index 7891ac2..c3f6e3b 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -187,13 +187,59 @@ static void mark_package(struct fetch_ctx *ctx, struct apk_package *pkg) pkg->marked = 1; } -static int fetch_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +static void mark_error(struct fetch_ctx *ctx, const char *match, struct apk_name *name) { - struct fetch_ctx *ctx = (struct fetch_ctx *) pctx; + if (strchr(match, '*') != NULL) + return; + + apk_message("%s: unable to select package (or it's dependencies)", name->name); + ctx->errors++; +} + +static void mark_name_recursive(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) +{ + struct apk_changeset changeset = {}; + struct apk_dependency dep = (struct apk_dependency) { + .name = name, + .version = &apk_null_blob, + .result_mask = APK_DEPMASK_ANY, + }; struct apk_dependency_array *world; struct apk_change *change; - char **parg; - int r = 0; + int r; + + apk_dependency_array_init(&world); + *apk_dependency_array_add(&world) = dep; + r = apk_solver_solve(db, 0, world, &changeset); + apk_dependency_array_free(&world); + if (r == 0) { + foreach_array_item(change, changeset.changes) + mark_package(ctx, change->new_pkg); + } else + mark_error(ctx, match, name); + + apk_change_array_free(&changeset.changes); +} + +static void mark_name(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) +{ + struct apk_package *pkg = NULL; + struct apk_provider *p; + + foreach_array_item(p, name->providers) + if (pkg == NULL || apk_pkg_version_compare(p->pkg, pkg) == APK_VERSION_GREATER) + pkg = p->pkg; + + if (pkg != NULL) + mark_package(ctx, pkg); + else + mark_error(ctx, match, name); +} + +static int fetch_main(void *pctx, struct apk_database *db, struct apk_string_array *args) +{ + struct fetch_ctx *ctx = (struct fetch_ctx *) pctx; + void *mark = (ctx->flags & FETCH_RECURSIVE) ? mark_name_recursive : mark_name; if (ctx->outdir_fd == 0) ctx->outdir_fd = AT_FDCWD; @@ -205,46 +251,8 @@ static int fetch_main(void *pctx, struct apk_database *db, struct apk_string_arr return 0; } - foreach_array_item(parg, args) { - struct apk_dependency dep = (struct apk_dependency) { - .name = apk_db_get_name(db, APK_BLOB_STR(*parg)), - .version = apk_blob_atomize(APK_BLOB_NULL), - .result_mask = APK_DEPMASK_ANY, - }; - - if (ctx->flags & FETCH_RECURSIVE) { - struct apk_changeset changeset = {}; - - apk_dependency_array_init(&world); - *apk_dependency_array_add(&world) = dep; - r = apk_solver_solve(db, 0, world, &changeset); - apk_dependency_array_free(&world); - if (r != 0) { - apk_error("%s: unable to get dependencies", dep.name->name); - ctx->errors++; - } else { - foreach_array_item(change, changeset.changes) - mark_package(ctx, change->new_pkg); - } - apk_change_array_free(&changeset.changes); - } else { - struct apk_package *pkg = NULL; - struct apk_provider *p; - - foreach_array_item(p, dep.name->providers) - if (pkg == NULL || apk_pkg_version_compare(p->pkg, pkg) == APK_VERSION_GREATER) - pkg = p->pkg; - - if (pkg == NULL) { - apk_message("%s: unable to select a version", dep.name->name); - ctx->errors++; - } else { - mark_package(ctx, pkg); - } - } - } - ctx->db = db; + apk_name_foreach_matching(db, args, apk_foreach_genid(), mark, ctx); apk_hash_foreach(&db->available.packages, fetch_package, ctx); return ctx->errors; |