commit: f6892b3ca6d1c8817bc15dacc87a3090770b9689
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Feb 8 10:15:08 2026 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Feb 8 10:15:08 2026 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=f6892b3c
libq/set: add set_add_from_string utility/helper
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
libq/set.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
libq/set.h | 9 +++++----
2 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/libq/set.c b/libq/set.c
index 1146ae12..3832bcf5 100644
--- a/libq/set.c
+++ b/libq/set.c
@@ -13,6 +13,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <xalloc.h>
#include "set.h"
@@ -142,6 +143,51 @@ set_t *set_add_unique
return q;
}
+/* splits buf on whitespace and adds the resulting tokens into the given
+ * set, ignoring any duplicates
+ * NOTE: if the input has keys > _Q_PATH_MAX this function misbehaves
+ * and doesn't function properly (currently there's no reasonable
+ * need for this though) */
+set_t *set_add_from_string
+(
+ set_t *s,
+ const char *buf
+)
+{
+ char key[_Q_PATH_MAX];
+ const char *p;
+ size_t len;
+
+ if (buf == NULL)
+ return s;
+
+ if (s == NULL)
+ s = set_new();
+
+ for (p = buf, len = 0; len < sizeof(key) - 1; p++)
+ {
+ if (*p == '\0' ||
+ isspace((int)*p))
+ {
+ if (len > 0)
+ {
+ key[len] = '\0';
+ set_add_unique(s, key, NULL);
+ }
+
+ len = 0;
+ if (*p == '\0')
+ break;
+ else
+ continue;
+ }
+
+ key[len++] = *p;
+ }
+
+ return s;
+}
+
/* returns whether name is in set, and if so, the set-internal key
* representation (an internal copy of name made during addition) */
const char *set_get_key
diff --git a/libq/set.h b/libq/set.h
index 5ba638fe..a2f0a8ef 100644
--- a/libq/set.h
+++ b/libq/set.h
@@ -11,16 +11,17 @@
#include "array.h"
-/* 2026 forward API */
+/* 2026 set API */
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);
+set_t *set_add_from_string(set_t *s, const char *buf);
#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) hash_keys(S)
+#define set_keys(S) hash_keys((hash_t *)S)
#endif
size_t set_size(set_t *s);
void set_clear(set_t *s);
@@ -51,8 +52,8 @@ typedef struct set_ set;
#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);
+size_t array_set(set_t *q, array *ret); /* hash_keys() */
+size_t values_set(set_t *q, array *ret); /* hash_values() */
#define cnt_set(S) set_size(S)
#define clear_set(S) set_clear(S)
#define free_set(S) set_free(S)