diff --git a/libpkg/pkg.c b/libpkg/pkg.c index 2c47eaa..bd80bf7 100644 --- a/libpkg/pkg.c +++ b/libpkg/pkg.c @@ -514,7 +514,7 @@ pkg_deps(const struct pkg *pkg, struct pkg_dep **d) { assert(pkg != NULL); - HASH_NEXT(pkg->deps, (*d)); + kh_next(pkg_deps, pkg->deps, (*d), name); } int @@ -522,7 +522,7 @@ pkg_rdeps(const struct pkg *pkg, struct pkg_dep **d) { assert(pkg != NULL); - HASH_NEXT(pkg->rdeps, (*d)); + kh_next(pkg_deps, pkg->rdeps, (*d), name); } int @@ -530,7 +530,7 @@ pkg_files(const struct pkg *pkg, struct pkg_file **f) { assert(pkg != NULL); - HASH_NEXT(pkg->files, (*f)); + kh_next(pkg_files, pkg->files, (*f), path); } int @@ -558,19 +558,19 @@ pkg_options(const struct pkg *pkg, struct pkg_option **o) } int -pkg_shlibs_required(const struct pkg *pkg, struct pkg_shlib **s) +pkg_shlibs_required(const struct pkg *pkg, char **s) { assert(pkg != NULL); - HASH_NEXT(pkg->shlibs_required, (*s)); + kh_string_next(pkg->shlibs_required, (*s)); } int -pkg_shlibs_provided(const struct pkg *pkg, struct pkg_shlib **s) +pkg_shlibs_provided(const struct pkg *pkg, char **s) { assert(pkg != NULL); - HASH_NEXT(pkg->shlibs_provided, (*s)); + kh_string_next(pkg->shlibs_provided, (*s)); } int @@ -582,19 +582,19 @@ pkg_conflicts(const struct pkg *pkg, struct pkg_conflict **c) } int -pkg_provides(const struct pkg *pkg, struct pkg_provide **c) +pkg_provides(const struct pkg *pkg, char **c) { assert(pkg != NULL); - HASH_NEXT(pkg->provides, (*c)); + kh_string_next(pkg->provides, (*c)); } int -pkg_requires(const struct pkg *pkg, struct pkg_provide **c) +pkg_requires(const struct pkg *pkg, char **c) { assert(pkg != NULL); - HASH_NEXT(pkg->requires, (*c)); + kh_string_next(pkg->requires, (*c)); } int @@ -684,8 +684,7 @@ pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *ve assert(origin != NULL && origin[0] != '\0'); pkg_debug(3, "Pkg: add a new dependency origin: %s, name: %s", origin, name); - HASH_FIND_STR(pkg->deps, name, d); - if (d != NULL) { + if (kh_contains(pkg_deps, pkg->deps, name)) { if (developer_mode) { pkg_emit_error("%s: duplicate dependency listing: %s, fatal (developer mode)", pkg->name, name); @@ -706,7 +705,7 @@ pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *ve d->uid = strdup(name); d->locked = locked; - HASH_ADD_KEYPTR(hh, pkg->deps, d->name, strlen(d->name), d); + kh_add(pkg_deps, pkg->deps, d, d->name); return (EPKG_OK); } @@ -730,7 +729,7 @@ pkg_addrdep(struct pkg *pkg, const char *name, const char *origin, const char *v d->uid = strdup(name); d->locked = locked; - HASH_ADD_KEYPTR(hh, pkg->rdeps, d->origin, strlen(d->origin), d); + kh_add(pkg_deps, pkg->rdeps, d, d->name); return (EPKG_OK); } @@ -755,16 +754,13 @@ pkg_addfile_attr(struct pkg *pkg, const char *path, const char *sum, path = pkg_absolutepath(path, abspath, sizeof(abspath)); pkg_debug(3, "Pkg: add new file '%s'", path); - if (check_duplicates) { - HASH_FIND_STR(pkg->files, path, f); - if (f != NULL) { - if (developer_mode) { - pkg_emit_error("duplicate file listing: %s, fatal (developer mode)", f->path); - return (EPKG_FATAL); - } else { - pkg_emit_error("duplicate file listing: %s, ignoring", f->path); - return (EPKG_OK); - } + if (check_duplicates && kh_contains(pkg_files, pkg->files, path)) { + if (developer_mode) { + pkg_emit_error("duplicate file listing: %s, fatal (developer mode)", path); + return (EPKG_FATAL); + } else { + pkg_emit_error("duplicate file listing: %s, ignoring", path); + return (EPKG_OK); } } @@ -786,7 +782,7 @@ pkg_addfile_attr(struct pkg *pkg, const char *path, const char *sum, if (fflags != 0) f->fflags = fflags; - HASH_ADD_STR(pkg->files, path, f); + kh_add(pkg_files, pkg->files, f, f->path); return (EPKG_OK); } @@ -1156,24 +1152,18 @@ 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 *storedname; assert(pkg != NULL); assert(name != NULL && name[0] != '\0'); - pkg_shlib_new(&s); - s->name = strdup(name); - - HASH_FIND_STR(pkg->shlibs_required, s->name, f); - /* silently ignore duplicates in case of shlibs */ - if (f != NULL) { - pkg_shlib_free(s); + if (kh_contains(strings, pkg->shlibs_required, name)) return (EPKG_OK); - } - HASH_ADD_KEYPTR(hh, pkg->shlibs_required, s->name, strlen(s->name), s); + storedname = strdup(name); - pkg_debug(3, "added shlib deps for %s on %s", pkg->name, name); + kh_add(strings, pkg->shlibs_required, storedname, storedname); + pkg_debug(3, "added shlib deps for %s on %s", pkg->name, storedname); return (EPKG_OK); } @@ -1181,7 +1171,7 @@ 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 *storedname; assert(pkg != NULL); assert(name != NULL && name[0] != '\0'); @@ -1190,18 +1180,12 @@ 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 (kh_contains(strings, pkg->shlibs_provided, name)) return (EPKG_OK); - } - - HASH_ADD_KEYPTR(hh, pkg->shlibs_provided, s->name, strlen(s->name), s); - pkg_debug(3, "added shlib provide %s for %s", name, pkg->name); + storedname = strdup(name); + kh_add(strings, pkg->shlibs_provided, storedname, storedname); + pkg_debug(3, "added shlib provide for %s on %s", pkg->name, storedname); return (EPKG_OK); } @@ -1231,20 +1215,16 @@ pkg_addconflict(struct pkg *pkg, const char *uniqueid) int pkg_addrequire(struct pkg *pkg, const char *name) { - struct pkg_provide *p = NULL; + char *storedname; assert(pkg != NULL); assert(name != NULL && name[0] != '\0'); - HASH_FIND_STR(pkg->requires, __DECONST(char *, name), p); - /* silently ignore duplicates in case of conflicts */ - if (p != NULL) + if (kh_contains(strings, pkg->requires, name)) return (EPKG_OK); - pkg_provide_new(&p); - p->provide = strdup(name); - - HASH_ADD_KEYPTR(hh, pkg->requires, p->provide, strlen(p->provide), p); + storedname = strdup(name); + kh_add(strings, pkg->requires, storedname, storedname); return (EPKG_OK); } @@ -1252,20 +1232,16 @@ pkg_addrequire(struct pkg *pkg, const char *name) int pkg_addprovide(struct pkg *pkg, const char *name) { - struct pkg_provide *p = NULL; + char *storedname; assert(pkg != NULL); assert(name != NULL && name[0] != '\0'); - HASH_FIND_STR(pkg->provides, __DECONST(char *, name), p); - /* silently ignore duplicates in case of conflicts */ - if (p != NULL) + if (kh_contains(strings, pkg->provides, name)) return (EPKG_OK); - pkg_provide_new(&p); - p->provide = strdup(name); - - HASH_ADD_KEYPTR(hh, pkg->provides, p->provide, strlen(p->provide), p); + storedname = strdup(name); + kh_add(strings, pkg->provides, storedname, storedname); return (EPKG_OK); } @@ -1318,13 +1294,13 @@ pkg_list_count(const struct pkg *pkg, pkg_list list) { switch (list) { case PKG_DEPS: - return (HASH_COUNT(pkg->deps)); + return (kh_count(pkg->deps)); case PKG_RDEPS: - return (HASH_COUNT(pkg->rdeps)); + return (kh_count(pkg->rdeps)); case PKG_OPTIONS: return (HASH_COUNT(pkg->options)); case PKG_FILES: - return (HASH_COUNT(pkg->files)); + return (kh_count(pkg->files)); case PKG_DIRS: return (HASH_COUNT(pkg->dirs)); case PKG_USERS: @@ -1332,15 +1308,15 @@ 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)); + return (kh_count(pkg->shlibs_required)); case PKG_SHLIBS_PROVIDED: - return (HASH_COUNT(pkg->shlibs_provided)); + return (kh_count(pkg->shlibs_provided)); case PKG_CONFLICTS: return (HASH_COUNT(pkg->conflicts)); case PKG_PROVIDES: - return (HASH_COUNT(pkg->provides)); + return (kh_count(pkg->provides)); case PKG_REQUIRES: - return (HASH_COUNT(pkg->requires)); + return (kh_count(pkg->requires)); case PKG_CONFIG_FILES: return (HASH_COUNT(pkg->config_files)); } @@ -1349,14 +1325,15 @@ pkg_list_count(const struct pkg *pkg, pkg_list list) } void -pkg_list_free(struct pkg *pkg, pkg_list list) { +pkg_list_free(struct pkg *pkg, pkg_list list) +{ switch (list) { case PKG_DEPS: - HASH_FREE(pkg->deps, pkg_dep_free); + kh_free(pkg_deps, pkg->deps, struct pkg_dep, pkg_dep_free); pkg->flags &= ~PKG_LOAD_DEPS; break; case PKG_RDEPS: - HASH_FREE(pkg->rdeps, pkg_dep_free); + kh_free(pkg_deps, pkg->rdeps, struct pkg_dep, pkg_dep_free); pkg->flags &= ~PKG_LOAD_RDEPS; break; case PKG_OPTIONS: @@ -1365,7 +1342,7 @@ pkg_list_free(struct pkg *pkg, pkg_list list) { break; case PKG_FILES: case PKG_CONFIG_FILES: - HASH_FREE(pkg->files, pkg_file_free); + kh_free(pkg_files, pkg->files, struct pkg_file, pkg_file_free); HASH_FREE(pkg->config_files, pkg_config_file_free); pkg->flags &= ~PKG_LOAD_FILES; break; @@ -1382,11 +1359,11 @@ 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_free(strings, pkg->shlibs_required, char, free); pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED; break; case PKG_SHLIBS_PROVIDED: - HASH_FREE(pkg->shlibs_provided, pkg_shlib_free); + kh_free(strings, pkg->shlibs_required, char, free); pkg->flags &= ~PKG_LOAD_SHLIBS_PROVIDED; break; case PKG_CONFLICTS: @@ -1394,11 +1371,11 @@ pkg_list_free(struct pkg *pkg, pkg_list list) { pkg->flags &= ~PKG_LOAD_CONFLICTS; break; case PKG_PROVIDES: - HASH_FREE(pkg->provides, pkg_provide_free); + kh_free(strings, pkg->provides, char, free); pkg->flags &= ~PKG_LOAD_PROVIDES; break; case PKG_REQUIRES: - HASH_FREE(pkg->requires, pkg_provide_free); + kh_free(strings, pkg->requires, char, free); pkg->flags &= ~PKG_LOAD_REQUIRES; break; } @@ -1732,21 +1709,21 @@ pkg_is_config_file(struct pkg *p, const char *path, const struct pkg_file **file, struct pkg_config_file **cfile) { - struct pkg_file *f; + khint_t k; struct pkg_config_file *cf; *file = NULL; *cfile = NULL; - HASH_FIND_STR(p->files, path, f); - if (f == NULL) + k = kh_get_pkg_files(p->files, path); + if (k == kh_end(p->files)) return (false); HASH_FIND_STR(p->config_files, path, cf); if (cf == NULL) return (false); - *file = f; + *file = kh_value(p->files, k); *cfile = cf; return (true); @@ -1755,11 +1732,8 @@ pkg_is_config_file(struct pkg *p, const char *path, bool pkg_has_file(struct pkg *p, const char *path) { - struct pkg_file *f; - - HASH_FIND_STR(p->files, path, f); - return (f != NULL ? true : false); + return (kh_get_pkg_files(p->files, path) != kh_end(p->files)); } bool diff --git a/libpkg/pkg.h.in b/libpkg/pkg.h.in index 399261a..b5b737b 100644 --- a/libpkg/pkg.h.in +++ b/libpkg/pkg.h.in @@ -101,8 +101,6 @@ struct pkg_option; struct pkg_license; struct pkg_user; struct pkg_group; -struct pkg_shlib; -struct pkg_provide; struct pkg_config_file; struct pkgdb; @@ -638,16 +636,14 @@ int pkg_options(const struct pkg *, struct pkg_option **option); * @param shlib must be set to NULL for the first call. * @return An error code */ -int pkg_shlibs_required(const struct pkg *pkg, struct pkg_shlib **shlib); +int pkg_shlibs_required(const struct pkg *pkg, char **shlib); /** * Iterates over the shared libraries provided by the package. * @param shlib must be set to NULL for the first call. * @return An error code */ -int pkg_shlibs_provided(const struct pkg *pkg, struct pkg_shlib **shlib); - -const char *pkg_shlib_name(const struct pkg_shlib *shlib); +int pkg_shlibs_provided(const struct pkg *pkg, char **shlib); /** * Iterates over the conflicts registered in the package. @@ -661,10 +657,8 @@ int pkg_conflicts(const struct pkg *pkg, struct pkg_conflict **conflict); * @param provide must be set to NULL for the first call. * @return An error code */ -int pkg_provides(const struct pkg *pkg, struct pkg_provide **provide); -int pkg_requires(const struct pkg *pkg, struct pkg_provide **require); - -const char *pkg_provide_name(const struct pkg_provide *provide); +int pkg_provides(const struct pkg *pkg, char **provide); +int pkg_requires(const struct pkg *pkg, char **require); /** * Iterates over the config files registered in the package. diff --git a/libpkg/pkg_add.c b/libpkg/pkg_add.c index 4cfacea..6cc4a4b 100644 --- a/libpkg/pkg_add.c +++ b/libpkg/pkg_add.c @@ -647,7 +647,7 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags, /* add the user and group if necessary */ - nfiles = HASH_COUNT(pkg->files); + nfiles = kh_count(pkg->files); /* * Extract the files on disk. */ diff --git a/libpkg/pkg_attributes.c b/libpkg/pkg_attributes.c index b337d05..6b7e61c 100644 --- a/libpkg/pkg_attributes.c +++ b/libpkg/pkg_attributes.c @@ -217,37 +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); -} - -const char * -pkg_shlib_name(const struct pkg_shlib *sl) -{ - if (sl == NULL) - return (NULL); - - return (sl->name); -} - -/* * Conflicts */ @@ -272,28 +241,6 @@ pkg_conflict_free(struct pkg_conflict *c) } /* - * Provides - */ -int -pkg_provide_new(struct pkg_provide **c) -{ - if ((*c = calloc(1, sizeof(struct pkg_provide))) == NULL) - return (EPKG_FATAL); - - return (EPKG_OK); -} - -void -pkg_provide_free(struct pkg_provide *c) -{ - if (c == NULL) - return; - - free(c->provide); - free(c); -} - -/* * Config files */ int @@ -366,15 +313,3 @@ pkg_kv_free(struct pkg_kv *c) free(c->value); free(c); } - -/* - * provide - */ -const char * -pkg_provide_name(const struct pkg_provide *provide) -{ - if (provide == NULL) - return (NULL); - - return (provide->provide); -} diff --git a/libpkg/pkg_checksum.c b/libpkg/pkg_checksum.c index b7370bc..7a3b57e 100644 --- a/libpkg/pkg_checksum.c +++ b/libpkg/pkg_checksum.c @@ -189,15 +189,13 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen, pkg_checksum_type_t type) { unsigned char *bdigest; - char *olduid; + char *olduid, *buf; 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; - struct pkg_provide *p = NULL; int i; if (pkg == NULL || type >= PKG_HASH_TYPE_UNKNOWN || @@ -213,13 +211,14 @@ 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); + buf = NULL; + while (pkg_shlibs_required(pkg, &buf) == EPKG_OK) { + pkg_checksum_add_entry("required_shlib", buf, &entries); } - shlib = NULL; - while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) { - pkg_checksum_add_entry("provided_shlib", shlib->name, &entries); + buf = NULL; + while (pkg_shlibs_provided(pkg, &buf) == EPKG_OK) { + pkg_checksum_add_entry("provided_shlib", buf, &entries); } while (pkg_users(pkg, &user) == EPKG_OK) { @@ -236,13 +235,14 @@ pkg_checksum_generate(struct pkg *pkg, char *dest, size_t destlen, free(olduid); } - while (pkg_provides(pkg, &p) == EPKG_OK) { - pkg_checksum_add_entry("provide", p->provide, &entries); + buf = NULL; + while (pkg_provides(pkg, &buf) == EPKG_OK) { + pkg_checksum_add_entry("provide", buf, &entries); } - p = NULL; - while (pkg_requires(pkg, &p) == EPKG_OK) { - pkg_checksum_add_entry("require", p->provide, &entries); + buf = NULL; + while (pkg_requires(pkg, &buf) == EPKG_OK) { + pkg_checksum_add_entry("require", buf, &entries); } /* Sort before hashing */ diff --git a/libpkg/pkg_create.c b/libpkg/pkg_create.c index 6ba4a15..3f70341 100644 --- a/libpkg/pkg_create.c +++ b/libpkg/pkg_create.c @@ -75,7 +75,7 @@ pkg_create_from_dir(struct pkg *pkg, const char *root, * Get / compute size / checksum if not provided in the manifest */ - nfiles = HASH_COUNT(pkg->files); + nfiles = kh_count(pkg->files); counter_init("file sizes/checksums", nfiles); hardlinks = kh_init_hardlinks(); diff --git a/libpkg/pkg_cudf.c b/libpkg/pkg_cudf.c index 6a1cb0e..95ed574 100644 --- a/libpkg/pkg_cudf.c +++ b/libpkg/pkg_cudf.c @@ -111,8 +111,8 @@ static int cudf_emit_pkg(struct pkg *pkg, int version, FILE *f, struct pkg_job_universe_item *conflicts_chain) { - struct pkg_dep *dep, *dtmp; - struct pkg_provide *prov, *ptmp; + struct pkg_dep *dep; + char *prov; struct pkg_conflict *conflict, *ctmp; struct pkg_job_universe_item *u; int column = 0, ver; @@ -126,27 +126,27 @@ cudf_emit_pkg(struct pkg *pkg, int version, FILE *f, if (fprintf(f, "\nversion: %d\n", version) < 0) return (EPKG_FATAL); - if (HASH_COUNT(pkg->deps) > 0) { + if (kh_count(pkg->deps) > 0) { if (fprintf(f, "depends: ") < 0) return (EPKG_FATAL); - HASH_ITER(hh, pkg->deps, dep, dtmp) { + kh_each_value(pkg->deps, dep, { if (cudf_print_element(f, dep->name, - (dep->hh.next != NULL), &column) < 0) { + column + 1 == kh_count(pkg->deps), &column) < 0) { return (EPKG_FATAL); } - } + }); } column = 0; - if (HASH_COUNT(pkg->provides) > 0) { + if (kh_count(pkg->provides) > 0) { if (fprintf(f, "provides: ") < 0) return (EPKG_FATAL); - HASH_ITER(hh, pkg->provides, prov, ptmp) { - if (cudf_print_element(f, prov->provide, - (prov->hh.next != NULL), &column) < 0) { + kh_each_value(pkg->provides, prov, { + if (cudf_print_element(f, prov, + column + 1 == kh_count(pkg->provides), &column) < 0) { return (EPKG_FATAL); } - } + }); } column = 0; @@ -246,13 +246,13 @@ int pkg_jobs_cudf_emit_file(struct pkg_jobs *j, pkg_jobs_t t, FILE *f) { struct pkg *pkg; - struct pkg_job_universe_item *it, *itmp, *icur; + struct pkg_job_universe_item *it, *icur; int version; if (fprintf(f, "preamble: \n\n") < 0) return (EPKG_FATAL); - HASH_ITER(hh, j->universe->items, it, itmp) { + kh_each_value(j->universe->items, it, { /* XXX * Here are dragons: * after sorting it we actually modify the head of the list, but there is @@ -278,7 +278,7 @@ pkg_jobs_cudf_emit_file(struct pkg_jobs *j, pkg_jobs_t t, FILE *f) return (EPKG_FATAL); } } - } + }); if (fprintf(f, "request: \n") < 0) return (EPKG_FATAL); diff --git a/libpkg/pkg_delete.c b/libpkg/pkg_delete.c index c2e8a5a..f9aeaf6 100644 --- a/libpkg/pkg_delete.c +++ b/libpkg/pkg_delete.c @@ -327,7 +327,7 @@ pkg_delete_files(struct pkg *pkg, unsigned force) int nfiles, cur_file = 0; - nfiles = HASH_COUNT(pkg->files); + nfiles = kh_count(pkg->files); if (nfiles == 0) return (EPKG_OK); diff --git a/libpkg/pkg_elf.c b/libpkg/pkg_elf.c index 4479f37..054116a 100644 --- a/libpkg/pkg_elf.c +++ b/libpkg/pkg_elf.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2011-2012 Baptiste Daroussin + * Copyright (c) 2011-2015 Baptiste Daroussin * Copyright (c) 2012-2013 Matthew Seaman * All rights reserved. * @@ -439,14 +439,17 @@ int pkg_analyse_files(struct pkgdb *db, struct pkg *pkg, const char *stage) { struct pkg_file *file = NULL; - struct pkg_shlib *sh, *shtmp, *found; + char *sh; + khint_t k; int ret = EPKG_OK; char fpath[MAXPATHLEN]; const char *lib; bool failures = false; - pkg_list_free(pkg, PKG_SHLIBS_REQUIRED); - pkg_list_free(pkg, PKG_SHLIBS_PROVIDED); + if (kh_count(pkg->shlibs_required) != 0) + pkg_list_free(pkg, PKG_SHLIBS_REQUIRED); + if (kh_count(pkg->shlibs_provided) != 0) + pkg_list_free(pkg, PKG_SHLIBS_PROVIDED); if (elf_version(EV_CURRENT) == EV_NONE) return (EPKG_FATAL); @@ -482,34 +485,35 @@ 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_each_value(pkg->shlibs_required, sh, { + if (kh_contains(strings, pkg->shlibs_provided, sh)) { 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); + sh, pkg->name); + k = kh_get_strings(pkg->shlibs_required, sh); + kh_del_strings(pkg->shlibs_required, k); continue; } file = NULL; while (pkg_files(pkg, &file) == EPKG_OK) { - if ((lib = strstr(file->path, sh->name)) != NULL && - strlen(lib) == strlen(sh->name) && lib[-1] == '/') { + if ((lib = strstr(file->path, sh)) != NULL && + strlen(lib) == strlen(sh) && lib[-1] == '/') { 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); + sh, pkg->name); + k = kh_get_strings(pkg->shlibs_required, sh); + kh_del_strings(pkg->shlibs_required, k); break; } } - } + }); /* * 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); + kh_free(strings, pkg->shlibs_provided, char, free); if (failures) goto cleanup; diff --git a/libpkg/pkg_jobs.c b/libpkg/pkg_jobs.c index b82ec42..104a652 100644 --- a/libpkg/pkg_jobs.c +++ b/libpkg/pkg_jobs.c @@ -777,8 +777,9 @@ pkg_jobs_has_replacement(struct pkg_jobs *j, const char *uid) { struct pkg_job_replace *cur; - LL_FOREACH(j->universe->uid_replaces, cur) { - if (strcmp (cur->new_uid, uid) == 0) { + for (int i = 0; i < kv_size(j->universe->uid_replaces); i++) { + cur = kv_A(j->universe->uid_replaces, i); + if (strcmp(cur->new_uid, uid) == 0) { return (true); } } @@ -1042,9 +1043,8 @@ 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; + char *ls = NULL, *rs = NULL; struct pkg_conflict *lc = NULL, *rc = NULL; - struct pkg_provide *lpr = NULL, *rpr = NULL; /* If no local package, then rp is obviously need to be added */ if (lp == NULL) @@ -1163,16 +1163,17 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp) } /* Provides */ + rs = ls = NULL; for (;;) { - ret1 = pkg_provides(rp, &rpr); - ret2 = pkg_provides(lp, &lpr); + ret1 = pkg_provides(rp, &rs); + ret2 = pkg_provides(lp, &ls); if (ret1 != ret2) { free(rp->reason); rp->reason = strdup("provides changed"); return (true); } if (ret1 == EPKG_OK) { - if (strcmp(rpr->provide, lpr->provide) != 0) { + if (strcmp(rs, ls) != 0) { free(rp->reason); rp->reason = strdup("provides changed"); return (true); @@ -1182,18 +1183,17 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp) break; } /* Requires */ - rpr = NULL; - lpr = NULL; + rs = ls = NULL; for (;;) { - ret1 = pkg_requires(rp, &rpr); - ret1 = pkg_requires(lp, &lpr); + ret1 = pkg_requires(rp, &rs); + ret1 = pkg_requires(lp, &ls); if (ret1 != ret2) { free(rp->reason); rp->reason = strdup("requires changed"); return (true); } if (ret1 == EPKG_OK) { - if (strcmp(rpr->provide, lpr->provide) != 0) { + if (strcmp(rs, ls) != 0) { free(rp->reason); rp->reason = strdup("requires changed"); return (true); @@ -1204,6 +1204,7 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp) } /* Finish by the shlibs */ + rs = ls = NULL; for (;;) { ret1 = pkg_shlibs_provided(rp, &rs); ret2 = pkg_shlibs_provided(lp, &ls); @@ -1213,11 +1214,11 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp) return (true); } if (ret1 == EPKG_OK) { - if (strcmp(rs->name, ls->name) != 0) { + if (strcmp(rs, ls) != 0) { free(rp->reason); rp->reason = strdup("provided shared library changed"); pkg_debug(1, "provided shlib changed %s -> %s", - ls->name, rs->name); + ls, rs); return (true); } } @@ -1225,6 +1226,7 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp) break; } + rs = ls = NULL; for (;;) { ret1 = pkg_shlibs_required(rp, &rs); ret2 = pkg_shlibs_required(lp, &ls); @@ -1234,11 +1236,11 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp) return (true); } if (ret1 == EPKG_OK) { - if (strcmp(rs->name, ls->name) != 0) { + if (strcmp(rs, ls) != 0) { free(rp->reason); rp->reason = strdup("needed shared library changed"); pkg_debug(1, "Required shlib changed %s -> %s", - ls->name, rs->name); + ls, rs); return (true); } } @@ -1252,11 +1254,11 @@ pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp) static void pkg_jobs_propagate_automatic(struct pkg_jobs *j) { - struct pkg_job_universe_item *unit, *utmp, *cur, *local; + struct pkg_job_universe_item *unit, *cur, *local; struct pkg_job_request *req; bool automatic; - HASH_ITER(hh, j->universe->items, unit, utmp) { + kh_each_value(j->universe->items, unit, { if (unit->next == NULL) { /* * For packages that are alone in the installation list @@ -1293,7 +1295,7 @@ pkg_jobs_propagate_automatic(struct pkg_jobs *j) if (cur->pkg->type != PKG_INSTALLED) cur->pkg->automatic = automatic; } - } + }); } static struct pkg_job_request * @@ -1656,7 +1658,8 @@ pkg_jobs_apply_replacements(struct pkg_jobs *j) return; } - LL_FOREACH(j->universe->uid_replaces, r) { + for (int i = 0; i < kv_size(j->universe->uid_replaces); i++) { + r = kv_A(j->universe->uid_replaces, i); pkg_debug(4, "changing uid %s -> %s", r->old_uid, r->new_uid); sqlite3_bind_text(stmt, 1, r->new_uid, -1, SQLITE_TRANSIENT); sqlite3_bind_text(stmt, 2, r->old_uid, -1, SQLITE_TRANSIENT); diff --git a/libpkg/pkg_jobs_conflicts.c b/libpkg/pkg_jobs_conflicts.c index 560331e..c5576e8 100644 --- a/libpkg/pkg_jobs_conflicts.c +++ b/libpkg/pkg_jobs_conflicts.c @@ -207,7 +207,7 @@ pkg_conflicts_item_cmp(struct pkg_jobs_conflict_item *a, static bool pkg_conflicts_need_conflict(struct pkg_jobs *j, struct pkg *p1, struct pkg *p2) { - struct pkg_file *fcur, *ftmp, *ff; + struct pkg_file *fcur; struct pkg_dir *df; struct pkg_conflict *c1, *c2; @@ -235,14 +235,13 @@ pkg_conflicts_need_conflict(struct pkg_jobs *j, struct pkg *p1, struct pkg *p2) /* * We need to check all files and dirs and find the similar ones */ - HASH_ITER(hh, p1->files, fcur, ftmp) { - HASH_FIND_STR(p2->files, fcur->path, ff); - if (ff != NULL) + kh_each_value(p1->files, fcur, { + if (pkg_has_file(p2, fcur->path)) return (true); HASH_FIND_STR(p2->dirs, fcur->path, df); if (df != NULL) return (true); - } + }); /* XXX pkg dirs are terribly broken */ /* No common paths are found in p1 and p2 */ @@ -466,20 +465,19 @@ static void pkg_conflicts_check_chain_conflict(struct pkg_job_universe_item *it, struct pkg_job_universe_item *local, struct pkg_jobs *j) { - struct pkg_file *fcur, *ftmp, *ff; + struct pkg_file *fcur; struct pkg *p; struct pkg_job_universe_item *cun; struct sipkey *k; - HASH_ITER(hh, it->pkg->files, fcur, ftmp) { + kh_each_value(it->pkg->files, fcur, { k = pkg_conflicts_sipkey_init(); /* Check in hash tree */ cun = pkg_conflicts_check_all_paths(j, fcur->path, it, k); if (local != NULL) { /* Filter only new files for remote packages */ - HASH_FIND_STR(local->pkg->files, fcur->path, ff); - if (ff != NULL) + if (pkg_has_file(local->pkg, fcur->path)) continue; } /* Check for local conflict in db */ @@ -492,7 +490,7 @@ pkg_conflicts_check_chain_conflict(struct pkg_job_universe_item *it, assert(cun != NULL); pkg_conflicts_register_chain(j, it, cun, fcur->path); } - } + }); /* XXX: dirs are currently broken terribly */ #if 0 struct pkg_dir *dcur, *dtmp, *df; diff --git a/libpkg/pkg_jobs_universe.c b/libpkg/pkg_jobs_universe.c index 31afd1f..292bade 100644 --- a/libpkg/pkg_jobs_universe.c +++ b/libpkg/pkg_jobs_universe.c @@ -38,20 +38,52 @@ #include #include -#include "utarray.h" - #include "pkg.h" #include "private/event.h" #include "private/pkg.h" #include "private/pkgdb.h" #include "private/pkg_jobs.h" +#include "kvec.h" #define IS_DELETE(j) ((j)->type == PKG_JOBS_DEINSTALL || (j)->type == PKG_JOBS_AUTOREMOVE) -struct pkg_chain { - struct pkg *p; - struct pkg_chain *next; -}; +typedef kvec_t(struct pkg *) pkg_chain_t; + +struct pkg_job_universe_item * +pkg_jobs_universe_find(struct pkg_jobs_universe *universe, const char *key) +{ + khint_t k; + + if (universe->items == NULL) + return(NULL); + k = kh_get_pkg_job_universe_items(universe->items, key); + if (k == kh_end(universe->items)) + return (NULL); + return (kh_value(universe->items, k)); +} + +static void +pkg_jobs_universe_del(struct pkg_jobs_universe *universe, struct pkg_job_universe_item *it) +{ + khint_t k; + + k = kh_get_pkg_job_universe_items(universe->items, it->pkg->uid); + if (k != kh_end(universe->items)) + kh_del_pkg_job_universe_items(universe->items, k); +} + +static struct pkg_job_universe_item * +pkg_jobs_seen_find(struct pkg_jobs_universe *universe, const char *digest) +{ + khint_t k; + + if (universe->seen == NULL) + return (NULL); + k = kh_get_pkg_jobs_seen(universe->seen, digest); + if (k == kh_end(universe->seen)) + return (NULL); + return (kh_value(universe->seen, k)); +} struct pkg * pkg_jobs_universe_get_local(struct pkg_jobs_universe *universe, @@ -71,7 +103,7 @@ pkg_jobs_universe_get_local(struct pkg_jobs_universe *universe, flag = PKG_LOAD_BASIC|PKG_LOAD_RDEPS|PKG_LOAD_DEPS|PKG_LOAD_ANNOTATIONS; } - HASH_FIND(hh, universe->items, uid, strlen(uid), unit); + unit = pkg_jobs_universe_find(universe, uid); if (unit != NULL) { /* Search local in a universe chain */ cur = unit; @@ -101,24 +133,12 @@ pkg_jobs_universe_get_local(struct pkg_jobs_universe *universe, return (pkg); } -static void -pkg_jobs_universe_free_chain(struct pkg_chain *chain) -{ - struct pkg_chain *cur, *tmp; - - if (chain) { - LL_FOREACH_SAFE(chain, cur, tmp) { - free(cur); - } - } -} - -static struct pkg_chain * +static pkg_chain_t * pkg_jobs_universe_get_remote(struct pkg_jobs_universe *universe, const char *uid, unsigned flag) { struct pkg *pkg = NULL; - struct pkg_chain *result = NULL, *r; + pkg_chain_t *result = NULL; struct pkgdb_it *it; struct pkg_job_universe_item *unit, *cur, *found; @@ -129,7 +149,7 @@ pkg_jobs_universe_get_remote(struct pkg_jobs_universe *universe, PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS; } - HASH_FIND(hh, universe->items, uid, strlen(uid), unit); + unit = pkg_jobs_universe_find(universe, uid); if (unit != NULL && unit->pkg->type != PKG_INSTALLED) { /* Search local in a universe chain */ cur = unit; @@ -153,10 +173,10 @@ pkg_jobs_universe_get_remote(struct pkg_jobs_universe *universe, return (NULL); while (pkgdb_it_next(it, &pkg, flag) == EPKG_OK) { - r = malloc(sizeof(*r)); - r->p = pkg; + if (result == NULL) + result = calloc(1, sizeof(pkg_chain_t)); + kv_prepend(typeof(pkg), *result, pkg); pkg = NULL; - LL_PREPEND(result, r); } pkgdb_it_free(it); @@ -172,8 +192,7 @@ int pkg_jobs_universe_add_pkg(struct pkg_jobs_universe *universe, struct pkg *pkg, bool force, struct pkg_job_universe_item **found) { - struct pkg_job_universe_item *item, *tmp = NULL; - struct pkg_job_seen *seen; + struct pkg_job_universe_item *item, *seen, *tmp = NULL; pkg_validate(pkg); if (pkg->digest == NULL) { @@ -185,7 +204,7 @@ pkg_jobs_universe_add_pkg(struct pkg_jobs_universe *universe, struct pkg *pkg, } } - HASH_FIND_STR(universe->seen, pkg->digest, seen); + seen = pkg_jobs_seen_find(universe, pkg->digest); if (seen != NULL && !force) { /* * For remote packages we could have the same digest but different repos @@ -193,16 +212,16 @@ pkg_jobs_universe_add_pkg(struct pkg_jobs_universe *universe, struct pkg *pkg, */ bool other_candidate = false; - if (seen->un->pkg->type != PKG_INSTALLED && pkg->type != PKG_INSTALLED) { - if (pkg->reponame && seen->un->pkg->reponame) { + if (seen->pkg->type != PKG_INSTALLED && pkg->type != PKG_INSTALLED) { + if (pkg->reponame && seen->pkg->reponame) { other_candidate = - (strcmp(pkg->reponame, seen->un->pkg->reponame) != 0); + (strcmp(pkg->reponame, seen->pkg->reponame) != 0); } } if (!other_candidate) { if (found != NULL) - *found = seen->un; + *found = seen; return (EPKG_END); } @@ -220,26 +239,12 @@ pkg_jobs_universe_add_pkg(struct pkg_jobs_universe *universe, struct pkg *pkg, item->pkg = pkg; - - HASH_FIND_STR(universe->items, pkg->uid, tmp); - if (tmp == NULL) - HASH_ADD_KEYPTR(hh, universe->items, pkg->uid, strlen(pkg->uid), item); + kh_add(pkg_job_universe_items, universe->items, item, item->pkg->uid); DL_APPEND(tmp, item); - if (seen == NULL) { - seen = calloc(1, sizeof(struct pkg_job_seen)); - if (seen == NULL) { - pkg_emit_errno("pkg_jobs_universe_add_pkg", "calloc: struct pkg_job_seen)"); - return (EPKG_FATAL); - } - seen->digest = pkg->digest; - seen->un = item; - HASH_ADD_KEYPTR(hh, universe->seen, seen->digest, strlen(seen->digest), - seen); - } - - universe->nitems++; + if (seen == NULL) + kh_add(pkg_jobs_seen, universe->seen, item, item->pkg->digest); if (found != NULL) *found = item; @@ -261,7 +266,8 @@ pkg_jobs_universe_process_deps(struct pkg_jobs_universe *universe, int (*deps_func)(const struct pkg *pkg, struct pkg_dep **d); struct pkg_job_universe_item *unit; struct pkg *npkg, *rpkg; - struct pkg_chain *rpkgs, *cur_remote; + pkg_chain_t *rpkgs = NULL; + int i; if (flags & DEPS_FLAG_REVERSE) deps_func = pkg_rdeps; @@ -269,7 +275,7 @@ pkg_jobs_universe_process_deps(struct pkg_jobs_universe *universe, deps_func = pkg_deps; while (deps_func(pkg, &d) == EPKG_OK) { - HASH_FIND_STR(universe->items, d->uid, unit); + unit = pkg_jobs_universe_find(universe, d->uid); if (unit != NULL) continue; @@ -299,8 +305,8 @@ pkg_jobs_universe_process_deps(struct pkg_jobs_universe *universe, continue; if (rpkgs != NULL) { - LL_FOREACH(rpkgs, cur_remote) { - rpkg = cur_remote->p; + for (i = 0; i < kv_size(*rpkgs); i++) { + rpkg = kv_A(*rpkgs, i); if (npkg != NULL) { /* Set reason for upgrades */ pkg_jobs_need_upgrade(rpkg, npkg); @@ -311,7 +317,8 @@ pkg_jobs_universe_process_deps(struct pkg_jobs_universe *universe, pkg_jobs_universe_process_item(universe, rpkg, NULL); } - pkg_jobs_universe_free_chain(rpkgs); + kv_destroy(*rpkgs); + free(rpkgs); } } @@ -334,7 +341,7 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe, prhead = NULL; while (pkgdb_it_next(it, &rpkg, flags) == EPKG_OK) { /* Check for local packages */ - HASH_FIND_STR(universe->items, rpkg->uid, unit); + unit = pkg_jobs_universe_find(universe, rpkg->uid); if (unit != NULL) { /* Remote provide is newer, so we can add it */ if (pkg_jobs_universe_process_item(universe, rpkg, @@ -359,8 +366,6 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe, /* Skip seen packages */ if (unit == NULL) { - struct pkg_job_seen *seen; - if (rpkg->digest == NULL) { pkg_debug(3, "no digest found for package %s", rpkg->uid); if (pkg_checksum_calculate(rpkg, universe->j->db) != EPKG_OK) { @@ -387,8 +392,7 @@ pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe, if (prhead == NULL) { DL_APPEND(prhead, pr); - HASH_ADD_KEYPTR(hh, universe->provides, pr->provide, - strlen(pr->provide), prhead); + kh_add(pkg_jobs_provide, universe->provides, pr, pr->provide); } else { DL_APPEND(prhead, pr); @@ -402,40 +406,38 @@ static int pkg_jobs_universe_process_shlibs(struct pkg_jobs_universe *universe, struct pkg *pkg) { - struct pkg_shlib *shlib = NULL; - struct pkg_job_provide *pr; + char *shlib = NULL; struct pkgdb_it *it; int rc; while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { - HASH_FIND_STR(universe->provides, shlib->name, pr); - if (pr != NULL) + if (kh_contains(pkg_jobs_provide, universe->provides, shlib)) continue; /* Check for local provides */ - it = pkgdb_query_shlib_provide(universe->j->db, shlib->name); + it = pkgdb_query_shlib_provide(universe->j->db, shlib); if (it != NULL) { - rc = pkg_jobs_universe_handle_provide(universe, it, shlib->name, true); + rc = pkg_jobs_universe_handle_provide(universe, it, shlib, 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); + shlib, pkg->name); } } /* Not found, search in the repos */ it = pkgdb_repo_shlib_provide(universe->j->db, - shlib->name, universe->j->reponame); + shlib, 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, shlib, 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); + shlib, pkg->name); } } } @@ -447,41 +449,39 @@ static int pkg_jobs_universe_process_provides_requires(struct pkg_jobs_universe *universe, struct pkg *pkg) { - struct pkg_provide *p = NULL; - struct pkg_job_provide *pr; struct pkgdb_it *it; + char *p = NULL; int rc; while (pkg_requires(pkg, &p) == EPKG_OK) { - HASH_FIND_STR(universe->provides, p->provide, pr); - if (pr != NULL) + if (kh_contains(pkg_jobs_provide, universe->provides, p)) continue; /* Check for local provides */ - it = pkgdb_query_provide(universe->j->db, p->provide); + it = pkgdb_query_provide(universe->j->db, p); if (it != NULL) { - rc = pkg_jobs_universe_handle_provide(universe, it, p->provide, false); + rc = pkg_jobs_universe_handle_provide(universe, it, p, false); pkgdb_it_free(it); if (rc != EPKG_OK) { pkg_debug(1, "cannot find local packages that provide %s " "required for %s", - p->provide, pkg->name); + p, pkg->name); } } /* Not found, search in the repos */ it = pkgdb_repo_provide(universe->j->db, - p->provide, universe->j->reponame); + p, universe->j->reponame); if (it != NULL) { - rc = pkg_jobs_universe_handle_provide(universe, it, p->provide, false); + rc = pkg_jobs_universe_handle_provide(universe, it, p, false); pkgdb_it_free(it); if (rc != EPKG_OK) { pkg_debug(1, "cannot find remote packages that provide %s " "required for %s", - p->provide, pkg->name); + p, pkg->name); return (rc); } } @@ -632,7 +632,7 @@ pkg_jobs_update_universe_item_priority(struct pkg_jobs_universe *universe, } while (deps_func(it->pkg, &d) == EPKG_OK) { - HASH_FIND_STR(universe->items, d->uid, found); + found = pkg_jobs_universe_find(universe, d->uid); if (found != NULL) { LL_FOREACH(found, cur) { if (cur->priority < priority + 1) @@ -645,7 +645,7 @@ pkg_jobs_update_universe_item_priority(struct pkg_jobs_universe *universe, d = NULL; maxpri = priority; while (rdeps_func(it->pkg, &d) == EPKG_OK) { - HASH_FIND_STR(universe->items, d->uid, found); + found = pkg_jobs_universe_find(universe, d->uid); if (found != NULL) { LL_FOREACH(found, cur) { if (cur->priority >= maxpri) { @@ -661,7 +661,7 @@ pkg_jobs_update_universe_item_priority(struct pkg_jobs_universe *universe, } if (it->pkg->type != PKG_INSTALLED) { while (pkg_conflicts(it->pkg, &c) == EPKG_OK) { - HASH_FIND_STR(universe->items, c->uid, found); + found = pkg_jobs_universe_find(universe, c->uid); if (found != NULL) { LL_FOREACH(found, cur) { if (cur->pkg->type == PKG_INSTALLED) { @@ -689,7 +689,7 @@ pkg_jobs_update_conflict_priority(struct pkg_jobs_universe *universe, while (pkg_conflicts(lp, &c) == EPKG_OK) { rit = NULL; - HASH_FIND_STR(universe->items, c->uid, found); + found = pkg_jobs_universe_find(universe, c->uid); assert(found != NULL); LL_FOREACH(found, cur) { @@ -741,19 +741,22 @@ pkg_jobs_universe_replacement_free(struct pkg_job_replace *r) void pkg_jobs_universe_free(struct pkg_jobs_universe *universe) { - struct pkg_job_universe_item *un, *untmp, *cur, *curtmp; - - HASH_ITER(hh, universe->items, un, untmp) { - HASH_DEL(universe->items, un); + struct pkg_job_universe_item *un, *cur, *curtmp; + struct pkg_job_provide *p; + kh_each_value(universe->items, un, { LL_FOREACH_SAFE(un, cur, curtmp) { pkg_free(cur->pkg); free(cur); } - } - HASH_FREE(universe->seen, free); - HASH_FREE(universe->provides, pkg_jobs_universe_provide_free); - LL_FREE(universe->uid_replaces, pkg_jobs_universe_replacement_free); + }); + kh_destroy_pkg_job_universe_items(universe->items); + kh_destroy_pkg_jobs_seen(universe->seen); + kh_each_value(universe->provides, p, pkg_jobs_universe_provide_free(p)); + kh_destroy_pkg_jobs_provide(universe->provides); + while (kv_size(universe->uid_replaces)) + pkg_jobs_universe_replacement_free(kv_pop(universe->uid_replaces)); + kv_destroy(universe->uid_replaces); } @@ -769,30 +772,11 @@ pkg_jobs_universe_new(struct pkg_jobs *j) } universe->j = j; + kv_init(universe->uid_replaces); return (universe); } -struct pkg_job_universe_item * -pkg_jobs_universe_find(struct pkg_jobs_universe *universe, const char *uid) -{ - struct pkg_job_universe_item *unit; - - HASH_FIND_STR(universe->items, uid, unit); - - return (unit); -} - -struct pkg_job_seen * -pkg_jobs_universe_seen(struct pkg_jobs_universe *universe, const char *digest) -{ - struct pkg_job_seen *seen; - - HASH_FIND_STR(universe->seen, digest, seen); - - return (seen); -} - void pkg_jobs_universe_change_uid(struct pkg_jobs_universe *universe, struct pkg_job_universe_item *unit, @@ -830,18 +814,18 @@ pkg_jobs_universe_change_uid(struct pkg_jobs_universe *universe, if (replacement != NULL) { replacement->old_uid = strdup(unit->pkg->uid); replacement->new_uid = strdup(new_uid); - LL_PREPEND(universe->uid_replaces, replacement); + kv_prepend(typeof(replacement), universe->uid_replaces, replacement); } - HASH_DELETE(hh, universe->items, unit); + pkg_jobs_universe_del(universe, unit); free(unit->pkg->uid); unit->pkg->uid = strdup(new_uid); - HASH_FIND(hh, universe->items, new_uid, uidlen, found); + found = pkg_jobs_universe_find(universe, new_uid); if (found != NULL) DL_APPEND(found, unit); else - HASH_ADD_KEYPTR(hh, universe->items, new_uid, uidlen, unit); + kh_add(pkg_job_universe_items, universe->items, unit, unit->pkg->uid); } @@ -998,14 +982,14 @@ pkg_jobs_universe_select_candidate(struct pkg_job_universe_item *chain, void pkg_jobs_universe_process_upgrade_chains(struct pkg_jobs *j) { - struct pkg_job_universe_item *unit, *tmp, *cur, *local; + struct pkg_job_universe_item *unit, *cur, *local; struct pkg_job_request *req; struct pkg_job_request_item *rit, *rtmp; bool conservative = false; conservative = pkg_object_bool(pkg_config_get("CONSERVATIVE_UPGRADE")); - HASH_ITER(hh, j->universe->items, unit, tmp) { + kh_each_value(j->universe->items, unit, { unsigned vercnt = 0; HASH_FIND_STR(j->request_add, unit->pkg->uid, req); @@ -1078,7 +1062,7 @@ pkg_jobs_universe_process_upgrade_chains(struct pkg_jobs *j) HASH_ADD_KEYPTR(hh, j->request_add, selected->pkg->uid, strlen (selected->pkg->uid), req); } - } + }); } struct pkg_job_universe_item* @@ -1092,10 +1076,9 @@ pkg_jobs_universe_get_upgrade_candidates(struct pkg_jobs_universe *universe, PKG_LOAD_REQUIRES|PKG_LOAD_PROVIDES| PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED| PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS; - UT_array *candidates; - struct pkg **p = NULL; + kvec_t(struct pkg *) candidates; - HASH_FIND(hh, universe->items, uid, strlen(uid), unit); + unit = pkg_jobs_universe_find(universe, uid); if (unit != NULL) { /* * If a unit has been found, we have already found the potential @@ -1121,7 +1104,7 @@ pkg_jobs_universe_get_upgrade_candidates(struct pkg_jobs_universe *universe, universe->j->reponame)) == NULL) return (NULL); - utarray_new(candidates, &ut_ptr_icd); + kv_init(candidates); while (pkgdb_it_next(it, &pkg, flag) == EPKG_OK) { if (force) { @@ -1135,7 +1118,7 @@ pkg_jobs_universe_get_upgrade_candidates(struct pkg_jobs_universe *universe, else if (pkg_version_change_between(pkg, selected) == PKG_UPGRADE) selected = pkg; } - utarray_push_back(candidates, &pkg); + kv_prepend(typeof(pkg), candidates, pkg); pkg = NULL; } @@ -1147,22 +1130,20 @@ pkg_jobs_universe_get_upgrade_candidates(struct pkg_jobs_universe *universe, } if (selected != lp) { /* We need to add the whole chain of upgrade candidates */ - while ((p = (struct pkg **)utarray_next(candidates, p)) != NULL) { - pkg_jobs_universe_add_pkg(universe, *p, true, NULL); + for (int i = 0; i < kv_size(candidates); i++) { + pkg_jobs_universe_add_pkg(universe, kv_A(candidates, i), true, NULL); } } else { - while ((p = (struct pkg **)utarray_next(candidates, p)) != NULL) { - pkg_free(*p); - } - - utarray_free(candidates); + while (kv_size(candidates) > 0) + pkg_free(kv_pop(candidates)); + kv_destroy(candidates); return (NULL); } - HASH_FIND(hh, universe->items, uid, strlen(uid), unit); - utarray_free(candidates); + unit = pkg_jobs_universe_find(universe, uid); + kv_destroy(candidates); return (unit); } diff --git a/libpkg/pkg_manifest.c b/libpkg/pkg_manifest.c index 8c00c99..252ed64 100644 --- a/libpkg/pkg_manifest.c +++ b/libpkg/pkg_manifest.c @@ -928,10 +928,8 @@ 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; + char *buf = NULL; struct pkg_conflict *conflict = NULL; - struct pkg_provide *provide = NULL; - struct pkg_provide *require = NULL; struct pkg_config_file *cf = NULL; struct sbuf *tmpsbuf = NULL; int i; @@ -1055,20 +1053,22 @@ pkg_emit_object(struct pkg *pkg, short flags) pkg_debug(4, "Emitting required"); seq = NULL; - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { + buf = NULL; + while (pkg_shlibs_required(pkg, &buf) == EPKG_OK) { 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(buf)); } 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) { + buf = NULL; + while (pkg_shlibs_provided(pkg, &buf) == EPKG_OK) { 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(buf)); } if (seq) ucl_object_insert_key(top, seq, "shlibs_provided", 15, false); @@ -1085,20 +1085,22 @@ pkg_emit_object(struct pkg *pkg, short flags) pkg_debug(4, "Emitting provides"); seq = NULL; - while (pkg_provides(pkg, &provide) == EPKG_OK) { + buf = NULL; + while (pkg_provides(pkg, &buf) == EPKG_OK) { if (seq == NULL) seq = ucl_object_typed_new(UCL_ARRAY); - ucl_array_append(seq, ucl_object_fromstring(provide->provide)); + ucl_array_append(seq, ucl_object_fromstring(buf)); } if (seq) ucl_object_insert_key(top, seq, "provides", 8, false); pkg_debug(4, "Emitting requires"); seq = NULL; - while (pkg_requires(pkg, &require) == EPKG_OK) { + buf = NULL; + while (pkg_requires(pkg, &buf) == EPKG_OK) { if (seq == NULL) seq = ucl_object_typed_new(UCL_ARRAY); - ucl_array_append(seq, ucl_object_fromstring(require->provide)); + ucl_array_append(seq, ucl_object_fromstring(buf)); } if (seq) ucl_object_insert_key(top, seq, "requires", 8, false); diff --git a/libpkg/pkg_printf.c b/libpkg/pkg_printf.c index 73e4268..355050b 100644 --- a/libpkg/pkg_printf.c +++ b/libpkg/pkg_printf.c @@ -912,8 +912,8 @@ format_shlibs_required(struct sbuf *sbuf, const void *data, struct percent_esc * 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; + char *shlib = NULL; + int count; set_list_defaults(p, "%Bn\n", ""); @@ -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 *shlib = data; - return (string_val(sbuf, shlib->name, p)); + return (string_val(sbuf, shlib, p)); } /* @@ -1470,8 +1470,8 @@ format_required(struct sbuf *sbuf, const void *data, struct percent_esc *p) if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) return (list_count(sbuf, pkg_list_count(pkg, PKG_REQUIRES), p)); else { - struct pkg_provide *provide = NULL; - int count; + char *provide = NULL; + int count; set_list_defaults(p, "%Yn\n", ""); @@ -1495,9 +1495,9 @@ format_required(struct sbuf *sbuf, const void *data, struct percent_esc *p) struct sbuf * format_provide_name(struct sbuf *sbuf, const void *data, struct percent_esc *p) { - const struct pkg_provide *provide = data; + const char *provide = data; - return (string_val(sbuf, provide->provide, p)); + return (string_val(sbuf, provide, p)); } /* * %a -- Autoremove flag. boolean. Accepts field-width, left-align. @@ -1526,8 +1526,8 @@ format_shlibs_provided(struct sbuf *sbuf, const void *data, struct percent_esc * 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; + char *shlib = NULL; + int count; set_list_defaults(p, "%bn\n", ""); @@ -1861,8 +1861,8 @@ format_provided(struct sbuf *sbuf, const void *data, struct percent_esc *p) if (p->flags & (PP_ALTERNATE_FORM1|PP_ALTERNATE_FORM2)) return (list_count(sbuf, pkg_list_count(pkg, PKG_PROVIDES), p)); else { - struct pkg_provide *provide = NULL; - int count; + char *provide = NULL; + int count; set_list_defaults(p, "%yn\n", ""); diff --git a/libpkg/pkg_solve.c b/libpkg/pkg_solve.c index eb4beb7..7cc28ac 100644 --- a/libpkg/pkg_solve.c +++ b/libpkg/pkg_solve.c @@ -302,9 +302,8 @@ pkg_solve_handle_provide (struct pkg_solve_problem *problem, struct pkg_solve_item *it = NULL; struct pkg_solve_variable *var, *curvar; struct pkg_job_universe_item *un; - struct pkg_shlib *shlp; - struct pkg_provide *np; struct pkg *pkg; + bool libfound, provide; /* Find the first package in the universe list */ un = pr->un; @@ -320,25 +319,24 @@ pkg_solve_handle_provide (struct pkg_solve_problem *problem, * For each provide we need to check whether this package * actually provides this require */ - shlp = NULL; - np = NULL; + libfound = provide = false; + pkg = curvar->unit->pkg; if (pr->is_shlib) { - HASH_FIND_STR(pkg->shlibs_provided, pr->provide, shlp); + libfound = kh_contains(strings, pkg->shlibs_provided, pr->provide); /* Skip incompatible ABI as well */ - if (shlp != NULL && strcmp(pkg->arch, orig->arch) != 0) { + if (libfound && 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; } - } - else { - HASH_FIND_STR(pkg->provides, pr->provide, np); + } else { + provide = kh_contains(strings, pkg->provides, pr->provide); } - if (np == NULL && shlp == NULL) { + if (!provide && !libfound) { pkg_debug(4, "%s provide is not satisfied by %s-%s(%c)", pr->provide, pkg->name, pkg->version, pkg->type == PKG_INSTALLED ? 'l' : 'r'); @@ -491,13 +489,18 @@ pkg_solve_add_require_rule(struct pkg_solve_problem *problem, { struct pkg_solve_rule *rule; struct pkg_solve_item *it = NULL; - struct pkg_job_provide *pr, *prhead; + struct pkg_job_provide *pr, *prhead = NULL; struct pkg *pkg; int cnt; + khint_t k; pkg = var->unit->pkg; - HASH_FIND_STR(problem->j->universe->provides, requirement, prhead); + if (kh_count(problem->j->universe->provides) > 0) { + k = kh_get_pkg_jobs_provide(problem->j->universe->provides, requirement); + if (k != kh_end(problem->j->universe->provides)) + prhead = kh_value(problem->j->universe->provides, k); + } if (prhead != NULL) { pkg_debug(4, "solver: Add require rule: %s-%s(%c) wants %s", pkg->name, pkg->version, pkg->type == PKG_INSTALLED ? 'l' : 'r', @@ -613,7 +616,7 @@ pkg_solve_add_request_rule(struct pkg_solve_problem *problem, cnt ++; } - if (cnt > 1 && var->unit->hh.keylen != 0) { + if (cnt > 1 && var->unit->pkg->uid != NULL) { kv_prepend(typeof(rule), problem->rules, rule); /* Also need to add pairs of conflicts */ LL_FOREACH(req->item, item) { @@ -715,12 +718,11 @@ static int pkg_solve_process_universe_variable(struct pkg_solve_problem *problem, struct pkg_solve_variable *var) { - struct pkg_dep *dep, *dtmp; + struct pkg_dep *dep; struct pkg_conflict *conflict, *ctmp; struct pkg *pkg; struct pkg_solve_variable *cur_var; - struct pkg_shlib *shlib = NULL; - struct pkg_provide *p = NULL; + char *buf = NULL; struct pkg_jobs *j = problem->j; struct pkg_job_request *jreq; bool chain_added = false; @@ -729,10 +731,10 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem, pkg = cur_var->unit->pkg; /* Depends */ - HASH_ITER(hh, pkg->deps, dep, dtmp) { + kh_each_value(pkg->deps, dep, { if (pkg_solve_add_depend_rule(problem, cur_var, dep) != EPKG_OK) continue; - } + }); /* Conflicts */ HASH_ITER(hh, pkg->conflicts, conflict, ctmp) { @@ -742,16 +744,16 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem, } /* Shlibs */ - shlib = NULL; - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { + buf = NULL; + while (pkg_shlibs_required(pkg, &buf) == EPKG_OK) { if (pkg_solve_add_require_rule(problem, cur_var, - shlib->name) != EPKG_OK) + buf) != EPKG_OK) continue; } - p = NULL; - while (pkg_requires(pkg, &p) == EPKG_OK) { + buf = NULL; + while (pkg_requires(pkg, &buf) == EPKG_OK) { if (pkg_solve_add_require_rule(problem, cur_var, - p->provide) != EPKG_OK) + buf) != EPKG_OK) continue; } @@ -816,7 +818,7 @@ struct pkg_solve_problem * pkg_solve_jobs_to_sat(struct pkg_jobs *j) { struct pkg_solve_problem *problem; - struct pkg_job_universe_item *un, *utmp; + struct pkg_job_universe_item *un; size_t i = 0; problem = calloc(1, sizeof(struct pkg_solve_problem)); @@ -827,7 +829,7 @@ pkg_solve_jobs_to_sat(struct pkg_jobs *j) } problem->j = j; - problem->nvars = j->universe->nitems; + problem->nvars = kh_count(j->universe->items); problem->variables = calloc(problem->nvars, sizeof(struct pkg_solve_variable)); problem->sat = picosat_init(); kv_init(problem->rules); @@ -845,15 +847,15 @@ pkg_solve_jobs_to_sat(struct pkg_jobs *j) picosat_adjust(problem->sat, problem->nvars); /* Parse universe */ - HASH_ITER(hh, j->universe->items, un, utmp) { + kh_each_value(j->universe->items, un, { /* Add corresponding variables */ if (pkg_solve_add_variable(un, problem, &i) == EPKG_FATAL) goto err; - } + }); /* Add rules for all conflict chains */ - HASH_ITER(hh, j->universe->items, un, utmp) { + kh_each_value(j->universe->items, un, { struct pkg_solve_variable *var; HASH_FIND_STR(problem->variables_by_uid, un->pkg->uid, var); @@ -864,7 +866,7 @@ pkg_solve_jobs_to_sat(struct pkg_jobs *j) } if (pkg_solve_process_universe_variable(problem, var) != EPKG_OK) goto err; - } + }); if (kv_size(problem->rules) == 0) { pkg_debug(1, "problem has no requests"); diff --git a/libpkg/pkgdb.c b/libpkg/pkgdb.c index f460522..3878bb8 100644 --- a/libpkg/pkgdb.c +++ b/libpkg/pkgdb.c @@ -69,6 +69,7 @@ #include "private/pkgdb.h" #include "private/utils.h" #include "private/pkg_deps.h" +#include "kvec.h" #include "private/db_upgrades.h" @@ -1984,13 +1985,13 @@ 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 *shlib = NULL; while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { - if (run_prstmt(SHLIBS1, shlib->name) + if (run_prstmt(SHLIBS1, shlib) != SQLITE_DONE || - run_prstmt(SHLIBS_REQD, package_id, shlib->name) + run_prstmt(SHLIBS_REQD, package_id, shlib) != SQLITE_DONE) { ERROR_SQLITE(s, SQL(SHLIBS_REQD)); return (EPKG_FATAL); @@ -2019,13 +2020,13 @@ 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 *shlib = NULL; while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) { - if (run_prstmt(SHLIBS1, shlib->name) + if (run_prstmt(SHLIBS1, shlib) != SQLITE_DONE || - run_prstmt(SHLIBS_PROV, package_id, shlib->name) + run_prstmt(SHLIBS_PROV, package_id, shlib) != SQLITE_DONE) { ERROR_SQLITE(s, SQL(SHLIBS_PROV)); return (EPKG_FATAL); @@ -2038,13 +2039,13 @@ pkgdb_update_shlibs_provided(struct pkg *pkg, int64_t package_id, sqlite3 *s) int pkgdb_update_requires(struct pkg *pkg, int64_t package_id, sqlite3 *s) { - struct pkg_provide *provide = NULL; + char *provide = NULL; while (pkg_requires(pkg, &provide) == EPKG_OK) { - if (run_prstmt(REQUIRE, provide->provide) + if (run_prstmt(REQUIRE, provide) != SQLITE_DONE || - run_prstmt(PKG_REQUIRE, package_id, provide->provide) + run_prstmt(PKG_REQUIRE, package_id, provide) != SQLITE_DONE) { ERROR_SQLITE(s, SQL(PKG_REQUIRE)); return (EPKG_FATAL); @@ -2057,13 +2058,13 @@ pkgdb_update_requires(struct pkg *pkg, int64_t package_id, sqlite3 *s) int pkgdb_update_provides(struct pkg *pkg, int64_t package_id, sqlite3 *s) { - struct pkg_provide *provide = NULL; + char *require = NULL; - while (pkg_provides(pkg, &provide) == EPKG_OK) { - if (run_prstmt(PROVIDE, provide->provide) + while (pkg_provides(pkg, &require) == EPKG_OK) { + if (run_prstmt(PROVIDE, require) != SQLITE_DONE || - run_prstmt(PKG_PROVIDE, package_id, provide->provide) + run_prstmt(PKG_PROVIDE, package_id, require) != SQLITE_DONE) { ERROR_SQLITE(s, SQL(PKG_PROVIDE)); return (EPKG_FATAL); @@ -3076,29 +3077,33 @@ pkgdb_begin_solver(struct pkgdb *db) "END TRANSACTION;" "CREATE INDEX pkg_digest_id ON packages(origin, manifestdigest);"; struct pkgdb_it *it; - struct pkg *pkglist = NULL, *p = NULL; + kvec_t(struct pkg *) pkglist; + struct pkg *p = NULL; int rc = EPKG_OK; int64_t cnt = 0, cur = 0; + int i; it = pkgdb_query(db, " WHERE manifestdigest IS NULL OR manifestdigest==''", MATCH_CONDITION); if (it != NULL) { + kv_init(pkglist); while (pkgdb_it_next(it, &p, PKG_LOAD_BASIC|PKG_LOAD_OPTIONS) == EPKG_OK) { pkg_checksum_calculate(p, NULL); - LL_PREPEND(pkglist, p); + kv_prepend(typeof(p), pkglist, p); p = NULL; cnt ++; } pkgdb_it_free(it); - if (pkglist != NULL) { + if (kv_size(pkglist) > 0) { rc = sql_exec(db->sqlite, update_digests_sql); if (rc != EPKG_OK) { ERROR_SQLITE(db->sqlite, update_digests_sql); } else { pkg_emit_progress_start("Updating database digests format"); - LL_FOREACH(pkglist, p) { + for (i = 0; i < kv_size(pkglist); i++) { + p = kv_A(pkglist, i); pkg_emit_progress_tick(cur++, cnt); rc = run_prstmt(UPDATE_DIGEST, p->digest, p->id); if (rc != SQLITE_DONE) { @@ -3119,7 +3124,9 @@ pkgdb_begin_solver(struct pkgdb *db) if (rc == EPKG_OK) rc = sql_exec(db->sqlite, solver_sql); - LL_FREE(pkglist, pkg_free); + while (kv_size(pkglist) > 0 && (p = kv_pop(pkglist))) + pkg_free(p); + kv_destroy(pkglist); } else { rc = sql_exec(db->sqlite, solver_sql); diff --git a/libpkg/private/pkg.h b/libpkg/private/pkg.h index 7c7c718..2302e25 100644 --- a/libpkg/private/pkg.h +++ b/libpkg/private/pkg.h @@ -121,6 +121,73 @@ return (EPKG_OK); \ } while (0) +#define kh_string_next(head, data) do { \ + khint_t k; \ + if (head == NULL) \ + return (EPKG_END); \ + if (data == NULL) { \ + k = kh_begin(head); \ + } else { \ + k = kh_get_strings(head, (data)); \ + k++; \ + } \ + while (k != kh_end(head) && !kh_exist(head, k)) \ + k++; \ + if (k == kh_end(head)) \ + return (EPKG_END); \ + data = kh_value(head, k); \ + return (EPKG_OK); \ +} while (0) + +#define kh_next(name, head, data, attrib) do { \ + khint_t k; \ + if (head == NULL) \ + return (EPKG_END); \ + if (data == NULL) { \ + k = kh_begin(head); \ + } else { \ + k = kh_get_##name(head, (data)->attrib); \ + k++; \ + } \ + while (k != kh_end(head) && !kh_exist(head, k)) \ + k++; \ + if (k == kh_end(head)) { \ + data = NULL; \ + return (EPKG_END); \ + } \ + data = kh_value(head, k); \ + return (EPKG_OK); \ +} while (0) + +#define kh_free(name, head, type, free_func) do { \ + if (head) { \ + type *_todelete; \ + kh_foreach_value(head, _todelete, free_func(_todelete));\ + kh_destroy_##name(head); \ + head = NULL; \ + } \ +} while (0) + +#define kh_contains(name, h, v) ((h)?(kh_get_##name(h, v) != kh_end(h)):false) + +#define kh_each_value(h, vvar, code) \ + for (khint_t __i = kh_begin(h); h != NULL && __i != kh_end(h); __i++) { \ + if (!kh_exist(h, __i)) continue; \ + (vvar) = kh_val(h, __i); \ + code; \ + } + +#define kh_count(h) ((h)?((h)->size):0) + +#define kh_add(name, h, val, k) do { \ + int __ret; \ + khint_t __i; \ + if (!h) h = kh_init_##name(); \ + __i = kh_put_##name(h, k, &__ret); \ + if (__ret != 0) \ + kh_val(h, __i) = val; \ +} while (0) + extern int eventpipe; extern int64_t debug_level; extern bool developer_mode; @@ -129,6 +196,10 @@ extern const char *pkg_rootdir; struct pkg_repo_it; struct pkg_repo; +KHASH_MAP_INIT_STR(pkg_deps, struct pkg_dep *); +KHASH_MAP_INIT_STR(pkg_files, struct pkg_file *); +KHASH_MAP_INIT_STR(strings, char *); + struct pkg { bool direct; bool locked; @@ -161,20 +232,20 @@ struct pkg { int64_t flatsize; int64_t old_flatsize; int64_t timestamp; - struct pkg_dep *deps; - struct pkg_dep *rdeps; + kh_pkg_deps_t *deps; + kh_pkg_deps_t *rdeps; struct pkg_strel *categories; struct pkg_strel *licenses; - struct pkg_file *files; + kh_pkg_files_t *files; struct pkg_dir *dirs; struct pkg_option *options; struct pkg_user *users; struct pkg_group *groups; - struct pkg_shlib *shlibs_required; - struct pkg_shlib *shlibs_provided; + kh_strings_t *shlibs_required; + kh_strings_t *shlibs_provided; struct pkg_conflict *conflicts; - struct pkg_provide *provides; - struct pkg_provide *requires; + kh_strings_t *provides; + kh_strings_t *requires; struct pkg_config_file *config_files; struct pkg_kv *annotations; unsigned flags; @@ -185,8 +256,6 @@ struct pkg { size_t dir_to_del_len; pkg_t type; struct pkg_repo *repo; - UT_hash_handle hh; - struct pkg *next; }; struct pkg_dep { @@ -195,7 +264,6 @@ struct pkg_dep { char *version; char *uid; bool locked; - UT_hash_handle hh; }; enum pkg_conflict_type { @@ -212,11 +280,6 @@ struct pkg_conflict { UT_hash_handle hh; }; -struct pkg_provide { - char *provide; - UT_hash_handle hh; -}; - struct pkg_file { char path[MAXPATHLEN]; int64_t size; @@ -225,7 +288,6 @@ struct pkg_file { char gname[MAXLOGNAME]; mode_t perm; u_long fflags; - UT_hash_handle hh; }; struct pkg_dir { @@ -257,11 +319,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; @@ -560,15 +617,9 @@ 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 *); -int pkg_provide_new(struct pkg_provide **); -void pkg_provide_free(struct pkg_provide *); - int pkg_config_file_new(struct pkg_config_file **); void pkg_config_file_free(struct pkg_config_file *); diff --git a/libpkg/private/pkg_jobs.h b/libpkg/private/pkg_jobs.h index f3e7fcc..c529d37 100644 --- a/libpkg/private/pkg_jobs.h +++ b/libpkg/private/pkg_jobs.h @@ -36,6 +36,7 @@ #include "private/pkg.h" #include "pkg.h" #include "tree.h" +#include "kvec.h" struct pkg_jobs; struct job_pattern; @@ -44,10 +45,11 @@ struct pkg_job_universe_item { struct pkg *pkg; int priority; bool processed; - UT_hash_handle hh; struct pkg_job_universe_item *next, *prev; }; +KHASH_MAP_INIT_STR(pkg_job_universe_items, struct pkg_job_universe_item *); + struct pkg_job_request_item { struct pkg *pkg; struct pkg_job_universe_item *unit; @@ -69,34 +71,28 @@ struct pkg_solved { struct pkg_solved *prev, *next; }; -struct pkg_job_seen { - struct pkg_job_universe_item *un; - const char *digest; - UT_hash_handle hh; -}; +KHASH_MAP_INIT_STR(pkg_jobs_seen, struct pkg_job_universe_item *); struct pkg_job_provide { struct pkg_job_universe_item *un; const char *provide; bool is_shlib; struct pkg_job_provide *next, *prev; - UT_hash_handle hh; }; +KHASH_MAP_INIT_STR(pkg_jobs_provide, struct pkg_job_provide *); + struct pkg_job_replace { char *new_uid; char *old_uid; - struct pkg_job_replace *next; }; - struct pkg_jobs_universe { - struct pkg_job_universe_item *items; - struct pkg_job_seen *seen; - struct pkg_job_provide *provides; - struct pkg_job_replace *uid_replaces; + kh_pkg_job_universe_items_t *items; + kh_pkg_jobs_seen_t *seen; + kh_pkg_jobs_provide_t *provides; + kvec_t(struct pkg_job_replace *) uid_replaces; struct pkg_jobs *j; - size_t nitems; }; struct pkg_jobs_conflict_item { @@ -173,12 +169,6 @@ int pkg_jobs_universe_process_item(struct pkg_jobs_universe *universe, struct pkg *pkg, struct pkg_job_universe_item **result); /* - * Check if the specified digest was seen in the universe - */ -struct pkg_job_seen* pkg_jobs_universe_seen(struct pkg_jobs_universe *universe, - const char *digest); - -/* * Search for an entry corresponding to the uid in the universe */ struct pkg_job_universe_item* pkg_jobs_universe_find(struct pkg_jobs_universe diff --git a/libpkg/repo/binary/update.c b/libpkg/repo/binary/update.c index 03e634a..706a801 100644 --- a/libpkg/repo/binary/update.c +++ b/libpkg/repo/binary/update.c @@ -138,8 +138,7 @@ 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; + char *buf = NULL; struct pkg_strel *el; struct pkg_kv *kv; const char *arch; @@ -224,48 +223,48 @@ try_again: } } - shlib = NULL; - while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) { - ret = pkg_repo_binary_run_prstatement(SHLIB1, shlib->name); + buf = NULL; + while (pkg_shlibs_required(pkg, &buf) == EPKG_OK) { + ret = pkg_repo_binary_run_prstatement(SHLIB1, buf); if (ret == SQLITE_DONE) ret = pkg_repo_binary_run_prstatement(SHLIB_REQD, package_id, - shlib->name); + buf); 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); + buf = NULL; + while (pkg_shlibs_provided(pkg, &buf) == EPKG_OK) { + ret = pkg_repo_binary_run_prstatement(SHLIB1, buf); if (ret == SQLITE_DONE) ret = pkg_repo_binary_run_prstatement(SHLIB_PROV, package_id, - shlib->name); + buf); 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) { - ret = pkg_repo_binary_run_prstatement(PROVIDE, provide->provide); + buf = NULL; + while (pkg_provides(pkg, &buf) == EPKG_OK) { + ret = pkg_repo_binary_run_prstatement(PROVIDE, buf); if (ret == SQLITE_DONE) ret = pkg_repo_binary_run_prstatement(PROVIDES, package_id, - provide->provide); + buf); if (ret != SQLITE_DONE) { ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(PROVIDES)); return (EPKG_FATAL); } } - provide = NULL; - while (pkg_requires(pkg, &provide) == EPKG_OK) { - ret = pkg_repo_binary_run_prstatement(REQUIRE, provide->provide); + buf = NULL; + while (pkg_requires(pkg, &buf) == EPKG_OK) { + ret = pkg_repo_binary_run_prstatement(REQUIRE, buf); if (ret == SQLITE_DONE) ret = pkg_repo_binary_run_prstatement(REQUIRES, package_id, - provide->provide); + buf); if (ret != SQLITE_DONE) { ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(REQUIRES)); return (EPKG_FATAL); diff --git a/src/audit.c b/src/audit.c index d4a0c85..4cdb1a1 100644 --- a/src/audit.c +++ b/src/audit.c @@ -129,7 +129,6 @@ exec_audit(int argc, char **argv) int ret = EX_OK; const char *portaudit_site = NULL; struct sbuf *sb; - const char *key; kh_pkgs_t *check = NULL; db_dir = pkg_object_string(pkg_config_get("PKG_DBDIR")); @@ -273,7 +272,7 @@ exec_audit(int argc, char **argv) #endif if (pkg_audit_process(audit) == EPKG_OK) { - kh_foreach(check, key, pkg, { + kh_foreach_value(check, pkg, { if (pkg_audit_is_vulnerable(audit, pkg, quiet, &sb)) { vuln ++; printf("%s", sbuf_data(sb)); diff --git a/src/check.c b/src/check.c index 3d93263..1d6dc39 100644 --- a/src/check.c +++ b/src/check.c @@ -63,9 +63,8 @@ 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; + char *buf; struct pkgdb_it *it; - struct pkg_provide *provide = NULL; int nbpkgs = 0; assert(db != NULL); @@ -85,33 +84,35 @@ 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) { - it = pkgdb_query_shlib_provide(db, pkg_shlib_name(shlib)); + buf = NULL; + while (pkg_shlibs_required(p, &buf) == EPKG_OK) { + it = pkgdb_query_shlib_provide(db, buf); if (it != NULL && pkgdb_it_count(it) > 0) { pkgdb_it_free(it); continue; } pkgdb_it_free(it); if (quiet) - pkg_sbuf_printf(out, "%n\t%Bn\n", p, shlib); + pkg_sbuf_printf(out, "%n\t%Bn\n", p, buf); else pkg_sbuf_printf(out, "%n has require a missing libraries: %Bn\n", - p, shlib); + p, buf); } /* checking requires */ - while (pkg_requires(p, &provide) == EPKG_OK) { - it = pkgdb_query_provide(db, pkg_provide_name(provide)); + buf = NULL; + while (pkg_requires(p, &buf) == EPKG_OK) { + it = pkgdb_query_provide(db, buf); if (it != NULL && pkgdb_it_count(it) > 0) { pkgdb_it_free(it); continue; } pkgdb_it_free(it); if (quiet) - pkg_sbuf_printf(out, "%n\tYn\n", p, provide); + pkg_sbuf_printf(out, "%n\tYn\n", p, buf); else pkg_sbuf_printf(out, "%n has a missing requirement: %Yn\n", - p, provide); + p, buf); } return (nbpkgs); diff --git a/src/clean.c b/src/clean.c index af99dc8..51d72f9 100644 --- a/src/clean.c +++ b/src/clean.c @@ -301,7 +301,7 @@ exec_clean(int argc, char **argv) } } if (sumlist != NULL) { - kh_foreach(sumlist, sum, cksum, free(cksum)); + kh_foreach_value(sumlist, cksum, free(cksum)); kh_destroy_sum(sumlist); } diff --git a/src/query.c b/src/query.c index 2d96abf..593a242 100644 --- a/src/query.c +++ b/src/query.c @@ -336,9 +336,9 @@ 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; + char *buf; switch (multiline) { case 'd': @@ -400,14 +400,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); + buf = NULL; + while (pkg_shlibs_required(pkg, &buf) == EPKG_OK) { + format_str(pkg, output, qstr, buf); printf("%s\n", sbuf_data(output)); } break; case 'b': - while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) { - format_str(pkg, output, qstr, shlib); + buf = NULL; + while (pkg_shlibs_provided(pkg, &buf) == EPKG_OK) { + format_str(pkg, output, qstr, buf); printf("%s\n", sbuf_data(output)); } break; diff --git a/src/version.c b/src/version.c index f05b8f3..3be0322 100644 --- a/src/version.c +++ b/src/version.c @@ -349,13 +349,12 @@ hash_indexfile(const char *indexfilename) static void free_categories(void) { - const char *key, *k; char *v; struct category *cat; - kh_foreach(categories, key, cat, { + kh_foreach_value(categories, cat, { free(cat->name); - kh_foreach(cat->ports, k, v, free(v)); + kh_foreach_value(cat->ports, v, free(v)); kh_destroy_ports(cat->ports); free(cat); }); @@ -365,13 +364,12 @@ free_categories(void) static void free_index(kh_index_t *index) { - const char *key __unused; struct index_entry *entry; if (index == NULL) return; - kh_foreach(index, key, entry, { + kh_foreach_value(index, entry, { free(entry->origin); free(entry->version); free(entry);