mirror of
https://github.com/AuxXxilium/eudev.git
synced 2024-12-24 02:20:45 +07:00
strv: introduce strv_env_merge() to merge environment arrays
This commit is contained in:
parent
8d49745c2b
commit
2e6c9e6bde
77
strv.c
77
strv.c
@ -23,6 +23,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
@ -301,6 +302,7 @@ char **strv_append(char **l, const char *s) {
|
|||||||
for (k = r; *l; k++, l++)
|
for (k = r; *l; k++, l++)
|
||||||
if (!(*k = strdup(*l)))
|
if (!(*k = strdup(*l)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!(*(k++) = strdup(s)))
|
if (!(*(k++) = strdup(s)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -349,3 +351,78 @@ char **strv_remove(char **l, const char *s) {
|
|||||||
*t = NULL;
|
*t = NULL;
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int env_append(char **r, char ***k, char **a) {
|
||||||
|
assert(r);
|
||||||
|
assert(k);
|
||||||
|
assert(a);
|
||||||
|
|
||||||
|
/* Add the entries of a to *k unless they already exist in *r
|
||||||
|
* in which case they are overriden instead. This assumes
|
||||||
|
* there is enough space in the r */
|
||||||
|
|
||||||
|
for (; *a; a++) {
|
||||||
|
char **j;
|
||||||
|
size_t n = strcspn(*a, "=") + 1;
|
||||||
|
|
||||||
|
for (j = r; j < *k; j++)
|
||||||
|
if (strncmp(*j, *a, n) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (j >= *k)
|
||||||
|
(*k)++;
|
||||||
|
else
|
||||||
|
free(*j);
|
||||||
|
|
||||||
|
if (!(*j = strdup(*a)))
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **strv_env_merge(char **x, ...) {
|
||||||
|
size_t n = 0;
|
||||||
|
char **l, **k, **r;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
/* Merges an arbitrary number of environment sets */
|
||||||
|
|
||||||
|
if (x) {
|
||||||
|
n += strv_length(x);
|
||||||
|
|
||||||
|
va_start(ap, x);
|
||||||
|
while ((l = va_arg(ap, char**)))
|
||||||
|
n += strv_length(l);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!(r = new(char*, n+1)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
k = r;
|
||||||
|
|
||||||
|
if (x) {
|
||||||
|
if (env_append(r, &k, x) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
va_start(ap, x);
|
||||||
|
while ((l = va_arg(ap, char**)))
|
||||||
|
if (env_append(r, &k, l) < 0)
|
||||||
|
goto fail;
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
*k = NULL;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
for (k--; k >= r; k--)
|
||||||
|
free(*k);
|
||||||
|
|
||||||
|
free(r);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
2
strv.h
2
strv.h
@ -49,6 +49,8 @@ char **strv_split_quoted(const char *s);
|
|||||||
|
|
||||||
char *strv_join(char **l, const char *separator);
|
char *strv_join(char **l, const char *separator);
|
||||||
|
|
||||||
|
char **strv_env_merge(char **x, ...) _sentinel;
|
||||||
|
|
||||||
#define STRV_FOREACH(s, l) \
|
#define STRV_FOREACH(s, l) \
|
||||||
for ((s) = (l); (s) && *(s); (s)++)
|
for ((s) = (l); (s) && *(s); (s)++)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user