aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-27 12:55:38 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-27 12:55:38 +0100
commiteb518df671b06ce805da858bf238493639cc6a2a (patch)
tree22f15c685486d1b628fe5220643ce938af555741
parent4b5d72298a7c2e34cb3934b4042b8bb612487240 (diff)
downloadpaludis-eb518df671b06ce805da858bf238493639cc6a2a.tar.gz
paludis-eb518df671b06ce805da858bf238493639cc6a2a.tar.xz
Support ${ENV{FOO}} in KV configs
-rw-r--r--paludis/util/config_file.cc44
-rw-r--r--paludis/util/config_file.se1
-rw-r--r--paludis/util/config_file_TEST.cc21
3 files changed, 57 insertions, 9 deletions
diff --git a/paludis/util/config_file.cc b/paludis/util/config_file.cc
index 8db0035..90dd0ef 100644
--- a/paludis/util/config_file.cc
+++ b/paludis/util/config_file.cc
@@ -28,6 +28,7 @@
#include <paludis/util/simple_parser.hh>
#include <paludis/util/log.hh>
#include <paludis/util/safe_ifstream.hh>
+#include <paludis/util/system.hh>
#include <istream>
#include <list>
@@ -358,7 +359,7 @@ namespace
PALUDIS_ATTRIBUTE((warn_unused_result));
bool parse_unquoted_value(const KeyValueConfigFile & k, const ConfigFile::Source & sr, SimpleParser & parser, std::string & result)
PALUDIS_ATTRIBUTE((warn_unused_result));
- bool parse_variable(const KeyValueConfigFile & k, const ConfigFile::Source & sr, SimpleParser & parser, std::string & var)
+ bool parse_variable(const KeyValueConfigFile & k, const ConfigFile::Source & sr, SimpleParser & parser, std::string & var, bool &)
PALUDIS_ATTRIBUTE((warn_unused_result));
bool parse_value(const KeyValueConfigFile & k, const ConfigFile::Source & sr, SimpleParser & parser, std::string & result)
@@ -430,9 +431,13 @@ namespace
else if ((! k.options()[kvcfo_disallow_variables]) && parser.consume(simple_parser::exact("$")))
{
std::string var;
- if (! parse_variable(k, sr, parser, var))
+ bool is_env;
+ if (! parse_variable(k, sr, parser, var, is_env))
throw ConfigFileError(sr.filename(), "Bad variable at line " + stringify(parser.current_line_number()));
- result.append(k.get(var));
+ if (is_env)
+ result.append(getenv_with_default(var, ""));
+ else
+ result.append(k.get(var));
}
else if (parser.consume(simple_parser::exact("\"")))
break;
@@ -445,16 +450,33 @@ namespace
return true;
}
- bool parse_variable(const KeyValueConfigFile &, const ConfigFile::Source &, SimpleParser & parser, std::string & var)
+ bool parse_variable(const KeyValueConfigFile & k, const ConfigFile::Source &, SimpleParser & parser, std::string & var, bool & is_env)
{
const std::string var_name_chars(
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789_"
);
- return
- parser.consume(simple_parser::exact("{") & +simple_parser::any_of(var_name_chars) >> var & simple_parser::exact("}")) ||
- parser.consume(+simple_parser::any_of(var_name_chars) >> var);
+
+ if (k.options()[kvcfo_allow_env])
+ {
+ is_env = true;
+
+ if (parser.consume(simple_parser::exact("{ENV{") & +simple_parser::any_of(var_name_chars) >> var & simple_parser::exact("}}")))
+ return true;
+ if (parser.consume(simple_parser::exact("ENV{") & +simple_parser::any_of(var_name_chars) >> var & simple_parser::exact("}")))
+ return true;
+ }
+
+ is_env = false;
+
+ if (parser.consume(simple_parser::exact("{") & +simple_parser::any_of(var_name_chars) >> var & simple_parser::exact("}")))
+ return true;
+
+ if (parser.consume(+simple_parser::any_of(var_name_chars) >> var))
+ return true;
+
+ return false;
}
bool parse_unquoted_value(const KeyValueConfigFile & k, const ConfigFile::Source & sr, SimpleParser & parser, std::string & result)
@@ -495,9 +517,13 @@ namespace
}
std::string var;
- if (! parse_variable(k, sr, parser, var))
+ bool is_env;
+ if (! parse_variable(k, sr, parser, var, is_env))
throw ConfigFileError(sr.filename(), "Bad variable at line " + stringify(parser.current_line_number()));
- result.append(k.get(var));
+ if (is_env)
+ result.append(getenv_with_default(var, ""));
+ else
+ result.append(k.get(var));
}
else if ((! k.options()[kvcfo_disallow_continuations]) && parser.consume(simple_parser::exact("\\\n")))
{
diff --git a/paludis/util/config_file.se b/paludis/util/config_file.se
index d7d7036..fb5a974 100644
--- a/paludis/util/config_file.se
+++ b/paludis/util/config_file.se
@@ -41,6 +41,7 @@ make_enum_KeyValueConfigFileOption()
key kvcfo_allow_multiple_assigns_per_line "Allow A='b' B='c' (and unquoted if kvcfo_disallow_space_inside_unquoted_values). \since 0.28"
key kvcfo_allow_sections "Allow [sections] \since 0.44"
key kvcfo_allow_fancy_assigns "Allow ?= assignments \since 0.54.1"
+ key kvcfo_allow_env "Allow \${ENV{blah}} \since 0.54.1"
doxygen_comment << "END"
/**
diff --git a/paludis/util/config_file_TEST.cc b/paludis/util/config_file_TEST.cc
index f681221..95ad3c9 100644
--- a/paludis/util/config_file_TEST.cc
+++ b/paludis/util/config_file_TEST.cc
@@ -526,5 +526,26 @@ namespace test_cases
TEST_CHECK_EQUAL(ff.get("b"), "B");
}
} test_key_value_config_file_fancy_assigns;
+
+ struct KeyValueConfigFileEnvVarsTest : TestCase
+ {
+ KeyValueConfigFileEnvVarsTest() : TestCase("key value config env vars") { }
+
+ void run()
+ {
+ ::setenv("A_VAR", "AAAARGH", 1);
+ ::setenv("B_VAR", "BRRRRGH", 1);
+
+ std::stringstream d_s;
+ d_s << "a = ${ENV{A_VAR}}" << std::endl;
+ d_s << "b = ${ENV{B_VAR}}" << std::endl;
+ KeyValueConfigFile ff(d_s, { kvcfo_allow_env },
+ &KeyValueConfigFile::no_defaults, &KeyValueConfigFile::no_transformation);
+
+ TEST_CHECK_EQUAL(std::distance(ff.begin(), ff.end()), 2);
+ TEST_CHECK_EQUAL(ff.get("a"), "AAAARGH");
+ TEST_CHECK_EQUAL(ff.get("b"), "BRRRRGH");
+ }
+ } test_key_value_config_file_env_vars;
}