// Inline and template functions
template<class ParameterType>
-void ParameterAcceptor::add_parameter(const std::string& entry,
- ParameterType& parameter,
- const std::string& documentation,
- const Patterns::PatternBase& pattern)
+void ParameterAcceptor::add_parameter(const std::string &entry,
+ ParameterType ¶meter,
+ const std::string &documentation,
+ const Patterns::PatternBase &pattern)
{
enter_my_subsection(prm);
prm.add_parameter(entry, parameter, documentation, pattern);
ParameterAcceptor::get_section_path() const
{
Assert(acceptor_id < class_list.size(), ExcInternalError());
+ auto my_section_name = get_section_name();
+ bool is_absolute = my_section_name.front() == sep;
+
std::vector<std::string> sections =
- Utilities::split_string_list(class_list[acceptor_id]->get_section_name(), sep);
- bool is_absolute = false;
- if (sections.size() > 1)
- {
- // Handle the cases of a leading "/"
- if (sections[0] == "")
- {
- is_absolute = true;
- sections.erase(sections.begin());
- }
- }
- if (is_absolute == false)
+ Utilities::split_string_list(my_section_name, sep);
+
+ if (is_absolute)
+ sections.erase(sections.begin());
+ else
{
- // In all other cases, we scan for earlier classes, and prepend the
- // first absolute path (in reverse order) we find to ours
+ // If we want a relative path, we prepend the path of the previous class
+ // to ours. This is tricky. If the previous class has a path with a
+ // trailing /, then the full path is used, else only the path except the
+ // last one
for (int i=acceptor_id-1; i>=0; --i)
if (class_list[i] != NULL)
- if (class_list[i]->get_section_name().front() == sep)
- {
- bool has_trailing = class_list[i]->get_section_name().back() == sep;
- // Absolute path found
- auto secs = Utilities::split_string_list(class_list[i]->get_section_name(), sep);
- Assert(secs[0] == "", ExcInternalError());
- // Insert all sections except first and last
- sections.insert(sections.begin(), secs.begin()+1, secs.end()-(has_trailing ? 0 : 1));
- // exit from for cycle
- break;
- }
+ {
+ bool has_trailing = class_list[i]->get_section_name().back() == sep;
+ auto previous_path = class_list[i]->get_section_path();
+
+ // See if we need to remove last piece of the path
+ if (previous_path.size() >= 1 && has_trailing == false)
+ previous_path.resize(previous_path.size()-1);
+
+ sections.insert(sections.begin(), previous_path.begin(), previous_path.end());
+ // Exit the for cycle
+ break;
+ }
}
return sections;
}
--- /dev/null
+//-----------------------------------------------------------
+//
+// Copyright (C) 2015 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+//-----------------------------------------------------------
+
+
+
+#include "../tests.h"
+#include <deal.II/base/path_search.h>
+#include <deal.II/base/parameter_acceptor.h>
+
+// Test subsectioning
+
+class Test : public ParameterAcceptor
+{
+public:
+ Test(const std::string &sec_name = "First Class",
+ const std::string &par_name = "Parameter name",
+ const std::string &par_value = "Parameter value"):
+ ParameterAcceptor(sec_name),
+ par_name(par_name),
+ par_value(par_value)
+ {
+ add_parameter(par_name, this->par_value);
+
+ deallog << "Section Name : " << sec_name << std::endl;
+ deallog << "N sections : " << get_section_path().size() << std::endl;
+ deallog << "Sections : ";
+ for (auto s : get_section_path())
+ deallog << "\"" << s << "\" ";
+ deallog << std::endl << std::endl;
+ };
+
+private:
+ std::string par_name;
+ std::string par_value;
+};
+
+int main ()
+{
+ initlog();
+ auto &prm = ParameterAcceptor::prm;
+
+ // Relative
+ Test a("Class A", "Parameter A", "a");
+
+ // Absolute (== relative if no other path is added)
+ Test c("/Class B", "Parameter C", "c");
+
+
+ // Absolute (== relative if no other path is added)
+ Test c2("/Class C/", "Parameter C", "c");
+
+ // Absolute and no name
+ Test a0("/", "Absolute parameter", "a");
+
+ // Relative to absolute = absolute
+ Test d("Class C", "Parameter C", "d");
+
+ // Explicit, with absolute path
+ Test d1("/Class D/Class D1", "Parameter D1", "d");
+
+ // Relative to previous, with trailing
+ Test d2("Class D2/", "Parameter D2", "d");
+
+ // Relative to previous
+ Test d3("Class D2D3", "Parameter D2D3", "e");
+
+ // Another relative to reset
+ Test d4("/Class E", "Parameter E", "e");
+
+ // Same level of E1
+ Test d5("Class E2/", "Parameter E", "e");
+
+ // One level below E2
+ Test d6("Class E2E3", "Parameter E", "e");
+
+ ParameterAcceptor::declare_all_parameters();
+ prm.log_parameters(deallog);
+}
--- /dev/null
+
+DEAL::Section Name : Class A
+DEAL::N sections : 1
+DEAL::Sections : "Class A"
+DEAL::
+DEAL::Section Name : /Class B
+DEAL::N sections : 1
+DEAL::Sections : "Class B"
+DEAL::
+DEAL::Section Name : /Class C/
+DEAL::N sections : 1
+DEAL::Sections : "Class C"
+DEAL::
+DEAL::Section Name : /
+DEAL::N sections : 0
+DEAL::Sections :
+DEAL::
+DEAL::Section Name : Class C
+DEAL::N sections : 1
+DEAL::Sections : "Class C"
+DEAL::
+DEAL::Section Name : /Class D/Class D1
+DEAL::N sections : 2
+DEAL::Sections : "Class D" "Class D1"
+DEAL::
+DEAL::Section Name : Class D2/
+DEAL::N sections : 2
+DEAL::Sections : "Class D" "Class D2"
+DEAL::
+DEAL::Section Name : Class D2D3
+DEAL::N sections : 3
+DEAL::Sections : "Class D" "Class D2" "Class D2D3"
+DEAL::
+DEAL::Section Name : /Class E
+DEAL::N sections : 1
+DEAL::Sections : "Class E"
+DEAL::
+DEAL::Section Name : Class E2/
+DEAL::N sections : 1
+DEAL::Sections : "Class E2"
+DEAL::
+DEAL::Section Name : Class E2E3
+DEAL::N sections : 2
+DEAL::Sections : "Class E2" "Class E2E3"
+DEAL::
+DEAL:parameters::Absolute parameter: a
+DEAL:parameters:Class A::Parameter A: a
+DEAL:parameters:Class B::Parameter C: c
+DEAL:parameters:Class C::Parameter C: d
+DEAL:parameters:Class D:Class D1::Parameter D1: d
+DEAL:parameters:Class D:Class D2::Parameter D2: d
+DEAL:parameters:Class D:Class D2:Class D2D3::Parameter D2D3: e
+DEAL:parameters:Class E::Parameter E: e
+DEAL:parameters:Class E2::Parameter E: e
+DEAL:parameters:Class E2:Class E2E3::Parameter E: e