aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-27 10:15:24 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-27 10:15:24 +0100
commita7dadc909b069b9eb6c85d67158219053bba9e05 (patch)
tree87b80c2a0ccbbf8f6251e272c585abbd8f9df8c6
parente4462298b03ef80c5566944f7ce04c131ddd2c51 (diff)
downloadpaludis-a7dadc909b069b9eb6c85d67158219053bba9e05.tar.gz
paludis-a7dadc909b069b9eb6c85d67158219053bba9e05.tar.xz
kvcfo_allow_fancy_assign
-rw-r--r--paludis/util/config_file.cc18
-rw-r--r--paludis/util/config_file.se1
-rw-r--r--paludis/util/config_file_TEST.cc19
3 files changed, 35 insertions, 3 deletions
diff --git a/paludis/util/config_file.cc b/paludis/util/config_file.cc
index 94d4797..8db0035 100644
--- a/paludis/util/config_file.cc
+++ b/paludis/util/config_file.cc
@@ -701,7 +701,7 @@ KeyValueConfigFile::KeyValueConfigFile(
/* is it superman? */
std::string key, value;
- if (! parser.consume(+simple_parser::any_except(" \t\n$#\"'=\\") >> key))
+ if (! parser.consume(+simple_parser::any_except(" \t\n$#\"'=\\?") >> key))
throw ConfigFileError(sr.filename(), "Couldn't find a key in line " + stringify(parser.current_line_number()));
while (! parser.eof())
@@ -718,9 +718,15 @@ KeyValueConfigFile::KeyValueConfigFile(
break;
}
- if (! parser.consume(simple_parser::exact("=")))
+ bool question_assign(false);
+ if (parser.consume(simple_parser::exact("?=")))
+ question_assign = true;
+ else if (! parser.consume(simple_parser::exact("=")))
throw ConfigFileError(sr.filename(), "Expected an = at line " + stringify(parser.current_line_number()));
+ if (question_assign && ! _imp->options[kvcfo_allow_fancy_assigns])
+ throw ConfigFileError(sr.filename(), "Not allowed to use ?= on line " + stringify(parser.current_line_number()));
+
while (! parser.eof())
{
if (parser.consume(+simple_parser::any_of(" \t")))
@@ -769,7 +775,13 @@ KeyValueConfigFile::KeyValueConfigFile(
}
key = _imp->active_key_prefix + key;
- _imp->values[key] = transformation_function()(*this, key, get(key), value);
+
+ bool want(true);
+ if (question_assign && ! get(key).empty())
+ want = false;
+
+ if (want)
+ _imp->values[key] = transformation_function()(*this, key, get(key), value);
}
_imp->active_key_prefix = "";
diff --git a/paludis/util/config_file.se b/paludis/util/config_file.se
index 1c56bb0..d7d7036 100644
--- a/paludis/util/config_file.se
+++ b/paludis/util/config_file.se
@@ -40,6 +40,7 @@ make_enum_KeyValueConfigFileOption()
key kvcfo_allow_inline_comments "Allow inline comments. \since 0.28"
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"
doxygen_comment << "END"
/**
diff --git a/paludis/util/config_file_TEST.cc b/paludis/util/config_file_TEST.cc
index 217aebe..f681221 100644
--- a/paludis/util/config_file_TEST.cc
+++ b/paludis/util/config_file_TEST.cc
@@ -507,5 +507,24 @@ namespace test_cases
TEST_CHECK_EQUAL(ff.get("var/a"), "b x d");
}
} test_key_value_config_file_sections;
+
+ struct KeyValueConfigFileFancyAssignsTest : TestCase
+ {
+ KeyValueConfigFileFancyAssignsTest() : TestCase("key value config fancy assigns") { }
+
+ void run()
+ {
+ std::stringstream d_s;
+ d_s << "a = A" << std::endl;
+ d_s << "a ?= X" << std::endl;
+ d_s << "b ?= B" << std::endl;
+ KeyValueConfigFile ff(d_s, { kvcfo_allow_sections, kvcfo_allow_fancy_assigns },
+ &KeyValueConfigFile::no_defaults, &KeyValueConfigFile::no_transformation);
+
+ TEST_CHECK_EQUAL(std::distance(ff.begin(), ff.end()), 2);
+ TEST_CHECK_EQUAL(ff.get("a"), "A");
+ TEST_CHECK_EQUAL(ff.get("b"), "B");
+ }
+ } test_key_value_config_file_fancy_assigns;
}