From a945cfbf35f48882c9e82129672f5ef84be92651 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 30 May 2015 01:43:18 +0200 Subject: [PATCH] Rework shlibs API to use a generic string hash map Plan is to turn other structures to use the same string hash map reducing the API and simplifying the code as well as allow accessing the content this map directly from the frontend without having to write ont getter per structure --- libpkg/pkg.c | 88 +++++++++++++++++++++++++++++---------------- libpkg/pkg.h.in | 13 ++++--- libpkg/pkg_attributes.c | 22 ------------ libpkg/pkg_checksum.c | 16 ++++----- libpkg/pkg_elf.c | 22 +++++++----- libpkg/pkg_jobs.c | 52 ++++++++++++++------------- libpkg/pkg_jobs_universe.c | 32 +++++++++-------- libpkg/pkg_manifest.c | 14 ++++---- libpkg/pkg_printf.c | 30 ++++++++-------- libpkg/pkg_solve.c | 24 ++++++------- libpkg/pkgdb.c | 20 +++++------ libpkg/private/pkg.h | 14 +++----- libpkg/repo/binary/update.c | 24 ++++++------- src/check.c | 12 ++++--- src/query.c | 17 +++++---- 15 files changed, 203 insertions(+), 197 deletions(-) diff --git a/libpkg/pkg.c b/libpkg/pkg.c index aa61faf..d95105c 100644 --- a/libpkg/pkg.c +++ b/libpkg/pkg.c @@ -549,20 +549,36 @@ pkg_options(const struct pkg *pkg, struct pkg_option **o) HASH_NEXT(pkg->options, (*o)); } -int -pkg_shlibs_required(const struct pkg *pkg, struct pkg_shlib **s) +char * +pkg_shlibs_required(const struct pkg *pkg, uint32_t *idx) { - assert(pkg != NULL); + khint_t k = *idx; + + if (k > kh_end(pkg->shlibs_required)) + return (NULL); - HASH_NEXT(pkg->shlibs_required, (*s)); + while (!kh_exist(pkg->shlibs_required, k) && + k != kh_end(pkg->shlibs_required)) + k++; + + *idx = k + 1; + return (kh_value(pkg->shlibs_required, k)); } -int -pkg_shlibs_provided(const struct pkg *pkg, struct pkg_shlib **s) +char * +pkg_shlibs_provided(const struct pkg *pkg, uint32_t *idx) { - assert(pkg != NULL); + khint_t k = *idx; + + if (k > kh_end(pkg->shlibs_provided)) + return (NULL); - HASH_NEXT(pkg->shlibs_provided, (*s)); + while (!kh_exist(pkg->shlibs_provided, k) && + k != kh_end(pkg->shlibs_provided)) + k++; + + *idx = k + 1; + return (kh_value(pkg->shlibs_provided, k)); } int @@ -1148,22 +1164,24 @@ pkg_addoption_description(struct pkg *pkg, const char *key, int pkg_addshlib_required(struct pkg *pkg, const char *name) { - struct pkg_shlib *s = NULL, *f; + char *val; + khint_t k; + int ret; assert(pkg != NULL); assert(name != NULL && name[0] != '\0'); - pkg_shlib_new(&s); - s->name = strdup(name); + if (pkg->shlibs_required == NULL) + pkg->shlibs_required = kh_init_strhash(); - HASH_FIND_STR(pkg->shlibs_required, s->name, f); - /* silently ignore duplicates in case of shlibs */ - if (f != NULL) { - pkg_shlib_free(s); + val = strdup(name); + + k = kh_put_strhash(pkg->shlibs_required, val, &ret); + if (ret == 0) { + free(val); return (EPKG_OK); } - - HASH_ADD_KEYPTR(hh, pkg->shlibs_required, s->name, strlen(s->name), s); + kh_value(pkg->shlibs_required, k) = val; pkg_debug(3, "added shlib deps for %s on %s", pkg->name, name); @@ -1173,7 +1191,9 @@ pkg_addshlib_required(struct pkg *pkg, const char *name) int pkg_addshlib_provided(struct pkg *pkg, const char *name) { - struct pkg_shlib *s = NULL, *f; + char *val; + khint_t k; + int ret; assert(pkg != NULL); assert(name != NULL && name[0] != '\0'); @@ -1182,16 +1202,16 @@ pkg_addshlib_provided(struct pkg *pkg, const char *name) if (strncmp(name, "lib", 3) != 0) return (EPKG_OK); - pkg_shlib_new(&s); - s->name = strdup(name); - HASH_FIND_STR(pkg->shlibs_provided, s->name, f); - /* silently ignore duplicates in case of shlibs */ - if (f != NULL) { - pkg_shlib_free(s); + if (pkg->shlibs_provided == NULL) + pkg->shlibs_provided = kh_init_strhash(); + + val = strdup(name); + k = kh_put_strhash(pkg->shlibs_provided, val, &ret); + if (ret == 0) { + free(val); return (EPKG_OK); } - - HASH_ADD_KEYPTR(hh, pkg->shlibs_provided, s->name, strlen(s->name), s); + kh_value(pkg->shlibs_provided, k) = val; pkg_debug(3, "added shlib provide %s for %s", name, pkg->name); @@ -1324,9 +1344,13 @@ pkg_list_count(const struct pkg *pkg, pkg_list list) case PKG_GROUPS: return (HASH_COUNT(pkg->groups)); case PKG_SHLIBS_REQUIRED: - return (HASH_COUNT(pkg->shlibs_required)); + if (pkg->shlibs_required == NULL) + return (0); + return (kh_size(pkg->shlibs_required)); case PKG_SHLIBS_PROVIDED: - return (HASH_COUNT(pkg->shlibs_provided)); + if (pkg->shlibs_provided == NULL) + return (0); + return (kh_size(pkg->shlibs_provided)); case PKG_CONFLICTS: return (HASH_COUNT(pkg->conflicts)); case PKG_PROVIDES: @@ -1342,6 +1366,8 @@ pkg_list_count(const struct pkg *pkg, pkg_list list) void pkg_list_free(struct pkg *pkg, pkg_list list) { + char *val; + switch (list) { case PKG_DEPS: HASH_FREE(pkg->deps, pkg_dep_free); @@ -1374,11 +1400,13 @@ pkg_list_free(struct pkg *pkg, pkg_list list) { pkg->flags &= ~PKG_LOAD_GROUPS; break; case PKG_SHLIBS_REQUIRED: - HASH_FREE(pkg->shlibs_required, pkg_shlib_free); + kh_foreach_value(pkg->shlibs_required, val, free(val)); + kh_destroy_strhash(pkg->shlibs_required); pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED; break; case PKG_SHLIBS_PROVIDED: - HASH_FREE(pkg->shlibs_provided, pkg_shlib_free); + kh_foreach_value(pkg->shlibs_provided, val, free(val)); + kh_destroy_strhash(pkg->shlibs_provided); pkg->flags &= ~PKG_LOAD_SHLIBS_PROVIDED; break; case PKG_CONFLICTS: diff --git a/libpkg/pkg.h.in b/libpkg/pkg.h.in index a59af2b..9947469 100644 --- a/libpkg/pkg.h.in +++ b/libpkg/pkg.h.in @@ -101,7 +101,6 @@ struct pkg_option; struct pkg_license; struct pkg_user; struct pkg_group; -struct pkg_shlib; struct pkg_provide; struct pkg_config_file; @@ -634,17 +633,17 @@ int pkg_options(const struct pkg *, struct pkg_option **option); /** * Iterates over the shared libraries used by the package. - * @param shlib must be set to NULL for the first call. - * @return An error code + * @param i index (first should be 0) + * @return the required lib */ -int pkg_shlibs_required(const struct pkg *pkg, struct pkg_shlib **shlib); +char *pkg_shlibs_required(const struct pkg *pkg, uint32_t *i); /** * Iterates over the shared libraries provided by the package. - * @param shlib must be set to NULL for the first call. - * @return An error code + * @param i index (first should be 0) + * @return the provided lib */ -int pkg_shlibs_provided(const struct pkg *pkg, struct pkg_shlib **shlib); +char *pkg_shlibs_provided(const struct pkg *pkg, uint32_t *i); /** * Iterates over the conflicts registered in the package. diff --git a/libpkg/pkg_attributes.c b/libpkg/pkg_attributes.c index b0e58d2..28f31e2 100644 --- a/libpkg/pkg_attributes.c +++ b/libpkg/pkg_attributes.c @@ -217,28 +217,6 @@ pkg_option_free(struct pkg_option *option) } /* - * Shared Libraries - */ -int -pkg_shlib_new(struct pkg_shlib **sl) -{ - if ((*sl = calloc(1, sizeof(struct pkg_shlib))) == NULL) - return (EPKG_FATAL); - - return (EPKG_OK); -} - -void -pkg_shlib_free(struct pkg_shlib *sl) -{ - if (sl == NULL) - return; - - free(sl->name); - free(sl); -} - -/* * Conflicts */ diff --git a/libpkg/pkg_checksum.c b/libpkg/pkg_checksum.c index b7370bc..16eba2a 100644 --- a/libpkg/pkg_checksum.c +++ b/libpkg/pkg_checksum.c @@ -189,11 +189,10 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen, pkg_checksum_type_t type) { unsigned char *bdigest; - char *olduid; + char *olduid, *val; size_t blen; struct pkg_checksum_entry *entries = NULL; struct pkg_option *option = NULL; - struct pkg_shlib *shlib = NULL; struct pkg_user *user = NULL; struct pkg_group *group = NULL; struct pkg_dep *dep = NULL; @@ -213,14 +212,13 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen, pkg_checksum_add_entry(option->key, option->value, &entries); } - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { - pkg_checksum_add_entry("required_shlib", shlib->name, &entries); - } + kh_foreach_value(pkg->shlibs_required, val, { + pkg_checksum_add_entry("required_shlib", val, &entries); + }); - shlib = NULL; - while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) { - pkg_checksum_add_entry("provided_shlib", shlib->name, &entries); - } + kh_foreach_value(pkg->shlibs_provided, val, { + pkg_checksum_add_entry("provided_shlib", val, &entries); + }); while (pkg_users(pkg, &user) == EPKG_OK) { pkg_checksum_add_entry("user", user->name, &entries); diff --git a/libpkg/pkg_elf.c b/libpkg/pkg_elf.c index e0d0151..dfd806a 100644 --- a/libpkg/pkg_elf.c +++ b/libpkg/pkg_elf.c @@ -439,10 +439,11 @@ int pkg_analyse_files(struct pkgdb *db, struct pkg *pkg, const char *stage) { struct pkg_file *file = NULL; - struct pkg_shlib *sh, *shtmp, *found; int ret = EPKG_OK; char fpath[MAXPATHLEN]; bool failures = false; + char *val; + khint_t k; pkg_list_free(pkg, PKG_SHLIBS_REQUIRED); pkg_list_free(pkg, PKG_SHLIBS_PROVIDED); @@ -481,22 +482,25 @@ pkg_analyse_files(struct pkgdb *db, struct pkg *pkg, const char *stage) /* * Do not depend on libraries that a package provides itself */ - HASH_ITER(hh, pkg->shlibs_required, sh, shtmp) { - HASH_FIND_STR(pkg->shlibs_provided, sh->name, found); - if (found != NULL) { + kh_foreach_value(pkg->shlibs_provided, val, { + k = kh_get_strhash(pkg->shlibs_required, val); + if (k != kh_end(pkg->shlibs_required)) { pkg_debug(2, "remove %s from required shlibs as the " "package %s provides this library itself", - sh->name, pkg->name); - HASH_DEL(pkg->shlibs_required, sh); + kh_value(pkg->shlibs_required, k), pkg->name); + kh_del_strhash(pkg->shlibs_required, k); } - } + }); /* * if the package is not supposed to provide share libraries then * drop the provided one */ - if (pkg_kv_get(&pkg->annotations, "no_provide_shlib") != NULL) - HASH_FREE(pkg->shlibs_provided, pkg_shlib_free); + if (pkg_kv_get(&pkg->annotations, "no_provide_shlib") != NULL) { + kh_foreach_value(pkg->shlibs_provided, val, free(val)); + kh_destroy_strhash(pkg->shlibs_provided); + pkg->shlibs_provided = NULL; + } if (failures) goto cleanup; diff --git a/libpkg/pkg_jobs.c b/libpkg/pkg_jobs.c index 6587a46..946fe78 100644 --- a/libpkg/pkg_jobs.c +++ b/libpkg/pkg_jobs.c @@ -1038,9 +1038,10 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp) int ret, ret1, ret2; struct pkg_option *lo = NULL, *ro = NULL; struct pkg_dep *ld = NULL, *rd = NULL; - struct pkg_shlib *ls = NULL, *rs = NULL; struct pkg_conflict *lc = NULL, *rc = NULL; struct pkg_provide *lpr = NULL, *rpr = NULL; + uint32_t li, ri; + char *lval, *rval; /* If no local package, then rp is obviously need to be added */ if (lp == NULL) @@ -1201,45 +1202,46 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp) /* Finish by the shlibs */ for (;;) { - ret1 = pkg_shlibs_provided(rp, &rs); - ret2 = pkg_shlibs_provided(lp, &ls); - if (ret1 != ret2) { + ri = li = 0; + rval = pkg_shlibs_provided(rp, &ri); + lval = pkg_shlibs_provided(lp, &li); + if (rval == NULL && lval == NULL) + break; + if ((rval == NULL && lval != NULL) || + (rval != NULL && lval == NULL)) { free(rp->reason); rp->reason = strdup("provided shared library changed"); return (true); } - if (ret1 == EPKG_OK) { - if (strcmp(rs->name, ls->name) != 0) { - free(rp->reason); - rp->reason = strdup("provided shared library changed"); - pkg_debug(1, "provided shlib changed %s -> %s", - ls->name, rs->name); + + if (strcmp(rval, lval) != 0) { + free(rp->reason); + rp->reason = strdup("provided shared library changed"); + pkg_debug(1, "provided shlib changed %s -> %s", + lval, rval); return (true); - } } - else - break; } for (;;) { - ret1 = pkg_shlibs_required(rp, &rs); - ret2 = pkg_shlibs_required(lp, &ls); - if (ret1 != ret2) { + ri = li = 0; + rval = pkg_shlibs_required(rp, &ri); + lval = pkg_shlibs_required(lp, &li); + if (rval == NULL && lval == NULL) + break; + if ((rval == NULL && lval != NULL) || + (rval != NULL && lval == NULL)) { free(rp->reason); rp->reason = strdup("needed shared library changed"); return (true); } - if (ret1 == EPKG_OK) { - if (strcmp(rs->name, ls->name) != 0) { - free(rp->reason); - rp->reason = strdup("needed shared library changed"); - pkg_debug(1, "Required shlib changed %s -> %s", - ls->name, rs->name); + if (strcmp(rval, lval) != 0) { + free(rp->reason); + rp->reason = strdup("needed shared library changed"); + pkg_debug(1, "Required shlib changed %s -> %s", + lval, rval); return (true); - } } - else - break; } return (false); diff --git a/libpkg/pkg_jobs_universe.c b/libpkg/pkg_jobs_universe.c index 7f025d2..f003901 100644 --- a/libpkg/pkg_jobs_universe.c +++ b/libpkg/pkg_jobs_universe.c @@ -432,45 +432,47 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe, static int pkg_jobs_universe_process_shlibs(struct pkg_jobs_universe *universe, - struct pkg *pkg) + struct pkg *pkg) { - struct pkg_shlib *shlib = NULL; struct pkg_job_provide *pr; struct pkgdb_it *it; int rc; + char *val; - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { - HASH_FIND_STR(universe->provides, shlib->name, pr); + kh_foreach_value(pkg->shlibs_required, val, { + HASH_FIND_STR(universe->provides, val, pr); if (pr != NULL) continue; /* Check for local provides */ - it = pkgdb_query_shlib_provide(universe->j->db, shlib->name); + it = pkgdb_query_shlib_provide(universe->j->db, val); if (it != NULL) { - rc = pkg_jobs_universe_handle_provide(universe, it, shlib->name, true); + rc = pkg_jobs_universe_handle_provide(universe, it, val, + true); pkgdb_it_free(it); if (rc != EPKG_OK) { - pkg_debug(1, "cannot find local packages that provide library %s " - "required for %s", - shlib->name, pkg->name); + pkg_debug(1, "cannot find local packages that " + "provide library %s required for %s", + val, pkg->name); } } /* Not found, search in the repos */ it = pkgdb_repo_shlib_provide(universe->j->db, - shlib->name, universe->j->reponame); + val, universe->j->reponame); if (it != NULL) { - rc = pkg_jobs_universe_handle_provide(universe, it, shlib->name, true); + rc = pkg_jobs_universe_handle_provide(universe, it, val, + true); pkgdb_it_free(it); if (rc != EPKG_OK) { - pkg_debug(1, "cannot find remote packages that provide library %s " - "required for %s", - shlib->name, pkg->name); + pkg_debug(1, "cannot find remote packages that " + "provide library %s required for %s", + val, pkg->name); } } - } + }); return (EPKG_OK); } diff --git a/libpkg/pkg_manifest.c b/libpkg/pkg_manifest.c index e95c75a..9f68c0d 100644 --- a/libpkg/pkg_manifest.c +++ b/libpkg/pkg_manifest.c @@ -924,7 +924,6 @@ pkg_emit_object(struct pkg *pkg, short flags) struct pkg_dir *dir = NULL; struct pkg_user *user = NULL; struct pkg_group *group = NULL; - struct pkg_shlib *shlib = NULL; struct pkg_conflict *conflict = NULL; struct pkg_provide *provide = NULL; struct pkg_provide *require = NULL; @@ -932,6 +931,7 @@ pkg_emit_object(struct pkg *pkg, short flags) struct sbuf *tmpsbuf = NULL; int i; const char *script_types = NULL; + char *val; char legacyarch[BUFSIZ]; ucl_object_t *map, *seq, *submap; ucl_object_t *top = ucl_object_typed_new(UCL_OBJECT); @@ -1051,21 +1051,21 @@ pkg_emit_object(struct pkg *pkg, short flags) pkg_debug(4, "Emitting required"); seq = NULL; - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { + kh_foreach_value(pkg->shlibs_required, val, { if (seq == NULL) seq = ucl_object_typed_new(UCL_ARRAY); - ucl_array_append(seq, ucl_object_fromstring(shlib->name)); - } + ucl_array_append(seq, ucl_object_fromstring(val)); + }); if (seq) ucl_object_insert_key(top, seq, "shlibs_required", 15, false); pkg_debug(4, "Emitting shlibs_provided"); seq = NULL; - while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) { + kh_foreach_value(pkg->shlibs_required, val, { if (seq == NULL) seq = ucl_object_typed_new(UCL_ARRAY); - ucl_array_append(seq, ucl_object_fromstring(shlib->name)); - } + ucl_array_append(seq, ucl_object_fromstring(val)); + }); if (seq) ucl_object_insert_key(top, seq, "shlibs_provided", 15, false); diff --git a/libpkg/pkg_printf.c b/libpkg/pkg_printf.c index 73e4268..b532fc3 100644 --- a/libpkg/pkg_printf.c +++ b/libpkg/pkg_printf.c @@ -908,25 +908,25 @@ struct sbuf * format_shlibs_required(struct sbuf *sbuf, const void *data, struct percent_esc *p) { const struct pkg *pkg = data; + char *val; + int count; if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) return (list_count(sbuf, pkg_list_count(pkg, PKG_SHLIBS_REQUIRED), p)); else { - struct pkg_shlib *shlib = NULL; - int count; set_list_defaults(p, "%Bn\n", ""); count = 1; - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { + kh_foreach_value(pkg->shlibs_required, val, { if (count > 1) iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt), - shlib, count, PP_B); + val, count, PP_B); iterate_item(sbuf, pkg, sbuf_data(p->item_fmt), - shlib, count, PP_B); + val, count, PP_B); count++; - } + }); } return (sbuf); } @@ -938,9 +938,9 @@ format_shlibs_required(struct sbuf *sbuf, const void *data, struct percent_esc * struct sbuf * format_shlib_name(struct sbuf *sbuf, const void *data, struct percent_esc *p) { - const struct pkg_shlib *shlib = data; + const char *val = data; - return (string_val(sbuf, shlib->name, p)); + return (string_val(sbuf, val, p)); } /* @@ -1522,25 +1522,23 @@ struct sbuf * format_shlibs_provided(struct sbuf *sbuf, const void *data, struct percent_esc *p) { const struct pkg *pkg = data; + char *val; + int count = 1; if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) return (list_count(sbuf, pkg_list_count(pkg, PKG_SHLIBS_PROVIDED), p)); else { - struct pkg_shlib *shlib = NULL; - int count; - set_list_defaults(p, "%bn\n", ""); - count = 1; - while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) { + kh_foreach_value(pkg->shlibs_provided, val, { if (count > 1) iterate_item(sbuf, pkg, sbuf_data(p->sep_fmt), - shlib, count, PP_b); + val, count, PP_b); iterate_item(sbuf, pkg, sbuf_data(p->item_fmt), - shlib, count, PP_b); + val, count, PP_b); count++; - } + }); } return (sbuf); } diff --git a/libpkg/pkg_solve.c b/libpkg/pkg_solve.c index a2e3c1b..bbe069e 100644 --- a/libpkg/pkg_solve.c +++ b/libpkg/pkg_solve.c @@ -301,6 +301,7 @@ pkg_solve_handle_provide (struct pkg_solve_problem *problem, struct pkg_shlib *shlp; struct pkg_provide *np; struct pkg *pkg; + khint_t k; /* Find the first package in the universe list */ un = pr->un; @@ -321,12 +322,14 @@ pkg_solve_handle_provide (struct pkg_solve_problem *problem, pkg = curvar->unit->pkg; if (pr->is_shlib) { - HASH_FIND_STR(pkg->shlibs_provided, pr->provide, shlp); + k = kh_get_strhash(pkg->shlibs_provided, pr->provide); /* Skip incompatible ABI as well */ - if (shlp != NULL && strcmp(pkg->arch, orig->arch) != 0) { - pkg_debug(2, "require %s: package %s-%s(%c) provides wrong ABI %s, " - "wanted %s", pr->provide, pkg->name, pkg->version, - pkg->type == PKG_INSTALLED ? 'l' : 'r', orig->arch, pkg->arch); + if (k != kh_end(pkg->shlibs_provided) && + strcmp(pkg->arch, orig->arch) != 0) { + pkg_debug(2, "require %s: package %s-%s(%c) " + "provides wrong ABI %s, wanted %s", + pr->provide, pkg->name, pkg->version, + pkg->type == PKG_INSTALLED ? 'l' : 'r', orig->arch, pkg->arch); continue; } } @@ -708,10 +711,10 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem, struct pkg_conflict *conflict, *ctmp; struct pkg *pkg; struct pkg_solve_variable *cur_var; - struct pkg_shlib *shlib = NULL; struct pkg_provide *p = NULL; struct pkg_jobs *j = problem->j; struct pkg_job_request *jreq; + char *val; bool chain_added = false; LL_FOREACH(var, cur_var) { @@ -731,12 +734,9 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem, } /* Shlibs */ - shlib = NULL; - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { - if (pkg_solve_add_require_rule(problem, cur_var, - shlib->name) != EPKG_OK) - continue; - } + kh_foreach_value(pkg->shlibs_required, val, { + pkg_solve_add_require_rule(problem, cur_var, val); + }); p = NULL; while (pkg_requires(pkg, &p) == EPKG_OK) { if (pkg_solve_add_require_rule(problem, cur_var, diff --git a/libpkg/pkgdb.c b/libpkg/pkgdb.c index eb354e6..01f1cd7 100644 --- a/libpkg/pkgdb.c +++ b/libpkg/pkgdb.c @@ -1927,18 +1927,18 @@ pkgdb_insert_scripts(struct pkg *pkg, int64_t package_id, sqlite3 *s) int pkgdb_update_shlibs_required(struct pkg *pkg, int64_t package_id, sqlite3 *s) { - struct pkg_shlib *shlib = NULL; + char *val; - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { - if (run_prstmt(SHLIBS1, shlib->name) + kh_foreach_value(pkg->shlibs_required, val, { + if (run_prstmt(SHLIBS1, val) != SQLITE_DONE || - run_prstmt(SHLIBS_REQD, package_id, shlib->name) + run_prstmt(SHLIBS_REQD, package_id, val) != SQLITE_DONE) { ERROR_SQLITE(s, SQL(SHLIBS_REQD)); return (EPKG_FATAL); } - } + }); return (EPKG_OK); } @@ -1962,18 +1962,18 @@ pkgdb_update_config_file_content(struct pkg *p, sqlite3 *s) int pkgdb_update_shlibs_provided(struct pkg *pkg, int64_t package_id, sqlite3 *s) { - struct pkg_shlib *shlib = NULL; + char *val; - while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) { - if (run_prstmt(SHLIBS1, shlib->name) + kh_foreach_value(pkg->shlibs_provided, val, { + if (run_prstmt(SHLIBS1, val) != SQLITE_DONE || - run_prstmt(SHLIBS_PROV, package_id, shlib->name) + run_prstmt(SHLIBS_PROV, package_id, val) != SQLITE_DONE) { ERROR_SQLITE(s, SQL(SHLIBS_PROV)); return (EPKG_FATAL); } - } + }); return (EPKG_OK); } diff --git a/libpkg/private/pkg.h b/libpkg/private/pkg.h index 9913e26..c426605 100644 --- a/libpkg/private/pkg.h +++ b/libpkg/private/pkg.h @@ -121,6 +121,8 @@ return (EPKG_OK); \ } while (0) +KHASH_MAP_INIT_STR(strhash, char *); + extern int eventpipe; extern int64_t debug_level; extern bool developer_mode; @@ -169,8 +171,8 @@ struct pkg { struct pkg_option *options; struct pkg_user *users; struct pkg_group *groups; - struct pkg_shlib *shlibs_required; - struct pkg_shlib *shlibs_provided; + kh_strhash_t *shlibs_required; + kh_strhash_t *shlibs_provided; struct pkg_conflict *conflicts; struct pkg_provide *provides; struct pkg_provide *requires; @@ -256,11 +258,6 @@ struct pkg_group { UT_hash_handle hh; }; -struct pkg_shlib { - char *name; - UT_hash_handle hh; -}; - struct http_mirror { struct url *url; struct http_mirror *next; @@ -559,9 +556,6 @@ void pkg_group_free(struct pkg_group *); int pkg_jobs_resolv(struct pkg_jobs *jobs); -int pkg_shlib_new(struct pkg_shlib **); -void pkg_shlib_free(struct pkg_shlib *); - int pkg_conflict_new(struct pkg_conflict **); void pkg_conflict_free(struct pkg_conflict *); diff --git a/libpkg/repo/binary/update.c b/libpkg/repo/binary/update.c index 5e50e4f..5da1db0 100644 --- a/libpkg/repo/binary/update.c +++ b/libpkg/repo/binary/update.c @@ -138,12 +138,12 @@ pkg_repo_binary_add_pkg(struct pkg *pkg, const char *pkg_path, int ret; struct pkg_dep *dep = NULL; struct pkg_option *option = NULL; - struct pkg_shlib *shlib = NULL; struct pkg_provide *provide = NULL; struct pkg_strel *el; struct pkg_kv *kv; const char *arch; int64_t package_id; + char *val; arch = pkg->abi != NULL ? pkg->abi : pkg->arch; @@ -224,29 +224,27 @@ try_again: } } - shlib = NULL; - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { - ret = pkg_repo_binary_run_prstatement(SHLIB1, shlib->name); + kh_foreach_value(pkg->shlibs_required, val, { + ret = pkg_repo_binary_run_prstatement(SHLIB1, val); if (ret == SQLITE_DONE) - ret = pkg_repo_binary_run_prstatement(SHLIB_REQD, package_id, - shlib->name); + ret = pkg_repo_binary_run_prstatement(SHLIB_REQD, + package_id, val); if (ret != SQLITE_DONE) { ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_REQD)); return (EPKG_FATAL); } - } + }); - shlib = NULL; - while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) { - ret = pkg_repo_binary_run_prstatement(SHLIB1, shlib->name); + kh_foreach_value(pkg->shlibs_provided, val, { + ret = pkg_repo_binary_run_prstatement(SHLIB1, val); if (ret == SQLITE_DONE) - ret = pkg_repo_binary_run_prstatement(SHLIB_PROV, package_id, - shlib->name); + ret = pkg_repo_binary_run_prstatement(SHLIB_PROV, + package_id, val); if (ret != SQLITE_DONE) { ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_PROV)); return (EPKG_FATAL); } - } + }); provide = NULL; while (pkg_provides(pkg, &provide) == EPKG_OK) { diff --git a/src/check.c b/src/check.c index c2344ac..3f7e898 100644 --- a/src/check.c +++ b/src/check.c @@ -63,9 +63,10 @@ static int check_deps(struct pkgdb *db, struct pkg *p, struct deps_head *dh, bool noinstall, struct sbuf *out) { struct pkg_dep *dep = NULL; - struct pkg_shlib *shlib = NULL; struct pkg_provide *provide = NULL; int nbpkgs = 0; + char *val; + uint32_t i; assert(db != NULL); assert(p != NULL); @@ -84,12 +85,13 @@ check_deps(struct pkgdb *db, struct pkg *p, struct deps_head *dh, bool noinstall } /* checking libraries required */ - while (pkg_shlibs_required(p, &shlib) == EPKG_OK) { + i = 0; + while ((val = pkg_shlibs_required(p, &i))) { if (quiet) - pkg_sbuf_printf(out, "%n\t%Bn\n", p, shlib); + pkg_sbuf_printf(out, "%n\t%S\n", p, val); else - pkg_sbuf_printf(out, "%n has require a missing libraries: %Bn\n", - p, shlib); + pkg_sbuf_printf(out, "%n has require a missing libraries: %S\n", + p, val); } /* checking requires */ diff --git a/src/query.c b/src/query.c index edf8098..a814f77 100644 --- a/src/query.c +++ b/src/query.c @@ -273,10 +273,10 @@ format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, const void *dat pkg_sbuf_printf(dest, "%Gn", data); break; case 'B': - pkg_sbuf_printf(dest, "%Bn", data); + pkg_sbuf_printf(dest, "%s", data); break; case 'b': - pkg_sbuf_printf(dest, "%bn", data); + pkg_sbuf_printf(dest, "%s", data); break; case 'A': qstr++; @@ -336,9 +336,10 @@ print_query(struct pkg *pkg, char *qstr, char multiline) struct pkg_dir *dir = NULL; struct pkg_user *user = NULL; struct pkg_group *group = NULL; - struct pkg_shlib *shlib = NULL; struct pkg_kv *kv; struct pkg_strel *list; + uint32_t i; + char *val; switch (multiline) { case 'd': @@ -400,14 +401,16 @@ print_query(struct pkg *pkg, char *qstr, char multiline) } break; case 'B': - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { - format_str(pkg, output, qstr, shlib); + i = 0; + while ((val = pkg_shlibs_required(pkg, &i))) { + format_str(pkg, output, qstr, val); printf("%s\n", sbuf_data(output)); } break; case 'b': - while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) { - format_str(pkg, output, qstr, shlib); + i = 0; + while ((val = pkg_shlibs_provided(pkg, &i))) { + format_str(pkg, output, qstr, val); printf("%s\n", sbuf_data(output)); } break; -- 2.4.0