summaryrefslogtreecommitdiff
path: root/src/database.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2013-06-18 13:01:51 +0300
committerTimo Teräs <timo.teras@iki.fi>2013-06-18 13:02:27 +0300
commitfe41ae07b90bbd4609ee6871def851a41027aae8 (patch)
tree7f5a872c5ee030450e3cfdb84a73c9338f69d7f4 /src/database.c
parentc51d82f8f616c2c8939b74c1d78f723ef778f0c8 (diff)
downloadapk-tools-fe41ae07b90bbd4609ee6871def851a41027aae8.tar.gz
apk-tools-fe41ae07b90bbd4609ee6871def851a41027aae8.tar.bz2
apk-tools-fe41ae07b90bbd4609ee6871def851a41027aae8.tar.xz
apk-tools-fe41ae07b90bbd4609ee6871def851a41027aae8.zip
apk: use string array in applet mains, separate apk_name_foreach_matching
Diffstat (limited to 'src/database.c')
-rw-r--r--src/database.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/database.c b/src/database.c
index 964bc22..1d10d59 100644
--- a/src/database.c
+++ b/src/database.c
@@ -2673,3 +2673,80 @@ ret_r:
free(script_args[2]);
return r;
}
+
+struct match_ctx {
+ struct apk_database *db;
+ struct apk_string_array *filter;
+ unsigned int match;
+ void (*cb)(struct apk_database *db, const char *match, struct apk_name *name, void *ctx);
+ void *cb_ctx;
+};
+
+static int match_names(apk_hash_item item, void *pctx)
+{
+ struct match_ctx *ctx = (struct match_ctx *) pctx;
+ struct apk_name *name = (struct apk_name *) item;
+ unsigned int genid = ctx->match & APK_FOREACH_GENID_MASK;
+ char **pmatch;
+
+ if (genid) {
+ if (name->foreach_genid >= genid)
+ return 0;
+ name->foreach_genid = genid;
+ }
+
+ if (ctx->filter->num == 0) {
+ ctx->cb(ctx->db, NULL, name, ctx->cb_ctx);
+ return 0;
+ }
+
+ foreach_array_item(pmatch, ctx->filter) {
+ if (fnmatch(*pmatch, name->name, FNM_CASEFOLD) == 0) {
+ ctx->cb(ctx->db, *pmatch, name, ctx->cb_ctx);
+ if (genid)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+void apk_name_foreach_matching(struct apk_database *db, struct apk_string_array *filter, unsigned int match,
+ void (*cb)(struct apk_database *db, const char *match, struct apk_name *name, void *ctx),
+ void *ctx)
+{
+ char **pmatch;
+ unsigned int genid = match & APK_FOREACH_GENID_MASK;
+ struct apk_name *name;
+ struct match_ctx mctx = {
+ .db = db,
+ .filter = filter,
+ .match = match,
+ .cb = cb,
+ .cb_ctx = ctx,
+ };
+
+ if (filter == NULL || filter->num == 0) {
+ apk_string_array_init(&mctx.filter);
+ goto all;
+ }
+ foreach_array_item(pmatch, filter)
+ if (strchr(*pmatch, '*') != NULL)
+ goto all;
+
+ foreach_array_item(pmatch, filter) {
+ name = (struct apk_name *) apk_hash_get(&db->available.names, APK_BLOB_STR(*pmatch));
+ if (name == NULL)
+ continue;
+ if (genid) {
+ if (name->foreach_genid >= genid)
+ continue;
+ name->foreach_genid = genid;
+ }
+ cb(db, *pmatch, name, ctx);
+ }
+ return;
+
+all:
+ apk_hash_foreach(&db->available.names, match_names, &mctx);
+}