summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2017-02-11 14:05:10 -0500
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2017-02-20 23:30:50 -0500
commitccad1fd07ce4eb40a2fcf81cfb55d9b41fdcac48 (patch)
tree41b72c7747d8072e212ed58fd8b5c1e71c18d0b7 /src/basic
parentcb4499d0056a7c974d7d3695cc355c7e77edc938 (diff)
Allow braceless variables to be expanded
(Only in environment.d files.) We have only basic compatibility with shell syntax, but specifying variables without using braces is probably more common, and I think a lot of people would be surprised if this didn't work.
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/env-util.c45
-rw-r--r--src/basic/env-util.h1
-rw-r--r--src/basic/fileio.c7
3 files changed, 50 insertions, 3 deletions
diff --git a/src/basic/env-util.c b/src/basic/env-util.c
index 8774a81531..f370854673 100644
--- a/src/basic/env-util.c
+++ b/src/basic/env-util.c
@@ -523,7 +523,8 @@ char *replace_env(const char *format, char **env, unsigned flags) {
enum {
WORD,
CURLY,
- VARIABLE
+ VARIABLE,
+ VARIABLE_RAW,
} state = WORD;
const char *e, *word = format;
@@ -563,6 +564,18 @@ char *replace_env(const char *format, char **env, unsigned flags) {
word = e+1;
state = WORD;
+
+ } else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_CHARS_ENV_NAME, *e)) {
+ k = strnappend(r, word, e-word-1);
+ if (!k)
+ return NULL;
+
+ free(r);
+ r = k;
+
+ word = e-1;
+ state = VARIABLE_RAW;
+
} else
state = WORD;
break;
@@ -584,10 +597,38 @@ char *replace_env(const char *format, char **env, unsigned flags) {
state = WORD;
}
break;
+
+ case VARIABLE_RAW:
+ assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
+
+ if (!strchr(VALID_CHARS_ENV_NAME, *e)) {
+ const char *t;
+
+ t = strv_env_get_n(env, word+1, e-word-1, flags);
+
+ k = strappend(r, t);
+ if (!k)
+ return NULL;
+
+ free(r);
+ r = k;
+
+ word = e--;
+ state = WORD;
+ }
+ break;
}
}
- return strnappend(r, word, e-word);
+ if (state == VARIABLE_RAW) {
+ const char *t;
+
+ assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
+
+ t = strv_env_get_n(env, word+1, e-word-1, flags);
+ return strappend(r, t);
+ } else
+ return strnappend(r, word, e-word);
}
char **replace_env_argv(char **argv, char **env) {
diff --git a/src/basic/env-util.h b/src/basic/env-util.h
index 4e83dcb43a..03bbc6af00 100644
--- a/src/basic/env-util.h
+++ b/src/basic/env-util.h
@@ -31,6 +31,7 @@ bool env_assignment_is_valid(const char *e);
enum {
REPLACE_ENV_USE_ENVIRONMENT = 1u,
+ REPLACE_ENV_ALLOW_BRACELESS = 2u,
};
char *replace_env(const char *format, char **env, unsigned flags);
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 49dd52bfd9..3c2dab1855 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -773,7 +773,8 @@ static int merge_env_file_push(
assert(env);
- expanded_value = replace_env(value, *env, REPLACE_ENV_USE_ENVIRONMENT);
+ expanded_value = replace_env(value, *env,
+ REPLACE_ENV_USE_ENVIRONMENT|REPLACE_ENV_ALLOW_BRACELESS);
if (!expanded_value)
return -ENOMEM;
@@ -787,6 +788,10 @@ int merge_env_file(
FILE *f,
const char *fname) {
+ /* NOTE: this function supports braceful and braceless variable expansions,
+ * unlike other exported parsing functions.
+ */
+
return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
}