commit: 9624a6dabc7bd131db0412915587937c24aa376a
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sat Feb 7 20:57:09 2026 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sat Feb 7 20:57:09 2026 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=9624a6da
libq/set: reflow for 2026 codestyle, change API to 2026 one too
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
libq/set.c | 712 ++++++++++++++++++++++++++++++++++++-------------------------
libq/set.h | 91 ++++----
2 files changed, 462 insertions(+), 341 deletions(-)
diff --git a/libq/set.c b/libq/set.c
index a6128392..1146ae12 100644
--- a/libq/set.c
+++ b/libq/set.c
@@ -18,197 +18,164 @@
#include "set.h"
#include "array.h"
+typedef struct setelem_ set_elem_t;
+struct setelem_ {
+ char *name;
+ unsigned int hash; /* FNV1a32 */
+ void *val;
+ set_elem_t *next;
+};
+
+#define _SET_HASH_SIZE 128
+struct set_ {
+ set_elem_t *buckets[_SET_HASH_SIZE];
+ size_t len;
+};
+
static unsigned int
fnv1a32(const char *s)
{
- unsigned int ret = 2166136261UL;
- for (; *s != '\0'; s++)
- ret = (ret ^ (unsigned int)*s) * 16777619;
- return ret;
+ unsigned int ret = 2166136261UL;
+ for (; *s != '\0'; s++)
+ ret = (ret ^ (unsigned int)*s) * 16777619;
+ return ret;
}
/* create a set */
-set *
-create_set(void)
+set_t *set_new
+(
+ void
+)
{
- return xzalloc(sizeof(set));
+ return xzalloc(sizeof(set_t));
}
/* add elem to a set (unpure: could add duplicates, basically hash) */
-set *
-add_set(const char *name, set *q)
+set_t *set_add
+(
+ set_t *s,
+ const char *key
+)
{
- int pos;
- set_elem *ll = xmalloc(sizeof(*ll));
- set_elem *w;
-
- if (q == NULL)
- q = create_set();
-
- ll->next = NULL;
- ll->name = xstrdup(name);
- ll->hash = fnv1a32(ll->name);
- ll->val = NULL;
-
- pos = ll->hash % _SET_HASH_SIZE;
- if (q->buckets[pos] == NULL) {
- q->buckets[pos] = ll;
- } else {
- for (w = q->buckets[pos]; w->next != NULL; w = w->next)
- ;
- w->next = ll;
- }
-
- q->len++;
- return q;
+ set_elem_t *ll = xzalloc(sizeof(*ll));
+ set_elem_t *w;
+ int pos;
+
+ if (s == NULL)
+ s = set_new();
+
+ ll->name = xstrdup(key);
+ ll->hash = fnv1a32(ll->name);
+
+ pos = ll->hash % _SET_HASH_SIZE;
+ if (s->buckets[pos] == NULL)
+ {
+ s->buckets[pos] = ll;
+ }
+ else
+ {
+ for (w = s->buckets[pos]; w->next != NULL; w = w->next)
+ ;
+ w->next = ll;
+ }
+
+ s->len++;
+ return s;
}
-/* add elem to set if it doesn't exist yet (pure definition of hash) */
-set *
-add_set_unique(const char *name, set *q, bool *unique)
-{
- unsigned int hash;
- int pos;
- set_elem *ll;
- set_elem *w;
- bool uniq = false;
-
- if (q == NULL)
- q = create_set();
-
- hash = fnv1a32(name);
- pos = hash % _SET_HASH_SIZE;
-
- if (q->buckets[pos] == NULL) {
- q->buckets[pos] = ll = xmalloc(sizeof(*ll));
- ll->next = NULL;
- ll->name = xstrdup(name);
- ll->hash = hash;
- ll->val = NULL;
- uniq = true;
- } else {
- ll = NULL;
- for (w = q->buckets[pos]; w != NULL; ll = w, w = w->next) {
- if (w->hash == hash && strcmp(w->name, name) == 0) {
- uniq = false;
- break;
- }
- }
- if (w == NULL) {
- ll = ll->next = xmalloc(sizeof(*ll));
- ll->next = NULL;
- ll->name = xstrdup(name);
- ll->hash = hash;
- ll->val = NULL;
- uniq = true;
- }
- }
-
- if (uniq)
- q->len++;
- if (unique)
- *unique = uniq;
- return q;
-}
-
-/* add ptr to set with name as key, return existing value when key
- * already exists or NULL otherwise */
-set *
-add_set_value(const char *name, void *ptr, void **prevptr, set *q)
+/* add elem to set if it doesn't exist yet (pure definition of set) */
+set_t *set_add_unique
+(
+ set_t *q,
+ const char *name,
+ bool *unique
+)
{
- 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;
- ll->name = xstrdup(name);
- ll->hash = hash;
- ll->val = ptr;
- } else {
- ll = NULL;
- for (w = q->buckets[pos]; w != NULL; ll = w, w = w->next) {
- 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));
- ll->next = NULL;
- ll->name = xstrdup(name);
- ll->hash = hash;
- ll->val = ptr;
- }
- }
-
- q->len++;
- return q;
+ set_elem_t *ll;
+ set_elem_t *w;
+ unsigned int hash;
+ int pos;
+ bool uniq = false;
+
+ if (q == NULL)
+ q = set_new();
+
+ hash = fnv1a32(name);
+ pos = hash % _SET_HASH_SIZE;
+
+ if (q->buckets[pos] == NULL)
+ {
+ q->buckets[pos] = ll = xzalloc(sizeof(*ll));
+
+ ll->name = xstrdup(name);
+ ll->hash = hash;
+
+ uniq = true;
+ }
+ else
+ {
+ ll = NULL;
+ for (w = q->buckets[pos]; w != NULL; ll = w, w = w->next)
+ {
+ if (w->hash == hash &&
+ strcmp(w->name, name) == 0)
+ {
+ uniq = false;
+ break;
+ }
+ }
+ if (w == NULL)
+ {
+ ll = ll->next = xzalloc(sizeof(*ll));
+
+ ll->name = xstrdup(name);
+ ll->hash = hash;
+
+ uniq = true;
+ }
+ }
+
+ if (uniq)
+ q->len++;
+ if (unique)
+ *unique = uniq;
+ return q;
}
/* returns whether name is in set, and if so, the set-internal key
* representation (an internal copy of name made during addition) */
-const char *
-contains_set(const char *name, set *q)
+const char *set_get_key
+(
+ set_t *q,
+ const char *name
+)
{
- unsigned int hash;
- int pos;
- set_elem *w;
- const char *found;
-
- if (q == NULL)
- return NULL;
-
- hash = fnv1a32(name);
- pos = hash % _SET_HASH_SIZE;
-
- found = NULL;
- if (q->buckets[pos] != NULL) {
- for (w = q->buckets[pos]; w != NULL; w = w->next) {
- if (w->hash == hash && strcmp(w->name, name) == 0) {
- found = w->name;
- break;
- }
- }
- }
-
- return found;
-}
-
-/* returns the value for name, or NULL if not found (cannot
- * differentiate between value NULL and unset) */
-void *
-get_set(const char *name, set *q)
-{
- unsigned int hash;
- int pos;
- set_elem *w;
-
- if (q == NULL)
- return NULL;
-
- hash = fnv1a32(name);
- pos = hash % _SET_HASH_SIZE;
-
- if (q->buckets[pos] != NULL) {
- for (w = q->buckets[pos]; w != NULL; w = w->next) {
- if (w->hash == hash && strcmp(w->name, name) == 0)
- return w->val;
- }
- }
-
- return NULL;
+ set_elem_t *w;
+ const char *found;
+ unsigned int hash;
+ int pos;
+
+ if (q == NULL)
+ return NULL;
+
+ hash = fnv1a32(name);
+ pos = hash % _SET_HASH_SIZE;
+
+ found = NULL;
+ if (q->buckets[pos] != NULL)
+ {
+ for (w = q->buckets[pos]; w != NULL; w = w->next)
+ {
+ if (w->hash == hash &&
+ strcmp(w->name, name) == 0)
+ {
+ found = w->name;
+ break;
+ }
+ }
+ }
+
+ return found;
}
/* remove elem from a set. matches ->name and frees name,item, returns
@@ -216,159 +183,324 @@ get_set(const char *name, set *q)
* note that when val isn't set, NULL is returned, so the caller should
* use the removed argument to determine if something was removed from
* the set. */
-void *
-del_set(const char *s, set *q, bool *removed)
+void *set_delete
+(
+ set_t *q,
+ const char *s,
+ bool *removed
+)
{
- unsigned int hash;
- int pos;
- set_elem *ll;
- set_elem *w;
- void *ret;
- bool rmd;
-
- if (q == NULL) {
- if (removed != NULL)
- *removed = false;
- return NULL;
- }
-
- hash = fnv1a32(s);
- pos = hash % _SET_HASH_SIZE;
-
- ret = NULL;
- rmd = false;
- if (q->buckets[pos] != NULL) {
- ll = NULL;
- for (w = q->buckets[pos]; w != NULL; ll = w, w = w->next) {
- if (w->hash == hash && strcmp(w->name, s) == 0) {
- if (ll == NULL) {
- q->buckets[pos] = w->next;
- } else {
- ll->next = w->next;
- }
- ret = w->val;
- free(w->name);
- free(w);
- rmd = true;
- break;
- }
- }
- }
-
- if (rmd)
- q->len--;
- if (removed != NULL)
- *removed = rmd;
- return ret;
+ set_elem_t *ll;
+ set_elem_t *w;
+ void *ret;
+ unsigned int hash;
+ int pos;
+ bool rmd;
+
+ if (q == NULL)
+ {
+ if (removed != NULL)
+ *removed = false;
+ return NULL;
+ }
+
+ hash = fnv1a32(s);
+ pos = hash % _SET_HASH_SIZE;
+
+ ret = NULL;
+ rmd = false;
+ if (q->buckets[pos] != NULL)
+ {
+ ll = NULL;
+ for (w = q->buckets[pos]; w != NULL; ll = w, w = w->next)
+ {
+ if (w->hash == hash &&
+ strcmp(w->name, s) == 0)
+ {
+ if (ll == NULL)
+ {
+ q->buckets[pos] = w->next;
+ }
+ else
+ {
+ ll->next = w->next;
+ }
+ ret = w->val;
+ free(w->name);
+ free(w);
+ rmd = true;
+ break;
+ }
+ }
+ }
+
+ if (rmd)
+ q->len--;
+ if (removed != NULL)
+ *removed = rmd;
+ return ret;
}
-/* return the contents of a set as an array of strings
+/* DEPRECATED -- use set_keys()/hash_keys()
+ * return the contents of a set as an array of strings
* the length of the list is returned, and the array is terminated with
* a NULL (not included in returned length)
* the caller should free l, but not the strings within */
-size_t
-list_set(set *q, char ***l)
+size_t list_set
+(
+ set_t *q,
+ char ***l
+)
{
- int i;
- set_elem *w;
- char **ret;
-
- 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++;
- }
- }
- *ret = NULL;
- return q->len;
+ set_elem_t *w;
+ char **ret;
+ int 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++;
+ }
+ }
+ *ret = NULL;
+ return q->len;
}
-size_t
-array_set(set *q, array *ret)
+/* DEPRECATED -- use set_keys()/hash_keys() */
+size_t array_set
+(
+ set_t *q,
+ array *ret
+)
{
- int i;
- set_elem *w;
+ set_elem_t *w;
+ int i;
- /* allow using empty set */
- if (q == NULL)
- return 0;
+ /* 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)
- array_append(ret, w->name);
- }
+ for (i = 0; i < _SET_HASH_SIZE; i++)
+ {
+ for (w = q->buckets[i]; w != NULL; w = w->next)
+ array_append(ret, w->name);
+ }
- return q->len;
+ return q->len;
}
-size_t
-values_set(set *q, array *ret)
+/* DEPRECATED -- use hash_values() */
+size_t values_set
+(
+ set_t *q,
+ array *ret
+)
{
- int i;
- set_elem *w;
+ set_elem_t *w;
+ int i;
- /* allow using empty set */
- if (q == NULL)
- return 0;
+ /* 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)
- array_append(ret, w->val);
- }
+ for (i = 0; i < _SET_HASH_SIZE; i++)
+ {
+ for (w = q->buckets[i]; w != NULL; w = w->next)
+ array_append(ret, w->val);
+ }
- return q->len;
+ return q->len;
}
-size_t
-cnt_set(set *q)
+size_t set_size
+(
+ set_t *q
+)
{
- return q == NULL ? 0 : q->len;
+ return q == NULL ? 0 : q->len;
}
/* clear out a set */
-void
-clear_set(set *q)
+void clear_set
+(
+ set_t *q
+)
{
- int i;
- 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;
- free(w->name);
- free(w);
- }
- q->buckets[i] = NULL;
- }
- q->len = 0;
+ set_elem_t *w;
+ set_elem_t *e;
+ int i;
+
+ if (q == NULL)
+ return;
+
+ for (i = 0; i < _SET_HASH_SIZE; i++)
+ {
+ for (w = q->buckets[i]; w != NULL; w = e)
+ {
+ e = w->next;
+ free(w->name);
+ free(w);
+ }
+ q->buckets[i] = NULL;
+ }
+ q->len = 0;
}
/* clear and free a set */
-void
-free_set(set *q)
+void set_free(set_t *q)
{
- if (q == NULL)
- return;
+ if (q == NULL)
+ return;
- clear_set(q);
- free(q);
+ clear_set(q);
+ free(q);
}
#ifdef EBUG
static void
-print_set(const set *q)
+set_print(const set_t *q)
{
- set_elem *w;
- int i;
-
- for (i = 0; i < _SET_HASH_SIZE; i++) {
- for (w = q->buckets[i]; w != NULL; w = w->next)
- puts(w->name);
- }
+ set_elem_t *w;
+ int i;
+
+ for (i = 0; i < _SET_HASH_SIZE; i++)
+ {
+ for (w = q->buckets[i]; w != NULL; w = w->next)
+ puts(w->name);
+ }
}
#endif
+
+hash_t *hash_new
+(
+ void
+)
+{
+ return xzalloc(sizeof(hash_t));
+}
+
+/* add val to hash under key, return existing value when key
+ * already exists or NULL otherwise */
+hash_t *hash_add
+(
+ hash_t *q,
+ const char *key,
+ void *val,
+ void **prevval
+)
+{
+ set_elem_t *ll;
+ set_elem_t *w;
+ unsigned int hash;
+ int pos;
+
+ if (q == NULL)
+ q = hash_new();
+
+ hash = fnv1a32(key);
+ pos = hash % _SET_HASH_SIZE;
+
+ if (prevval != NULL)
+ *prevval = NULL;
+ if (q->buckets[pos] == NULL)
+ {
+ q->buckets[pos] = ll = xzalloc(sizeof(*ll));
+ ll->name = xstrdup(key);
+ ll->hash = hash;
+ ll->val = val;
+ }
+ else
+ {
+ ll = NULL;
+ for (w = q->buckets[pos]; w != NULL; ll = w, w = w->next)
+ {
+ if (w->hash == hash &&
+ strcmp(w->name, key) == 0)
+ {
+ if (prevval != NULL)
+ *prevval = w->val;
+ return q;
+ }
+ }
+ if (w == NULL)
+ {
+ ll = ll->next = xzalloc(sizeof(*ll));
+ ll->name = xstrdup(key);
+ ll->hash = hash;
+ ll->val = val;
+ }
+ }
+
+ q->len++;
+ return q;
+}
+
+/* returns the value for key, or NULL if not found (cannot
+ * differentiate between value NULL and unset) */
+void *hash_get
+(
+ hash_t *q,
+ const char *key
+)
+{
+ set_elem_t *w;
+ unsigned int hash;
+ int pos;
+
+ if (q == NULL)
+ return NULL;
+
+ hash = fnv1a32(key);
+ pos = hash % _SET_HASH_SIZE;
+
+ if (q->buckets[pos] != NULL)
+ {
+ for (w = q->buckets[pos]; w != NULL; w = w->next)
+ {
+ if (w->hash == hash &&
+ strcmp(w->name, key) == 0)
+ return w->val;
+ }
+ }
+
+ return NULL;
+}
+
+void *hash_delete_chk
+(
+ hash_t *q,
+ const char *key,
+ bool *removed
+)
+{
+ return set_delete((set_t *)q, key, removed);
+}
+
+size_t hash_size
+(
+ hash_t *h
+)
+{
+ return h->len;
+}
+
+void hash_clear
+(
+ hash_t *h
+)
+{
+ set_clear((set_t *)h);
+}
+
+void hash_free
+(
+ hash_t *h
+)
+{
+ set_free((set_t *)h);
+}
+
+/* vim: set ts=2 sw=2 expandtab cino+=\:0 foldmethod=marker: */
diff --git a/libq/set.h b/libq/set.h
index dc3c5ac7..5ba638fe 100644
--- a/libq/set.h
+++ b/libq/set.h
@@ -11,64 +11,53 @@
#include "array.h"
-typedef struct setelem_t set_elem;
-typedef struct set_t set;
-
-struct setelem_t {
- char *name;
- unsigned int hash; /* FNV1a32 */
- void *val;
- set_elem *next;
-};
-
-#define _SET_HASH_SIZE 128
-struct set_t {
- set_elem *buckets[_SET_HASH_SIZE];
- size_t len;
-};
-
-set *create_set(void);
-set *add_set(const char *name, set *q);
-set *add_set_unique(const char *name, set *q, bool *unique);
-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);
-size_t list_set(set *q, char ***l);
-size_t array_set(set *q, array *ret);
-size_t values_set(set *q, array *ret);
-size_t cnt_set(set *q);
-void free_set(set *q);
-void clear_set(set *q);
-
/* 2026 forward API */
-typedef struct set_t set_t;
-#define set_new() create_set()
-#define set_add(S,K) add_set(K,S)
-#define set_add_unique(S,K,U) add_set_unique(K,S,U)
-#define set_contains(S,K) (contains_set(K,S) == NULL ? false : true)
-#define set_get_key(S,K) contains_set(K,S)
-#define set_delete(S,K) del_set(K,S,NULL)
+typedef struct set_ set_t;
+set_t *set_new(void);
+set_t *set_add(set_t *s, const char *key);
+set_t *set_add_unique(set_t *s, const char *key, bool *unique);
+#define set_contains(S,K) (set_get_key(S,K) == NULL ? false : true)
+const char *set_get_key(set_t *s, const char *key);
+void *set_delete(set_t *s, const char *key, bool *removed);
#if 0
-#define set_keys(S) TODO
+#define set_keys(S) hash_keys(S)
#endif
-#define set_size(S) cnt_set(S)
-#define set_clear(S) clear_set(S)
-#define set_free(S) free_set(S)
-
-typedef struct set_t hash_t;
-#define hash_new() create_set()
-#define hash_add(S,K,V,P) add_set_value(K,V,P,S)
-#define hash_get(S,K) get_set(K,S)
-#define hash_delete(S,K) del_set(K,S,NULL)
-#define hash_delete_chk(S,K,R) del_set(K,S,R)
+size_t set_size(set_t *s);
+void set_clear(set_t *s);
+void set_free(set_t *s);
+
+/* hash/dict interface */
+typedef struct set_ hash_t;
+hash_t *hash_new(void);
+hash_t *hash_add(hash_t *h, const char *key, void *val, void **prevval);
+void *hash_get(hash_t *h, const char *key);
+#define hash_delete(S,K) hash_delete_chk(S,K,NULL)
+void *hash_delete_chk(hash_t *h, const char *key, bool *removed);
#if 0
#define hash_keys(S) TODO
#define hash_values(S) TODO
#endif
-#define hash_size(S) cnt_set(S)
-#define hash_clear(S) clear_set(S)
-#define hash_free(S) free_set(S)
+size_t hash_size(hash_t *h);
+void hash_clear(hash_t *h);
+void hash_free(hash_t *h);
+
+/* backwards compat aliases and funcs */
+typedef struct set_ set;
+#define create_set(X) set_new(X)
+#define add_set(K,S) set_add(S,K)
+#define add_set_unique(K,S,U) set_add_unique(S,K,U)
+#define add_set_value(K,V,P,S) hash_add((hash_t *)S,K,V,P)
+#define contains_set(K,S) set_get_key(S,K)
+#define get_set(K,S) hash_get((hash_t *)S,K)
+#define del_set(K,S,R) set_delete(S,K,R)
+size_t list_set(set_t *q, char ***l);
+size_t array_set(set_t *q, array *ret);
+size_t values_set(set_t *q, array *ret);
+#define cnt_set(S) set_size(S)
+#define clear_set(S) set_clear(S)
+#define free_set(S) set_free(S)
#endif
+
+/* vim: set ts=2 sw=2 expandtab cino+=\:0 foldmethod=marker: */