shared: move replace_env* from util to env-util
This commit is contained in:
@@ -448,3 +448,147 @@ char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const cha
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
char *replace_env(const char *format, char **env) {
|
||||
enum {
|
||||
WORD,
|
||||
CURLY,
|
||||
VARIABLE
|
||||
} state = WORD;
|
||||
|
||||
const char *e, *word = format;
|
||||
char *r = NULL, *k;
|
||||
|
||||
assert(format);
|
||||
|
||||
for (e = format; *e; e ++) {
|
||||
|
||||
switch (state) {
|
||||
|
||||
case WORD:
|
||||
if (*e == '$')
|
||||
state = CURLY;
|
||||
break;
|
||||
|
||||
case CURLY:
|
||||
if (*e == '{') {
|
||||
k = strnappend(r, word, e-word-1);
|
||||
if (!k)
|
||||
goto fail;
|
||||
|
||||
free(r);
|
||||
r = k;
|
||||
|
||||
word = e-1;
|
||||
state = VARIABLE;
|
||||
|
||||
} else if (*e == '$') {
|
||||
k = strnappend(r, word, e-word);
|
||||
if (!k)
|
||||
goto fail;
|
||||
|
||||
free(r);
|
||||
r = k;
|
||||
|
||||
word = e+1;
|
||||
state = WORD;
|
||||
} else
|
||||
state = WORD;
|
||||
break;
|
||||
|
||||
case VARIABLE:
|
||||
if (*e == '}') {
|
||||
const char *t;
|
||||
|
||||
t = strempty(strv_env_get_n(env, word+2, e-word-2));
|
||||
|
||||
k = strappend(r, t);
|
||||
if (!k)
|
||||
goto fail;
|
||||
|
||||
free(r);
|
||||
r = k;
|
||||
|
||||
word = e+1;
|
||||
state = WORD;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
k = strnappend(r, word, e-word);
|
||||
if (!k)
|
||||
goto fail;
|
||||
|
||||
free(r);
|
||||
return k;
|
||||
|
||||
fail:
|
||||
free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **replace_env_argv(char **argv, char **env) {
|
||||
char **ret, **i;
|
||||
unsigned k = 0, l = 0;
|
||||
|
||||
l = strv_length(argv);
|
||||
|
||||
ret = new(char*, l+1);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
STRV_FOREACH(i, argv) {
|
||||
|
||||
/* If $FOO appears as single word, replace it by the split up variable */
|
||||
if ((*i)[0] == '$' && (*i)[1] != '{') {
|
||||
char *e;
|
||||
char **w, **m = NULL;
|
||||
unsigned q;
|
||||
|
||||
e = strv_env_get(env, *i+1);
|
||||
if (e) {
|
||||
int r;
|
||||
|
||||
r = strv_split_quoted(&m, e, UNQUOTE_RELAX);
|
||||
if (r < 0) {
|
||||
ret[k] = NULL;
|
||||
strv_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
m = NULL;
|
||||
|
||||
q = strv_length(m);
|
||||
l = l + q - 1;
|
||||
|
||||
w = realloc(ret, sizeof(char*) * (l+1));
|
||||
if (!w) {
|
||||
ret[k] = NULL;
|
||||
strv_free(ret);
|
||||
strv_free(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = w;
|
||||
if (m) {
|
||||
memcpy(ret + k, m, q * sizeof(char*));
|
||||
free(m);
|
||||
}
|
||||
|
||||
k += q;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If ${FOO} appears as part of a word, replace it by the variable as-is */
|
||||
ret[k] = replace_env(*i, env);
|
||||
if (!ret[k]) {
|
||||
strv_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
ret[k] = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ bool env_name_is_valid(const char *e);
|
||||
bool env_value_is_valid(const char *e);
|
||||
bool env_assignment_is_valid(const char *e);
|
||||
|
||||
char *replace_env(const char *format, char **env);
|
||||
char **replace_env_argv(char **argv, char **env);
|
||||
|
||||
bool strv_env_is_valid(char **e);
|
||||
#define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL)
|
||||
char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata);
|
||||
|
||||
@@ -2083,150 +2083,6 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
|
||||
}
|
||||
}
|
||||
|
||||
char *replace_env(const char *format, char **env) {
|
||||
enum {
|
||||
WORD,
|
||||
CURLY,
|
||||
VARIABLE
|
||||
} state = WORD;
|
||||
|
||||
const char *e, *word = format;
|
||||
char *r = NULL, *k;
|
||||
|
||||
assert(format);
|
||||
|
||||
for (e = format; *e; e ++) {
|
||||
|
||||
switch (state) {
|
||||
|
||||
case WORD:
|
||||
if (*e == '$')
|
||||
state = CURLY;
|
||||
break;
|
||||
|
||||
case CURLY:
|
||||
if (*e == '{') {
|
||||
k = strnappend(r, word, e-word-1);
|
||||
if (!k)
|
||||
goto fail;
|
||||
|
||||
free(r);
|
||||
r = k;
|
||||
|
||||
word = e-1;
|
||||
state = VARIABLE;
|
||||
|
||||
} else if (*e == '$') {
|
||||
k = strnappend(r, word, e-word);
|
||||
if (!k)
|
||||
goto fail;
|
||||
|
||||
free(r);
|
||||
r = k;
|
||||
|
||||
word = e+1;
|
||||
state = WORD;
|
||||
} else
|
||||
state = WORD;
|
||||
break;
|
||||
|
||||
case VARIABLE:
|
||||
if (*e == '}') {
|
||||
const char *t;
|
||||
|
||||
t = strempty(strv_env_get_n(env, word+2, e-word-2));
|
||||
|
||||
k = strappend(r, t);
|
||||
if (!k)
|
||||
goto fail;
|
||||
|
||||
free(r);
|
||||
r = k;
|
||||
|
||||
word = e+1;
|
||||
state = WORD;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
k = strnappend(r, word, e-word);
|
||||
if (!k)
|
||||
goto fail;
|
||||
|
||||
free(r);
|
||||
return k;
|
||||
|
||||
fail:
|
||||
free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **replace_env_argv(char **argv, char **env) {
|
||||
char **ret, **i;
|
||||
unsigned k = 0, l = 0;
|
||||
|
||||
l = strv_length(argv);
|
||||
|
||||
ret = new(char*, l+1);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
STRV_FOREACH(i, argv) {
|
||||
|
||||
/* If $FOO appears as single word, replace it by the split up variable */
|
||||
if ((*i)[0] == '$' && (*i)[1] != '{') {
|
||||
char *e;
|
||||
char **w, **m = NULL;
|
||||
unsigned q;
|
||||
|
||||
e = strv_env_get(env, *i+1);
|
||||
if (e) {
|
||||
int r;
|
||||
|
||||
r = strv_split_quoted(&m, e, UNQUOTE_RELAX);
|
||||
if (r < 0) {
|
||||
ret[k] = NULL;
|
||||
strv_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
m = NULL;
|
||||
|
||||
q = strv_length(m);
|
||||
l = l + q - 1;
|
||||
|
||||
w = realloc(ret, sizeof(char*) * (l+1));
|
||||
if (!w) {
|
||||
ret[k] = NULL;
|
||||
strv_free(ret);
|
||||
strv_free(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = w;
|
||||
if (m) {
|
||||
memcpy(ret + k, m, q * sizeof(char*));
|
||||
free(m);
|
||||
}
|
||||
|
||||
k += q;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If ${FOO} appears as part of a word, replace it by the variable as-is */
|
||||
ret[k] = replace_env(*i, env);
|
||||
if (!ret[k]) {
|
||||
strv_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
ret[k] = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int files_same(const char *filea, const char *fileb) {
|
||||
struct stat a, b;
|
||||
|
||||
|
||||
@@ -220,9 +220,6 @@ const char* split(const char **state, size_t *l, const char *separator, bool quo
|
||||
char *strappend(const char *s, const char *suffix);
|
||||
char *strnappend(const char *s, const char *suffix, size_t length);
|
||||
|
||||
char *replace_env(const char *format, char **env);
|
||||
char **replace_env_argv(char **argv, char **env);
|
||||
|
||||
int readlinkat_malloc(int fd, const char *p, char **ret);
|
||||
int readlink_malloc(const char *p, char **r);
|
||||
int readlink_value(const char *p, char **ret);
|
||||
|
||||
Reference in New Issue
Block a user