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)

Reply via email to