diff options
author | 2010-08-27 12:55:38 +0100 | |
---|---|---|
committer | 2010-08-27 12:55:38 +0100 | |
commit | eb518df671b06ce805da858bf238493639cc6a2a (patch) | |
tree | 22f15c685486d1b628fe5220643ce938af555741 | |
parent | 4b5d72298a7c2e34cb3934b4042b8bb612487240 (diff) | |
download | paludis-eb518df671b06ce805da858bf238493639cc6a2a.tar.gz paludis-eb518df671b06ce805da858bf238493639cc6a2a.tar.xz |
Support ${ENV{FOO}} in KV configs
-rw-r--r-- | paludis/util/config_file.cc | 44 | ||||
-rw-r--r-- | paludis/util/config_file.se | 1 | ||||
-rw-r--r-- | paludis/util/config_file_TEST.cc | 21 |
3 files changed, 57 insertions, 9 deletions
diff --git a/paludis/util/config_file.cc b/paludis/util/config_file.cc index 8db003559..90dd0ef81 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 d7d7036bf..fb5a974c8 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 f68122188..95ad3c98b 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; } |