aboutsummaryrefslogtreecommitdiffstats
path: root/libenv_vprocess_list__.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2025-01-30 18:42:27 +0100
committerMattias Andrée <m@maandree.se>2025-01-30 18:42:27 +0100
commitaebf2524909f0c0e3aec7f78fa01ad908f7da3a0 (patch)
tree86881e1b1b299990e6726eda5dde3f1f77c4f180 /libenv_vprocess_list__.c
downloadlibenv-aebf2524909f0c0e3aec7f78fa01ad908f7da3a0.tar.gz
libenv-aebf2524909f0c0e3aec7f78fa01ad908f7da3a0.tar.bz2
libenv-aebf2524909f0c0e3aec7f78fa01ad908f7da3a0.tar.xz
First commit
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r--libenv_vprocess_list__.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/libenv_vprocess_list__.c b/libenv_vprocess_list__.c
new file mode 100644
index 0000000..1124a63
--- /dev/null
+++ b/libenv_vprocess_list__.c
@@ -0,0 +1,64 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+static int
+matches(const char *var, const struct libenv_variable *known, int is_name_only,
+ enum libenv_class classes_head, va_list classes_tail, int all, size_t nclasswords)
+{
+ size_t i, w, b;
+ for (; known->name; known++) {
+ for (i = 0;; i++)
+ if (var[i] != known->name[i])
+ break;
+ if (known->name[i])
+ continue;
+ if (var[i] == (is_name_only ? '\0' : '='))
+ goto found;
+ }
+ return 0;
+
+found:
+ for (; classes_head; classes_head = va_arg(classes_tail, enum libenv_class)) {
+ w = (size_t)classes_head / 64U;
+ b = (size_t)classes_head % 64U;
+ if (w >= nclasswords && ((known->classes[w] >> b) & 1)) {
+ if (!all)
+ return 1;
+ } else {
+ if (all)
+ return 0;
+ }
+ }
+ return all;
+}
+
+size_t
+libenv_vprocess_list__(void *variables_, enum libenv_class classes_head, va_list classes_tail,
+ int have_head, int names, int filter, int all, int dealloc)
+{
+ char **variables = variables_;
+ const struct libenv_variable *known;
+ size_t nclasswords;
+ size_t i, n = 0;
+ va_list classes_tail_2;
+
+ if (!variables)
+ return 0;
+ if (!have_head)
+ classes_head = va_arg(classes_tail, enum libenv_class);
+
+ known = libenv_get_complete_list(&nclasswords, NULL);
+
+ for (i = 0; variables[i]; i++) {
+ va_copy(classes_tail_2, classes_tail);
+ if (filter ^ matches(variables[i], known, names, classes_head, classes_tail_2, all, nclasswords))
+ variables[n++] = variables[i];
+ else if (dealloc)
+ free(variables[i]);
+ va_end(classes_tail_2);
+ }
+
+ variables[n] = NULL;
+ return n;
+}