From 0b962b11037c5229fcd62eb10f4d191c1635be41 Mon Sep 17 00:00:00 2001 From: David Wells Date: Mon, 18 Jan 2016 21:10:39 -0500 Subject: [PATCH] Improve ParameterHandler continuation handling. This commit builds on 23f306dfc5. ParameterHandler now correctly handles continuation lines in both versions of the read_input function, while before it only handled continuation lines in one version (the file name as a string version) before. Closes #333. --- doc/news/changes.h | 2 +- source/base/parameter_handler.cc | 93 ++++++++----------- tests/bits/parameter_handler_backslash_01.cc | 45 +++++---- .../parameter_handler_backslash_01.output | 1 + tests/bits/parameter_handler_backslash_02.cc | 45 +++++---- .../parameter_handler_backslash_02.output | 1 + tests/bits/parameter_handler_backslash_03.cc | 46 +++++---- ...er_handler_backslash_03.expect=diff.output | 1 + tests/bits/parameter_handler_backslash_04.cc | 46 +++++---- ...er_handler_backslash_04.expect=diff.output | 1 + tests/bits/parameter_handler_backslash_05.cc | 58 +++++++----- ...er_handler_backslash_05.expect=diff.output | 2 + 12 files changed, 201 insertions(+), 140 deletions(-) diff --git a/doc/news/changes.h b/doc/news/changes.h index b4b652751f..ec08bf161c 100644 --- a/doc/news/changes.h +++ b/doc/news/changes.h @@ -433,7 +433,7 @@ inconvenience this causes.
  • Improved: Allow continuation lines in ParameterHandler.
    - (Alberto Sartori, 2015/09/04) + (Alberto Sartori, 2015/09/04, David Wells, 2016/01/18)
  • Cleanup: The interface of Tensor has been cleaned diff --git a/source/base/parameter_handler.cc b/source/base/parameter_handler.cc index 97679b3f06..fa072ed560 100644 --- a/source/base/parameter_handler.cc +++ b/source/base/parameter_handler.cc @@ -1337,14 +1337,45 @@ bool ParameterHandler::read_input (std::istream &input, // store subsections we are currently in std::vector saved_path = subsection_path; - std::string line; + std::string input_line; + std::string fully_concatenated_line; + bool is_concatenated = false; unsigned int current_line_n = 0; bool status = true; - while (std::getline (input, line)) + while (std::getline (input, input_line)) { ++current_line_n; - status &= scan_line (line, filename, current_line_n); + + // check whether or not the current line should be joined with the next + // line before calling scan_line. + if (input_line.length() != 0 && + input_line.find_last_of('\\') == input_line.length() - 1) + { + input_line.erase(input_line.length() - 1); // remove the last '\' + is_concatenated = true; + + fully_concatenated_line += input_line; + } + // If the previous line ended in a '\' but the current did not, then we + // should proceed to scan_line. + else if (is_concatenated) + { + fully_concatenated_line += input_line; + is_concatenated = false; + } + // finally, if neither the previous nor current lines are continuations, + // then the current input line is entirely concatenated. + else + { + fully_concatenated_line = input_line; + } + + if (!is_concatenated) + { + status &= scan_line (fully_concatenated_line, filename, current_line_n); + fully_concatenated_line.clear(); + } } if (status && (saved_path != subsection_path)) @@ -1382,19 +1413,10 @@ bool ParameterHandler::read_input (const std::string &filename, try { std::string openname = search.find(filename); - std::ifstream file (openname.c_str()); - AssertThrow(file, ExcIO()); + std::ifstream file_stream (openname.c_str()); + AssertThrow(file_stream, ExcIO()); - std::string str; - std::string file_contents; - - while (std::getline(file, str)) - { - file_contents += str; - file_contents.push_back('\n'); - } - - return ParameterHandler::read_input_from_string (file_contents.c_str()); + return read_input (file_stream, filename); } catch (const PathSearch::ExcFileNotFound &) { @@ -1416,43 +1438,8 @@ bool ParameterHandler::read_input (const std::string &filename, bool ParameterHandler::read_input_from_string (const char *s) { - // create an istringstream representation and pass it off - // to the other functions doing this work - - // concatenate the lines ending with "\" - - std::istringstream file(s); - std::string str; - std::string file_contents; - bool is_concatenated(false); - while (std::getline(file, str)) - { - // if this str must be concatenated with the previous one - // we strip the whitespaces - if (is_concatenated) - { - const std::size_t str_begin = str.find_first_not_of(" \t"); - if (str_begin == std::string::npos) - str = ""; // no content - else - str.erase(0,str_begin); // trim whitespaces from left - } - - if ((std::find(str.begin(),str.end(),'\\') != str.end()) && str.find_last_of('\\') == str.length()-1) - { - str.erase(str.length()-1); // remove '\' - file_contents += str; - is_concatenated = true; // next line must be concatenated = true - } - else - { - is_concatenated = false; // next line must be concatenated = false - file_contents += str; - file_contents.push_back('\n'); - } - } - std::istringstream in (file_contents); - return read_input (in, "input string"); + std::istringstream input_stream (s); + return read_input (input_stream, "input string"); } @@ -2840,7 +2827,7 @@ bool MultipleParameterLoop::read_input (const std::string &filename, return ParameterHandler::read_input (filename, optional, write_compact); // don't call init_branches, since this read_input // function calls - // MultipleParameterLoop::Readinput(std::istream &, std::ostream &) + // MultipleParameterLoop::read_input(std::istream &, std::ostream &) // which itself calls init_branches. } diff --git a/tests/bits/parameter_handler_backslash_01.cc b/tests/bits/parameter_handler_backslash_01.cc index 689734fd0e..88f65430a4 100644 --- a/tests/bits/parameter_handler_backslash_01.cc +++ b/tests/bits/parameter_handler_backslash_01.cc @@ -1,6 +1,6 @@ // --------------------------------------------------------------------- // -// Copyright (C) 2003 - 2014 by the deal.II authors +// Copyright (C) 2003 - 2016 by the deal.II authors // // This file is part of the deal.II library. // @@ -26,21 +26,34 @@ int main () deallog.attach(logfile); deallog.threshold_double(1.e-10); - ParameterHandler prm; - prm.enter_subsection ("Testing"); - prm.declare_entry ("Function", - "a", - Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h"))); - prm.leave_subsection (); - - prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_01.prm"); - - std::string list; - prm.enter_subsection ("Testing"); - list = prm.get ("Function"); - prm.leave_subsection (); - - deallog << list << std::endl; + for (unsigned int i = 0; i < 2; ++i) + { + ParameterHandler prm; + prm.enter_subsection ("Testing"); + prm.declare_entry ("Function", + "a", + Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h"))); + prm.leave_subsection (); + + // test both relevant read_input functions + if (i == 0) + { + prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_01.prm"); + } + else + { + std::ifstream input_stream + (SOURCE_DIR "/prm/parameter_handler_backslash_01.prm"); + prm.read_input(input_stream); + } + + std::string list; + prm.enter_subsection ("Testing"); + list = prm.get ("Function"); + prm.leave_subsection (); + + deallog << list << std::endl; + } return 0; } diff --git a/tests/bits/parameter_handler_backslash_01.output b/tests/bits/parameter_handler_backslash_01.output index 9eb091f67d..5c8ecde2ba 100644 --- a/tests/bits/parameter_handler_backslash_01.output +++ b/tests/bits/parameter_handler_backslash_01.output @@ -1,2 +1,3 @@ DEAL::a, b, c +DEAL::a, b, c diff --git a/tests/bits/parameter_handler_backslash_02.cc b/tests/bits/parameter_handler_backslash_02.cc index 08f7b89675..f5e8b216e7 100644 --- a/tests/bits/parameter_handler_backslash_02.cc +++ b/tests/bits/parameter_handler_backslash_02.cc @@ -1,6 +1,6 @@ // --------------------------------------------------------------------- // -// Copyright (C) 2003 - 2014 by the deal.II authors +// Copyright (C) 2003 - 2016 by the deal.II authors // // This file is part of the deal.II library. // @@ -26,21 +26,34 @@ int main () deallog.attach(logfile); deallog.threshold_double(1.e-10); - ParameterHandler prm; - prm.enter_subsection ("Testing"); - prm.declare_entry ("Function", - "a", - Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h"))); - prm.leave_subsection (); - - prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_02.prm"); - - std::string list; - prm.enter_subsection ("Testing"); - list = prm.get ("Function"); - prm.leave_subsection (); - - deallog << list << std::endl; + for (unsigned int i = 0; i < 2; ++i) + { + ParameterHandler prm; + prm.enter_subsection ("Testing"); + prm.declare_entry ("Function", + "a", + Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h"))); + prm.leave_subsection (); + + // test both relevant read_input functions + if (i == 0) + { + prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_02.prm"); + } + else + { + std::ifstream input_stream + (SOURCE_DIR "/prm/parameter_handler_backslash_02.prm"); + prm.read_input(input_stream); + } + + std::string list; + prm.enter_subsection ("Testing"); + list = prm.get ("Function"); + prm.leave_subsection (); + + deallog << list << std::endl; + } return 0; } diff --git a/tests/bits/parameter_handler_backslash_02.output b/tests/bits/parameter_handler_backslash_02.output index 7e7203d2cd..0c39df8770 100644 --- a/tests/bits/parameter_handler_backslash_02.output +++ b/tests/bits/parameter_handler_backslash_02.output @@ -1,2 +1,3 @@ DEAL::a,b,c +DEAL::a,b,c diff --git a/tests/bits/parameter_handler_backslash_03.cc b/tests/bits/parameter_handler_backslash_03.cc index 99e59faa09..3b205e7be0 100644 --- a/tests/bits/parameter_handler_backslash_03.cc +++ b/tests/bits/parameter_handler_backslash_03.cc @@ -1,6 +1,6 @@ // --------------------------------------------------------------------- // -// Copyright (C) 2003 - 2014 by the deal.II authors +// Copyright (C) 2003 - 2016 by the deal.II authors // // This file is part of the deal.II library. // @@ -26,21 +26,35 @@ int main () deallog.attach(logfile); deallog.threshold_double(1.e-10); - ParameterHandler prm; - prm.enter_subsection ("Testing"); - prm.declare_entry ("Function", - "a", - Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h"))); - prm.leave_subsection (); - - prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_03.prm"); - - std::string list; - prm.enter_subsection ("Testing"); - list = prm.get ("Function"); - prm.leave_subsection (); - - deallog << list << std::endl; + for (unsigned int i = 0; i < 2; ++i) + { + ParameterHandler prm; + prm.enter_subsection ("Testing"); + prm.declare_entry ("Function", + "a", + Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h"))); + prm.leave_subsection (); + + // test both relevant read_input functions + if (i == 0) + { + prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_03.prm"); + } + else + { + std::ifstream input_stream + (SOURCE_DIR "/prm/parameter_handler_backslash_03.prm"); + prm.read_input(input_stream); + } + + + std::string list; + prm.enter_subsection ("Testing"); + list = prm.get ("Function"); + prm.leave_subsection (); + + deallog << list << std::endl; + } return 0; } diff --git a/tests/bits/parameter_handler_backslash_03.expect=diff.output b/tests/bits/parameter_handler_backslash_03.expect=diff.output index 9eb091f67d..5c8ecde2ba 100644 --- a/tests/bits/parameter_handler_backslash_03.expect=diff.output +++ b/tests/bits/parameter_handler_backslash_03.expect=diff.output @@ -1,2 +1,3 @@ DEAL::a, b, c +DEAL::a, b, c diff --git a/tests/bits/parameter_handler_backslash_04.cc b/tests/bits/parameter_handler_backslash_04.cc index 4b8e8f9037..92fe3fe89a 100644 --- a/tests/bits/parameter_handler_backslash_04.cc +++ b/tests/bits/parameter_handler_backslash_04.cc @@ -1,6 +1,6 @@ // --------------------------------------------------------------------- // -// Copyright (C) 2003 - 2014 by the deal.II authors +// Copyright (C) 2003 - 2016 by the deal.II authors // // This file is part of the deal.II library. // @@ -26,21 +26,35 @@ int main () deallog.attach(logfile); deallog.threshold_double(1.e-10); - ParameterHandler prm; - prm.enter_subsection ("Testing"); - prm.declare_entry ("Function", - "a", - Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h"))); - prm.leave_subsection (); - - prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_04.prm"); - - std::string list; - prm.enter_subsection ("Testing"); - list = prm.get ("Function"); - prm.leave_subsection (); - - deallog << list << std::endl; + for (unsigned int i = 0; i < 2; ++i) + { + ParameterHandler prm; + prm.enter_subsection ("Testing"); + prm.declare_entry ("Function", + "a", + Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h"))); + prm.leave_subsection (); + + // test both relevant read_input functions + if (i == 0) + { + prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_04.prm"); + } + else + { + std::ifstream input_stream + (SOURCE_DIR "/prm/parameter_handler_backslash_04.prm"); + prm.read_input(input_stream); + } + + + std::string list; + prm.enter_subsection ("Testing"); + list = prm.get ("Function"); + prm.leave_subsection (); + + deallog << list << std::endl; + } return 0; } diff --git a/tests/bits/parameter_handler_backslash_04.expect=diff.output b/tests/bits/parameter_handler_backslash_04.expect=diff.output index 9eb091f67d..5c8ecde2ba 100644 --- a/tests/bits/parameter_handler_backslash_04.expect=diff.output +++ b/tests/bits/parameter_handler_backslash_04.expect=diff.output @@ -1,2 +1,3 @@ DEAL::a, b, c +DEAL::a, b, c diff --git a/tests/bits/parameter_handler_backslash_05.cc b/tests/bits/parameter_handler_backslash_05.cc index c34a71c2c0..cd0b010ff7 100644 --- a/tests/bits/parameter_handler_backslash_05.cc +++ b/tests/bits/parameter_handler_backslash_05.cc @@ -1,6 +1,6 @@ // --------------------------------------------------------------------- // -// Copyright (C) 2003 - 2014 by the deal.II authors +// Copyright (C) 2003 - 2016 by the deal.II authors // // This file is part of the deal.II library. // @@ -26,27 +26,41 @@ int main () deallog.attach(logfile); deallog.threshold_double(1.e-10); - ParameterHandler prm; - prm.enter_subsection ("Testing"); - prm.declare_entry ("Function_1", - "a", - Patterns::List(Patterns::Selection("a|b|c"))); - prm.declare_entry ("Function_2", - "d", - Patterns::List(Patterns::Selection("d|e|f"))); - prm.leave_subsection (); - - prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_05.prm"); - - std::string list_1; - std::string list_2; - prm.enter_subsection ("Testing"); - list_1 = prm.get ("Function_1"); - list_2 = prm.get ("Function_2"); - prm.leave_subsection (); - - deallog << list_1 << std::endl; - deallog << list_2 << std::endl; + for (unsigned int i = 0; i < 2; ++i) + { + ParameterHandler prm; + prm.enter_subsection ("Testing"); + prm.declare_entry ("Function_1", + "a", + Patterns::List(Patterns::Selection("a|b|c"))); + prm.declare_entry ("Function_2", + "d", + Patterns::List(Patterns::Selection("d|e|f"))); + prm.leave_subsection (); + + + // test both relevant read_input functions + if (i == 0) + { + prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_05.prm"); + } + else + { + std::ifstream input_stream + (SOURCE_DIR "/prm/parameter_handler_backslash_05.prm"); + prm.read_input(input_stream); + } + + std::string list_1; + std::string list_2; + prm.enter_subsection ("Testing"); + list_1 = prm.get ("Function_1"); + list_2 = prm.get ("Function_2"); + prm.leave_subsection (); + + deallog << list_1 << std::endl; + deallog << list_2 << std::endl; + } return 0; } diff --git a/tests/bits/parameter_handler_backslash_05.expect=diff.output b/tests/bits/parameter_handler_backslash_05.expect=diff.output index 5902adc93b..ab2fb7d59e 100644 --- a/tests/bits/parameter_handler_backslash_05.expect=diff.output +++ b/tests/bits/parameter_handler_backslash_05.expect=diff.output @@ -1,3 +1,5 @@ DEAL::a, b, c DEAL::d, e, f +DEAL::a, b, c +DEAL::d, e, f -- 2.39.5