From a12f9f6b81668cfc6860643f6c27edf950c072e9 Mon Sep 17 00:00:00 2001 From: Luca Heltai Date: Wed, 20 Sep 2017 14:13:02 +0200 Subject: [PATCH] Test for path handling. --- include/deal.II/base/parameter_acceptor.h | 8 +- source/base/parameter_acceptor.cc | 49 +++++----- .../parameter_acceptor_08.cc | 90 +++++++++++++++++++ .../parameter_acceptor_08.output | 55 ++++++++++++ 4 files changed, 173 insertions(+), 29 deletions(-) create mode 100644 tests/parameter_handler/parameter_acceptor_08.cc create mode 100644 tests/parameter_handler/parameter_acceptor_08.output diff --git a/include/deal.II/base/parameter_acceptor.h b/include/deal.II/base/parameter_acceptor.h index 27fc2a894b..78b5814df1 100644 --- a/include/deal.II/base/parameter_acceptor.h +++ b/include/deal.II/base/parameter_acceptor.h @@ -500,10 +500,10 @@ protected: // Inline and template functions template -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); diff --git a/source/base/parameter_acceptor.cc b/source/base/parameter_acceptor.cc index e0213ad7a0..9e28e7474c 100644 --- a/source/base/parameter_acceptor.cc +++ b/source/base/parameter_acceptor.cc @@ -180,35 +180,34 @@ std::vector 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 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; } diff --git a/tests/parameter_handler/parameter_acceptor_08.cc b/tests/parameter_handler/parameter_acceptor_08.cc new file mode 100644 index 0000000000..bf869581cc --- /dev/null +++ b/tests/parameter_handler/parameter_acceptor_08.cc @@ -0,0 +1,90 @@ +//----------------------------------------------------------- +// +// 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 +#include + +// 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); +} diff --git a/tests/parameter_handler/parameter_acceptor_08.output b/tests/parameter_handler/parameter_acceptor_08.output new file mode 100644 index 0000000000..323f53b9ff --- /dev/null +++ b/tests/parameter_handler/parameter_acceptor_08.output @@ -0,0 +1,55 @@ + +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 -- 2.39.5