diff options
author | Timo Teräs <timo.teras@iki.fi> | 2013-06-18 13:01:51 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2013-06-18 13:02:27 +0300 |
commit | fe41ae07b90bbd4609ee6871def851a41027aae8 (patch) | |
tree | 7f5a872c5ee030450e3cfdb84a73c9338f69d7f4 /src/database.c | |
parent | c51d82f8f616c2c8939b74c1d78f723ef778f0c8 (diff) | |
download | apk-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.c | 77 |
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); +} |