diff options
author | Mattias Andrée <m@maandree.se> | 2025-01-30 18:42:27 +0100 |
---|---|---|
committer | Mattias Andrée <m@maandree.se> | 2025-01-30 18:42:27 +0100 |
commit | aebf2524909f0c0e3aec7f78fa01ad908f7da3a0 (patch) | |
tree | 86881e1b1b299990e6726eda5dde3f1f77c4f180 /libenv_vprocess_list__.c | |
download | libenv-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__.c | 64 |
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; +} |