summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2013-06-19 14:49:44 +0300
committerTimo Teräs <timo.teras@iki.fi>2013-06-19 14:49:44 +0300
commit9c54ef726c624a4635c0b1a8160baab7b575df62 (patch)
treee048e0c62e066811b20b273c211f35fa77cc22bf
parenta984fd3679ef83edd8bd98f55233e5eb12f0faf0 (diff)
fetch, del: perform wildcard matching
ref #511
-rw-r--r--src/del.c86
-rw-r--r--src/fetch.c94
2 files changed, 92 insertions, 88 deletions
diff --git a/src/del.c b/src/del.c
index 02d34a7..e8dec56 100644
--- a/src/del.c
+++ b/src/del.c
@@ -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;