From 67f5a753e50da8737dc28b0ea2c2194b21d76fdd Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Sat, 4 Mar 2023 13:54:54 +0200 Subject: db, apps: sort display results based on package names --- src/apk_database.h | 16 +++++-- src/app_del.c | 21 ++++---- src/app_fetch.c | 21 ++++---- src/app_fix.c | 11 +++-- src/app_info.c | 9 ++-- src/app_list.c | 22 ++++----- src/app_manifest.c | 12 +++-- src/app_policy.c | 8 ++-- src/app_search.c | 9 ++-- src/app_upgrade.c | 7 +-- src/app_version.c | 16 +++---- src/commit.c | 2 +- src/database.c | 137 +++++++++++++++++++++++++++++++++++++++++------------ src/solver.c | 2 +- 14 files changed, 191 insertions(+), 102 deletions(-) diff --git a/src/apk_database.h b/src/apk_database.h index a0a62ca..194fe06 100644 --- a/src/apk_database.h +++ b/src/apk_database.h @@ -162,6 +162,7 @@ struct apk_database { int no_chroot : 1; int compat_newfeatures : 1; int compat_notinstallable : 1; + int sorted_names : 1; struct apk_dependency_array *world; struct apk_protected_path_array *protected_paths; @@ -175,6 +176,7 @@ struct apk_database { } repositories; struct { + struct apk_name_array *sorted_names; struct apk_hash names; struct apk_hash packages; } available; @@ -198,6 +200,10 @@ typedef union apk_database_or_void { void *ptr; } apk_database_t __attribute__ ((__transparent_union__)); +static inline int apk_name_cmp_display(const struct apk_name *a, const struct apk_name *b) { + return strcmp(a->name, b->name); +} + struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name); struct apk_name *apk_db_query_name(struct apk_database *db, apk_blob_t name); int apk_db_get_tag_id(struct apk_database *db, apk_blob_t tag); @@ -269,8 +275,12 @@ int apk_db_install_pkg(struct apk_database *db, struct apk_package *newpkg, apk_progress_cb cb, void *cb_ctx); -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); +typedef int (*apk_db_foreach_name_cb)(struct apk_database *db, const char *match, struct apk_name *name, void *ctx); + +int apk_db_foreach_matching_name(struct apk_database *db, struct apk_string_array *filter, + apk_db_foreach_name_cb cb, void *ctx); + +int apk_db_foreach_sorted_name(struct apk_database *db, struct apk_string_array *filter, + apk_db_foreach_name_cb cb, void *ctx); #endif diff --git a/src/app_del.c b/src/app_del.c index 7d3cf36..06deb43 100644 --- a/src/app_del.c +++ b/src/app_del.c @@ -85,12 +85,14 @@ static void print_not_deleted_pkg(struct apk_package *pkg0, struct apk_dependenc } } -static void print_not_deleted_name(struct apk_database *db, const char *match, - struct apk_name *name, void *pctx) +static int 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; + if (!name) return 0; + ctx->name = name; ctx->matches = apk_foreach_genid() | APK_FOREACH_MARKED | APK_DEP_SATISFIES; apk_print_indented_init(&ctx->indent, 0); @@ -98,6 +100,7 @@ static void print_not_deleted_name(struct apk_database *db, const char *match, if (p->pkg->marked) print_not_deleted_pkg(p->pkg, NULL, NULL, ctx); apk_print_indented_end(&ctx->indent); + return 0; } static void delete_pkg(struct apk_package *pkg0, struct apk_dependency *dep0, @@ -112,8 +115,8 @@ static void delete_pkg(struct apk_package *pkg0, struct apk_dependency *dep0, delete_pkg, pctx); } -static void delete_name(struct apk_database *db, const char *match, - struct apk_name *name, void *pctx) +static int delete_name(struct apk_database *db, const char *match, + struct apk_name *name, void *pctx) { struct del_ctx *ctx = (struct del_ctx *) pctx; struct apk_package *pkg; @@ -121,7 +124,7 @@ static void delete_name(struct apk_database *db, const char *match, if (!name) { apk_error("No such package: %s", match); ctx->errors++; - return; + return 0; } pkg = apk_pkg_get_installed(name); @@ -129,6 +132,7 @@ static void delete_name(struct apk_database *db, const char *match, delete_pkg(pkg, NULL, NULL, pctx); else apk_deps_del(&ctx->world, name); + return 0; } static int del_main(void *pctx, struct apk_database *db, struct apk_string_array *args) @@ -141,7 +145,7 @@ static int del_main(void *pctx, struct apk_database *db, struct apk_string_array int r = 0; apk_dependency_array_copy(&ctx->world, db->world); - apk_name_foreach_matching(db, args, apk_foreach_genid(), delete_name, ctx); + apk_db_foreach_matching_name(db, args, delete_name, ctx); if (ctx->errors) return ctx->errors; r = apk_solver_solve(db, 0, ctx->world, &changeset); @@ -152,10 +156,7 @@ static int del_main(void *pctx, struct apk_database *db, struct apk_string_array change->new_pkg->marked = 1; foreach_array_item(d, ctx->world) d->name->state_int = 1; - apk_name_foreach_matching( - db, args, - apk_foreach_genid() | APK_FOREACH_MARKED | APK_DEP_SATISFIES, - print_not_deleted_name, &ndctx); + apk_db_foreach_sorted_name(db, args, print_not_deleted_name, &ndctx); if (ndctx.header) printf("\n"); diff --git a/src/app_fetch.c b/src/app_fetch.c index 0cc1918..ea2ca13 100644 --- a/src/app_fetch.c +++ b/src/app_fetch.c @@ -235,7 +235,7 @@ static void mark_dep_flags(struct fetch_ctx *ctx, struct apk_dependency *dep) apk_deps_add(&ctx->world, dep); } -static void mark_name_flags(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) +static int mark_name_flags(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) { struct fetch_ctx *ctx = (struct fetch_ctx *) pctx; struct apk_dependency dep = (struct apk_dependency) { @@ -244,13 +244,15 @@ static void mark_name_flags(struct apk_database *db, const char *match, struct a .result_mask = APK_DEPMASK_ANY, }; - if (!IS_ERR_OR_NULL(name)) { - name->auto_select_virtual = 1; - apk_deps_add(&ctx->world, &dep); - } else { + if (!name) { ctx->errors++; mark_error(ctx, match, name); + return 0; } + + name->auto_select_virtual = 1; + apk_deps_add(&ctx->world, &dep); + return 0; } static void mark_names_recursive(struct apk_database *db, struct apk_string_array *args, void *pctx) @@ -271,7 +273,7 @@ static void mark_names_recursive(struct apk_database *db, struct apk_string_arra apk_change_array_free(&changeset.changes); } -static void mark_name(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) +static int mark_name(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) { struct apk_package *pkg = NULL; struct apk_provider *p; @@ -284,10 +286,11 @@ static void mark_name(struct apk_database *db, const char *match, struct apk_nam if (!pkg) goto err; mark_package(ctx, pkg); - return; + return 0; err: mark_error(ctx, match, name); + return 0; } static int purge_package(void *pctx, int dirfd, const char *filename) @@ -346,12 +349,12 @@ static int fetch_main(void *pctx, struct apk_database *db, struct apk_string_arr apk_dependency_array_init(&ctx->world); foreach_array_item(dep, db->world) mark_dep_flags(ctx, dep); - apk_name_foreach_matching(db, args, apk_foreach_genid(), mark_name_flags, ctx); + apk_db_foreach_matching_name(db, args, mark_name_flags, ctx); if (ctx->errors == 0) mark_names_recursive(db, args, ctx); apk_dependency_array_free(&ctx->world); } else { - apk_name_foreach_matching(db, args, apk_foreach_genid(), mark_name, ctx); + apk_db_foreach_matching_name(db, args, mark_name, ctx); } if (!ctx->errors) apk_hash_foreach(&db->available.packages, fetch_package, ctx); diff --git a/src/app_fix.c b/src/app_fix.c index ccd1e3c..5169176 100644 --- a/src/app_fix.c +++ b/src/app_fix.c @@ -74,15 +74,18 @@ static void mark_fix(struct fix_ctx *ctx, struct apk_name *name) apk_solver_set_name_flags(name, ctx->solver_flags, ctx->fix_depends ? ctx->solver_flags : 0); } -static void set_solver_flags(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) +static int set_solver_flags(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) { struct fix_ctx *ctx = pctx; if (!name) { apk_error("Package '%s' not found", match); ctx->errors++; - } else - mark_fix(ctx, name); + return 0; + } + + mark_fix(ctx, name); + return 0; } static int fix_main(void *pctx, struct apk_database *db, struct apk_string_array *args) @@ -103,7 +106,7 @@ static int fix_main(void *pctx, struct apk_database *db, struct apk_string_array mark_fix(ctx, ipkg->pkg->name); } } else - apk_name_foreach_matching(db, args, apk_foreach_genid(), set_solver_flags, ctx); + apk_db_foreach_matching_name(db, args, set_solver_flags, ctx); if (ctx->errors) return ctx->errors; diff --git a/src/app_info.c b/src/app_info.c index 8454f0f..2cdbad6 100644 --- a/src/app_info.c +++ b/src/app_info.c @@ -350,18 +350,19 @@ static void info_subaction(struct info_ctx *ctx, struct apk_package *pkg) } } -static void print_name_info(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) +static int print_name_info(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) { struct info_ctx *ctx = (struct info_ctx *) pctx; struct apk_provider *p; if (name == NULL) { ctx->errors++; - return; + return 0; } foreach_array_item(p, name->providers) info_subaction(ctx, p->pkg); + return 0; } #define INFO_OPTIONS(OPT) \ @@ -454,9 +455,7 @@ static int info_main(void *ctx, struct apk_database *db, struct apk_string_array ictx->action(ictx, db, args); } else if (args->num > 0) { /* Print info on given names */ - apk_name_foreach_matching( - db, args, APK_FOREACH_NULL_MATCHES_ALL | apk_foreach_genid(), - print_name_info, ctx); + apk_db_foreach_sorted_name(db, args, print_name_info, ctx); } else { /* Print all installed packages */ list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) diff --git a/src/app_list.c b/src/app_list.c index 0693f4b..13ab0a7 100644 --- a/src/app_list.c +++ b/src/app_list.c @@ -147,8 +147,7 @@ static void iterate_providers(const struct apk_name *name, const struct list_ctx { struct apk_provider *p; - foreach_array_item(p, name->providers) - { + foreach_array_item(p, name->providers) { if (!ctx->match_providers && p->pkg->name != name) continue; @@ -159,22 +158,20 @@ static void iterate_providers(const struct apk_name *name, const struct list_ctx } } -static void print_result(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) +static int print_result(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) { struct list_ctx *ctx = pctx; - if (name == NULL) - return; + if (!name) return 0; - if (ctx->match_depends) - { + if (ctx->match_depends) { struct apk_name **pname; - foreach_array_item(pname, name->rdepends) iterate_providers(*pname, ctx); - } - else + } else { iterate_providers(name, ctx); + } + return 0; } #define LIST_OPTIONS(OPT) \ @@ -242,10 +239,7 @@ static int list_main(void *pctx, struct apk_database *db, struct apk_string_arra if (ctx->match_origin) args = NULL; - apk_name_foreach_matching( - db, args, APK_FOREACH_NULL_MATCHES_ALL | apk_foreach_genid(), - print_result, ctx); - + apk_db_foreach_sorted_name(db, args, print_result, ctx); return 0; } diff --git a/src/app_manifest.c b/src/app_manifest.c index cd5b2ef..e476872 100644 --- a/src/app_manifest.c +++ b/src/app_manifest.c @@ -100,23 +100,25 @@ static void process_file(struct apk_database *db, const char *match) if (r < 0) apk_error("%s: %s", match, apk_error_str(r)); } -static void process_match(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) +static int process_match(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) { struct apk_provider *p; - if (name == NULL) - { + if (!name) { process_file(db, match); - return; + return 0; } foreach_array_item(p, name->providers) process_package(db, p->pkg); + + return 0; } static int manifest_main(void *ctx, struct apk_database *db, struct apk_string_array *args) { - apk_name_foreach_matching(db, args, apk_foreach_genid(), process_match, NULL); + if (!args->num) return 0; + apk_db_foreach_sorted_name(db, args, process_match, NULL); return 0; } diff --git a/src/app_policy.c b/src/app_policy.c index 954eb9d..519257a 100644 --- a/src/app_policy.c +++ b/src/app_policy.c @@ -15,13 +15,13 @@ extern const char * const apk_installed_file; -static void print_policy(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) +static int print_policy(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) { struct apk_provider *p; struct apk_repository *repo; int i, j, num = 0; - if (!name) return; + if (!name) return 0; /* zlib1g policy: @@ -58,11 +58,13 @@ zlib1g policy: } } } + return 0; } static int policy_main(void *ctx, struct apk_database *db, struct apk_string_array *args) { - apk_name_foreach_matching(db, args, apk_foreach_genid(), print_policy, NULL); + if (!args->num) return 0; + apk_db_foreach_sorted_name(db, args, print_policy, NULL); return 0; } diff --git a/src/app_search.c b/src/app_search.c index 866bb7a..3651ec6 100644 --- a/src/app_search.c +++ b/src/app_search.c @@ -143,13 +143,13 @@ match: ctx->print_result(ctx, pkg); } -static void print_result(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) +static int print_result(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) { struct search_ctx *ctx = pctx; struct apk_provider *p; struct apk_package *pkg = NULL; - if (!name) return; + if (!name) return 0; if (ctx->show_all) { foreach_array_item(p, name->providers) @@ -163,6 +163,7 @@ static void print_result(struct apk_database *db, const char *match, struct apk_ if (pkg) print_result_pkg(ctx, pkg); } + return 0; } static int print_pkg(apk_hash_item item, void *pctx) @@ -193,9 +194,7 @@ static int search_main(void *pctx, struct apk_database *db, struct apk_string_ar *pmatch = tmp; } } - apk_name_foreach_matching( - db, args, APK_FOREACH_NULL_MATCHES_ALL | apk_foreach_genid(), - print_result, ctx); + apk_db_foreach_sorted_name(db, args, print_result, ctx); return 0; } diff --git a/src/app_upgrade.c b/src/app_upgrade.c index bc6ccb1..c618cb6 100644 --- a/src/app_upgrade.c +++ b/src/app_upgrade.c @@ -136,17 +136,18 @@ ret: return r; } -static void set_upgrade_for_name(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) +static int set_upgrade_for_name(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) { struct upgrade_ctx *uctx = (struct upgrade_ctx *) pctx; if (!name) { apk_error("Package '%s' not found", match); uctx->errors++; - return; + return 0; } apk_solver_set_name_flags(name, uctx->ignore ? APK_SOLVERF_INSTALLED : APK_SOLVERF_UPGRADE, 0); + return 0; } static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_array *args) @@ -206,7 +207,7 @@ static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_ar if (args->num > 0) { /* if specific packages are listed, we don't want to upgrade world. */ if (!uctx->ignore) solver_flags &= ~APK_SOLVERF_UPGRADE; - apk_name_foreach_matching(db, args, apk_foreach_genid(), set_upgrade_for_name, uctx); + apk_db_foreach_matching_name(db, args, set_upgrade_for_name, uctx); if (uctx->errors) return uctx->errors; } diff --git a/src/app_version.c b/src/app_version.c index d5d9c88..2a8cdb8 100644 --- a/src/app_version.c +++ b/src/app_version.c @@ -107,7 +107,7 @@ static const struct apk_option_group optgroup_applet = { .parse = option_parse_applet, }; -static void ver_print_package_status(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) +static int ver_print_package_status(struct apk_database *db, const char *match, struct apk_name *name, void *pctx) { struct ver_ctx *ctx = (struct ver_ctx *) pctx; struct apk_package *pkg; @@ -119,10 +119,10 @@ static void ver_print_package_status(struct apk_database *db, const char *match, int i, r = -1; unsigned short tag, allowed_repos; - if (!name) return; + if (!name) return 0; pkg = apk_pkg_get_installed(name); - if (!pkg) return; + if (!pkg) return 0; tag = pkg->ipkg->repository_tag; allowed_repos = db->repo_tags[tag].allowed_repos; @@ -148,10 +148,10 @@ static void ver_print_package_status(struct apk_database *db, const char *match, : APK_VERSION_UNKNOWN; opstr = apk_version_op_string(r); if ((ctx->limchars != NULL) && (strchr(ctx->limchars, *opstr) == NULL)) - return; + return 0; if (apk_verbosity <= 0) { printf("%s\n", pkg->name->name); - return; + return 0; } tag = APK_DEFAULT_REPOSITORY_TAG; @@ -167,6 +167,7 @@ static void ver_print_package_status(struct apk_database *db, const char *match, pkgname, opstr, BLOB_PRINTF(*latest), BLOB_PRINTF(db->repo_tags[tag].tag)); + return 0; } static int ver_main(void *pctx, struct apk_database *db, struct apk_string_array *args) @@ -186,10 +187,7 @@ static int ver_main(void *pctx, struct apk_database *db, struct apk_string_array if (apk_verbosity > 0) printf("%-42sAvailable:\n", "Installed:"); - apk_name_foreach_matching( - db, args, APK_FOREACH_NULL_MATCHES_ALL | apk_foreach_genid(), - ver_print_package_status, ctx); - + apk_db_foreach_sorted_name(db, args, ver_print_package_status, ctx); return 0; } diff --git a/src/commit.c b/src/commit.c index f582ec2..79438db 100644 --- a/src/commit.c +++ b/src/commit.c @@ -155,7 +155,7 @@ static int sort_change(const void *a, const void *b) const struct apk_change *cb = b; const struct apk_name *na = ca->old_pkg ? ca->old_pkg->name : ca->new_pkg->name; const struct apk_name *nb = cb->old_pkg ? cb->old_pkg->name : cb->new_pkg->name; - return strcmp(na->name, nb->name); + return apk_name_cmp_display(na, nb); } static int cmp_remove(struct apk_change *change) diff --git a/src/database.c b/src/database.c index a4c7f97..3dc72f2 100644 --- a/src/database.c +++ b/src/database.c @@ -221,6 +221,7 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name) apk_name_array_init(&pn->rdepends); apk_name_array_init(&pn->rinstall_if); apk_hash_insert_hashed(&db->available.names, pn, hash); + db->sorted_names = 0; return pn; } @@ -1515,6 +1516,7 @@ void apk_db_init(struct apk_database *db) list_init(&db->installed.triggers); apk_dependency_array_init(&db->world); apk_protected_path_array_init(&db->protected_paths); + apk_name_array_init(&db->available.sorted_names); db->permanent = 1; db->root_fd = -1; } @@ -1836,6 +1838,7 @@ void apk_db_close(struct apk_database *db) apk_dependency_array_free(&db->world); + apk_name_array_free(&db->available.sorted_names); apk_hash_free(&db->available.packages); apk_hash_free(&db->available.names); apk_hash_free(&db->installed.files); @@ -2986,8 +2989,7 @@ ret_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); + apk_db_foreach_name_cb cb; void *cb_ctx; }; @@ -2995,16 +2997,9 @@ 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) { + if (!ctx->filter->num) { ctx->cb(ctx->db, NULL, name, ctx->cb_ctx); return 0; } @@ -3012,50 +3007,132 @@ static int match_names(apk_hash_item item, void *pctx) foreach_array_item(pmatch, ctx->filter) { if (fnmatch(*pmatch, name->name, 0) == 0) { ctx->cb(ctx->db, *pmatch, name, ctx->cb_ctx); - if (genid) - break; + 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) +int apk_db_foreach_matching_name(struct apk_database *db, struct apk_string_array *filter, + apk_db_foreach_name_cb cb, 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, }; + int r; + + if (!filter || !filter->num) return 0; - if (filter == NULL || filter->num == 0) { - if (!(match & APK_FOREACH_NULL_MATCHES_ALL)) - return; - 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 (genid && name) { - if (name->foreach_genid >= genid) + r = cb(db, *pmatch, name, ctx); + if (r) return r; + } + return 0; + +all: + return apk_hash_foreach(&db->available.names, match_names, &mctx); +} + +static int cmp_name(const void *a, const void *b) +{ + const struct apk_name * const* na = a, * const* nb = b; + return apk_name_cmp_display(*na, *nb); +} + +struct add_name_ctx { + struct apk_name_array *a; + size_t i; +}; + +static int add_name(apk_hash_item item, void *ctx) +{ + struct apk_name *name = (struct apk_name *) item; + struct add_name_ctx *a = ctx; + a->a->item[a->i++] = name; + return 0; +} + +static struct apk_name_array *apk_db_sorted_names(struct apk_database *db) +{ + if (!db->sorted_names) { + apk_name_array_resize(&db->available.sorted_names, db->available.names.num_items); + + struct add_name_ctx ctx = { .a = db->available.sorted_names, .i = 0 }; + apk_hash_foreach(&db->available.names, add_name, &ctx); + + qsort(db->available.sorted_names->item, db->available.sorted_names->num, + sizeof(db->available.sorted_names->item[0]), cmp_name); + db->sorted_names = 1; + } + return db->available.sorted_names; +} + +int apk_db_foreach_sorted_name(struct apk_database *db, struct apk_string_array *filter, + apk_db_foreach_name_cb cb, void *cb_ctx) +{ + int walk_all = 0; + char **pmatch; + struct apk_name *name; + struct apk_name *results[128], **res; + size_t i, num_res = 0; + int r; + + if (filter && filter->num) { + foreach_array_item(pmatch, filter) { + name = (struct apk_name *) apk_hash_get(&db->available.names, APK_BLOB_STR(*pmatch)); + if (strchr(*pmatch, '*')) { + walk_all = 1; + continue; + } + if (!name) { + cb(db, *pmatch, NULL, cb_ctx); + continue; + } + if (walk_all) continue; + if (num_res >= ARRAY_SIZE(results)) { + walk_all = 1; continue; - name->foreach_genid = genid; + } + results[num_res++] = name; } - cb(db, *pmatch, name, ctx); + } else { + walk_all = 1; + filter = NULL; } - return; -all: - apk_hash_foreach(&db->available.names, match_names, &mctx); + if (walk_all) { + struct apk_name_array *a = apk_db_sorted_names(db); + res = a->item; + num_res = a->num; + } else { + qsort(results, num_res, sizeof results[0], cmp_name); + res = results; + } + + for (i = 0; i < num_res; i++) { + name = res[i]; + if (!filter || !filter->num) { + cb(db, NULL, name, cb_ctx); + continue; + } + foreach_array_item(pmatch, filter) { + if (fnmatch(*pmatch, name->name, 0) == 0) { + r = cb(db, *pmatch, name, cb_ctx); + break; + } + } + if (r) return r; + } + return 0; } diff --git a/src/solver.c b/src/solver.c index 8021df2..345656c 100644 --- a/src/solver.c +++ b/src/solver.c @@ -1024,7 +1024,7 @@ static int free_package(apk_hash_item item, void *ctx) static int cmp_pkgname(const void *p1, const void *p2) { const struct apk_dependency *d1 = p1, *d2 = p2; - return strcmp(d1->name->name, d2->name->name); + return apk_name_cmp_display(d1->name, d2->name); } static int compare_name_dequeue(const struct apk_name *a, const struct apk_name *b) -- cgit v1.2.3-60-g2f50