diff options
author | 2010-01-02 22:21:48 +0000 | |
---|---|---|
committer | 2010-01-02 22:21:48 +0000 | |
commit | 9ee3e69e7d5cc3a4ae500855fb57dbc36ac759b8 (patch) | |
tree | c76fd295d673641918a4019b92bc9a5fd5ccfdbe /paludis | |
parent | a5c83d8107c3454685a592b46fbbec17a0eaf117 (diff) | |
download | paludis-9ee3e69e7d5cc3a4ae500855fb57dbc36ac759b8.tar.gz paludis-9ee3e69e7d5cc3a4ae500855fb57dbc36ac759b8.tar.xz |
Support sections in kv configs
Diffstat (limited to 'paludis')
-rw-r--r-- | paludis/util/config_file.cc | 54 | ||||
-rw-r--r-- | paludis/util/config_file.hh | 2 | ||||
-rw-r--r-- | paludis/util/config_file.se | 1 | ||||
-rw-r--r-- | paludis/util/config_file_TEST.cc | 31 |
4 files changed, 85 insertions, 3 deletions
diff --git a/paludis/util/config_file.cc b/paludis/util/config_file.cc index 5306fb1ec..5187a1da8 100644 --- a/paludis/util/config_file.cc +++ b/paludis/util/config_file.cc @@ -1,7 +1,7 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* - * Copyright (c) 2006, 2007, 2008, 2009 Ciaran McCreesh + * Copyright (c) 2006, 2007, 2008, 2009, 2010 Ciaran McCreesh * Copyright (c) 2006 Danny van Dyk * * This file is part of the Paludis package manager. Paludis is free software; @@ -334,6 +334,8 @@ namespace paludis KeyValueConfigFileValues values; + std::string active_key_prefix; + Implementation( const KeyValueConfigFileOptions & o, const KeyValueConfigFile::DefaultFunction & d, @@ -635,6 +637,48 @@ KeyValueConfigFile::KeyValueConfigFile( continue; } + /* is it a section? */ + if (_imp->options[kvcfo_allow_sections] && parser.consume(simple_parser::exact("["))) + { + std::string sec_t, sec_s; + if (! parser.consume(+simple_parser::any_except(" \t\n$#\"'=\\]") >> sec_t)) + throw ConfigFileError(sr.filename(), "Expected section name on line " + stringify(parser.current_line_number())); + + if (! parser.consume(*simple_parser::any_of(" \t"))) + throw InternalError(PALUDIS_HERE, "failed to consume a zero width match"); + + if (! parser.consume(simple_parser::exact("]"))) + { + if (! parser.consume(+simple_parser::any_except(" \t\n$#\"\\]") >> sec_s)) + throw ConfigFileError(sr.filename(), "Expected section name value on line " + + stringify(parser.current_line_number())); + if (! parser.consume(*simple_parser::any_of(" \t"))) + throw InternalError(PALUDIS_HERE, "failed to consume a zero width match"); + if (! parser.consume(simple_parser::exact("]"))) + throw ConfigFileError(sr.filename(), "Expected ] on line " + + stringify(parser.current_line_number())); + } + + if (! parser.consume(*simple_parser::any_of(" \t"))) + throw InternalError(PALUDIS_HERE, "failed to consume a zero width match"); + if (! parser.consume(*simple_parser::exact("\n"))) + { + if (parser.eof()) + Log::get_instance()->message("key_value_config_file.no_trailing_newline", ll_debug, lc_context) + << "No newline at end of file"; + else + throw ConfigFileError(sr.filename(), "Expected newline after ']' at line " + + stringify(parser.current_line_number() + "'")); + } + + if (sec_s.empty()) + _imp->active_key_prefix = sec_t + "/"; + else + _imp->active_key_prefix = sec_t + "/" + sec_s + "/"; + + continue; + } + /* ignore export, if appropriate */ if (_imp->options[kvcfo_ignore_export] && parser.consume(simple_parser::exact("export") & +simple_parser::any_of(" \t"))) @@ -711,8 +755,11 @@ KeyValueConfigFile::KeyValueConfigFile( break; } + key = _imp->active_key_prefix + key; _imp->values[key] = transformation_function()(*this, key, get(key), value); } + + _imp->active_key_prefix = ""; } KeyValueConfigFile::~KeyValueConfigFile() @@ -734,7 +781,10 @@ KeyValueConfigFile::end() const std::string KeyValueConfigFile::get(const std::string & s) const { - std::map<std::string, std::string>::const_iterator f(_imp->values.find(s)); + std::map<std::string, std::string>::const_iterator f(_imp->values.find(_imp->active_key_prefix + s)); + if (_imp->values.end() == f) + f = _imp->values.find(s); + if (_imp->values.end() == f) return _imp->default_function(*this, s); else diff --git a/paludis/util/config_file.hh b/paludis/util/config_file.hh index 9026ad7c9..0c21bf3fa 100644 --- a/paludis/util/config_file.hh +++ b/paludis/util/config_file.hh @@ -192,6 +192,8 @@ namespace paludis * - Unless kvcfo_disallow_variables, variables using $foo and ${foo} are expanded. * - Unless kvcfo_disallow_source, source path is legal. * - Unless kvcfo_preserve_whitespace, leading and trailing whitespace on values is stripped. + * - If kvcfo_allow_sections, sections in the form "[foo]" and "[foo bar]" are allowed. A key + * 'baz' in section "[foo]" will be treated as "foo/baz", and "[foo bar]" as "foo/bar/baz". * * \ingroup g_config_file * \nosubgrouping diff --git a/paludis/util/config_file.se b/paludis/util/config_file.se index ca139db74..1c56bb031 100644 --- a/paludis/util/config_file.se +++ b/paludis/util/config_file.se @@ -39,6 +39,7 @@ make_enum_KeyValueConfigFileOption() key kvcfo_ignore_export "Accept and ignore the word export at the beginning of a line" 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" doxygen_comment << "END" /** diff --git a/paludis/util/config_file_TEST.cc b/paludis/util/config_file_TEST.cc index f5a46c142..dcd91b78e 100644 --- a/paludis/util/config_file_TEST.cc +++ b/paludis/util/config_file_TEST.cc @@ -1,7 +1,7 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* - * Copyright (c) 2006, 2007, 2008 Ciaran McCreesh + * Copyright (c) 2006, 2007, 2008, 2009, 2010 Ciaran McCreesh * * This file is part of the Paludis package manager. Paludis is free software; * you can redistribute it and/or modify it under the terms of the GNU General @@ -479,5 +479,34 @@ namespace test_cases TEST_CHECK_EQUAL(ff.get("five"), "five"); } } test_key_value_config_file_multiple_assigns; + + struct KeyValueConfigFileSectionsTest : TestCase + { + KeyValueConfigFileSectionsTest() : TestCase("key value config sections") { } + + void run() + { + std::stringstream d_s; + d_s << "a = b" << std::endl; + d_s << "c = d" << std::endl; + d_s << "[foo]" << std::endl; + d_s << "a = c" << std::endl; + d_s << "[bar bar]" << std::endl; + d_s << "a = d" << std::endl; + d_s << "[var]" << std::endl; + d_s << "b = x" << std::endl; + d_s << "a = ${a} ${b} ${c}" << std::endl; + KeyValueConfigFile ff(d_s, KeyValueConfigFileOptions() + kvcfo_allow_sections, + &KeyValueConfigFile::no_defaults, &KeyValueConfigFile::no_transformation); + + TEST_CHECK_EQUAL(std::distance(ff.begin(), ff.end()), 6); + TEST_CHECK_EQUAL(ff.get("a"), "b"); + TEST_CHECK_EQUAL(ff.get("c"), "d"); + TEST_CHECK_EQUAL(ff.get("foo/a"), "c"); + TEST_CHECK_EQUAL(ff.get("bar/bar/a"), "d"); + TEST_CHECK_EQUAL(ff.get("var/b"), "x"); + TEST_CHECK_EQUAL(ff.get("var/a"), "b x d"); + } + } test_key_value_config_file_sections; } |