/* 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; }