diff options
author | Fabian Groffen <grobian@gentoo.org> | 2023-02-07 09:08:13 +0100 |
---|---|---|
committer | Fabian Groffen <grobian@gentoo.org> | 2023-02-07 09:08:13 +0100 |
commit | e2ebb44db31d4e0e9bfc0a9974d36eff63c8b2b1 (patch) | |
tree | 992157f1f78251bd617bf445c6b818a2314440dd | |
parent | qmerge: add some braindump notes about how things could be (diff) | |
download | portage-utils-e2ebb44db31d4e0e9bfc0a9974d36eff63c8b2b1.tar.gz portage-utils-e2ebb44db31d4e0e9bfc0a9974d36eff63c8b2b1.tar.bz2 portage-utils-e2ebb44db31d4e0e9bfc0a9974d36eff63c8b2b1.zip |
set: ensure NULL is empty behaviour is retained throughout
Not all set functions respected NULL is empty behaviour, changed
add_set_value signature to return a set instead so it can conform.
Bug: https://bugs.gentoo.org/893424
Signed-off-by: Fabian Groffen <grobian@gentoo.org>
-rw-r--r-- | libq/set.c | 47 | ||||
-rw-r--r-- | libq/set.h | 4 | ||||
-rw-r--r-- | libq/tree.c | 5 | ||||
-rw-r--r-- | main.c | 6 | ||||
-rw-r--r-- | qkeyword.c | 6 | ||||
-rw-r--r-- | qlop.c | 12 |
6 files changed, 59 insertions, 21 deletions
@@ -1,5 +1,5 @@ /* - * Copyright 2005-2019 Gentoo Foundation + * Copyright 2005-2023 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2010 Ned Ludd - <solar@gentoo.org> @@ -112,17 +112,22 @@ add_set_unique(const char *name, set *q, bool *unique) /* add ptr to set with name as key, return existing value when key * already exists or NULL otherwise */ -void * -add_set_value(const char *name, void *ptr, set *q) +set * +add_set_value(const char *name, void *ptr, void **prevptr, set *q) { unsigned int hash; int pos; set_elem *ll; set_elem *w; + if (q == NULL) + q = create_set(); + hash = fnv1a32(name); pos = hash % _SET_HASH_SIZE; + if (prevptr != NULL) + *prevptr = NULL; if (q->buckets[pos] == NULL) { q->buckets[pos] = ll = xmalloc(sizeof(*ll)); ll->next = NULL; @@ -132,8 +137,11 @@ add_set_value(const char *name, void *ptr, set *q) } else { ll = NULL; for (w = q->buckets[pos]; w != NULL; ll = w, w = w->next) { - if (w->hash == hash && strcmp(w->name, name) == 0) - return w->val; + if (w->hash == hash && strcmp(w->name, name) == 0) { + if (prevptr != NULL) + *prevptr = w->val; + return q; + } } if (w == NULL) { ll = ll->next = xmalloc(sizeof(*ll)); @@ -145,7 +153,7 @@ add_set_value(const char *name, void *ptr, set *q) } q->len++; - return NULL; + return q; } /* returns whether name is in set, and if so, the set-internal key @@ -158,6 +166,9 @@ contains_set(const char *name, set *q) set_elem *w; const char *found; + if (q == NULL) + return NULL; + hash = fnv1a32(name); pos = hash % _SET_HASH_SIZE; @@ -183,6 +194,9 @@ get_set(const char *name, set *q) int pos; set_elem *w; + if (q == NULL) + return NULL; + hash = fnv1a32(name); pos = hash % _SET_HASH_SIZE; @@ -211,6 +225,12 @@ del_set(const char *s, set *q, bool *removed) void *ret; bool rmd; + if (q == NULL) { + if (removed != NULL) + *removed = false; + return NULL; + } + hash = fnv1a32(s); pos = hash % _SET_HASH_SIZE; @@ -252,8 +272,8 @@ list_set(set *q, char ***l) set_elem *w; char **ret; - ret = *l = xmalloc(sizeof(char *) * (q->len + 1)); - for (i = 0; i < _SET_HASH_SIZE; i++) { + ret = *l = xmalloc(sizeof(char *) * (cnt_set(q) + 1)); + for (i = 0; q != NULL && i < _SET_HASH_SIZE; i++) { for (w = q->buckets[i]; w != NULL; w = w->next) { *ret = w->name; ret++; @@ -292,6 +312,11 @@ values_set(set *q, array_t *ret) array_t blank = array_init_decl; *ret = blank; + + /* allow using empty set */ + if (q == NULL) + return 0; + for (i = 0; i < _SET_HASH_SIZE; i++) { for (w = q->buckets[i]; w != NULL; w = w->next) xarraypush_ptr(ret, w->val); @@ -314,6 +339,9 @@ clear_set(set *q) set_elem *w; set_elem *e; + if (q == NULL) + return; + for (i = 0; i < _SET_HASH_SIZE; i++) { for (w = q->buckets[i]; w != NULL; w = e) { e = w->next; @@ -329,6 +357,9 @@ clear_set(set *q) void free_set(set *q) { + if (q == NULL) + return; + clear_set(q); free(q); } @@ -1,5 +1,5 @@ /* - * Copyright 2005-2019 Gentoo Foundation + * Copyright 2005-2023 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 */ @@ -30,7 +30,7 @@ struct set_t { set *create_set(void); set *add_set(const char *name, set *q); set *add_set_unique(const char *name, set *q, bool *unique); -void *add_set_value(const char *name, void *ptr, set *q); +set *add_set_value(const char *name, void *ptr, void **prevptr, set *q); const char *contains_set(const char *name, set *q); void *get_set(const char *name, set *q); void *del_set(const char *s, set *q, bool *removed); diff --git a/libq/tree.c b/libq/tree.c index 76190ed..a05a86e 100644 --- a/libq/tree.c +++ b/libq/tree.c @@ -297,7 +297,8 @@ tree_open_cat(tree_ctx *ctx, const char *name) cat_ctx->pkg_cnt = 0; if (ctx->cache.categories != NULL) { - add_set_value(name, cat_ctx, ctx->cache.categories); + ctx->cache.categories = + add_set_value(name, cat_ctx, NULL, ctx->cache.categories); /* ensure name doesn't expire after this instantiation is closed */ cat_ctx->name = contains_set(name, ctx->cache.categories); } @@ -1708,7 +1709,7 @@ tree_match_atom_cache_populate_cb(tree_pkg_ctx *ctx, void *priv) cat_ctx = get_set(atom->CATEGORY, cache); if (cat_ctx == NULL) { cat_ctx = tree_open_cat(tctx, "."); - add_set_value(atom->CATEGORY, cat_ctx, cache); + cache = add_set_value(atom->CATEGORY, cat_ctx, NULL, cache); /* get a pointer from the set */ cat_ctx->name = contains_set(atom->CATEGORY, cache); } @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 Gentoo Foundation + * Copyright 2005-2023 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2008 Ned Ludd - <solar@gentoo.org> @@ -581,10 +581,12 @@ read_portage_file(const char *file, enum portage_file_type type, void *data) if ((p = del_set(buf + 1, masks, NULL)) != NULL) free(p); } else { + void *e; snprintf(npath, sizeof(npath), "%s:%zu:%zu-%zu", file, line, cbeg, cend); p = xstrdup(npath); - if (add_set_value(buf, p, masks) != NULL) + masks = add_set_value(buf, p, &e, masks); + if (e != NULL) free(p); } } @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 Gentoo Foundation + * Copyright 2005-2023 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2006 Thomas A. Cort - <tcort@gentoo.org> @@ -913,8 +913,8 @@ int qkeyword_main(int argc, char **argv) continue; bucket = xzalloc(sizeof(array_t)); xarraypush_ptr(bucket, atom); - ebuck = add_set_value(atom_format("%[CAT]%[PN]", atom), - bucket, pmasks); + pmasks = add_set_value(atom_format("%[CAT]%[PN]", atom), + bucket, (void **)&ebuck, pmasks); if (ebuck != NULL) { xarraypush_ptr(ebuck, atom); xarrayfree_int(bucket); @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 Gentoo Foundation + * Copyright 2005-2023 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2010 Ned Ludd - <solar@gentoo.org> @@ -523,7 +523,7 @@ static int do_emerge_log( last_merge = tstart_emerge; } - atomw = add_set_value(afmt, atom, atomset); + atomset = add_set_value(afmt, atom, (void **)&atomw, atomset); if (atomw != NULL) atom_implode(atom); } @@ -807,7 +807,9 @@ static int do_emerge_log( pkgw->atom->CATEGORY, pkgw->atom->PN); } - pkg = add_set_value(afmt, pkgw, merge_averages); + merge_averages = + add_set_value(afmt, pkgw, + (void **)&pkg, merge_averages); if (pkg != NULL) { pkg->cnt++; pkg->time += elapsed; @@ -952,7 +954,9 @@ static int do_emerge_log( pkgw->atom->CATEGORY, pkgw->atom->PN); } - pkg = add_set_value(afmt, pkgw, unmerge_averages); + unmerge_averages = + add_set_value(afmt, pkgw, + (void **)&pkg, unmerge_averages); if (pkg != NULL) { pkg->cnt++; pkg->time += elapsed; |