From ca4ca2e6963f3ca164fefa184397b12f311d8dfd Mon Sep 17 00:00:00 2001 From: Weiqun Zhang Date: Thu, 20 Jul 2023 18:18:33 -0700 Subject: [PATCH] ParmParse: Line Continuation In #3433, we added an option to disable multi-line support to avoid certain types of errors. Since multi-line support seems to be desirable feature, we add a new feature that uses `\` as line continuation. To avoid confusion, we have decided to stop supporting the old style of multi-line values and make it a runtime error. Hopefully it does not cause too much trouble for users. --- Src/Base/AMReX_ParmParse.H | 67 ++++++++++++------------------------ Src/Base/AMReX_ParmParse.cpp | 36 +++++++++++-------- 2 files changed, 43 insertions(+), 60 deletions(-) diff --git a/Src/Base/AMReX_ParmParse.H b/Src/Base/AMReX_ParmParse.H index 564ac25c3bf..01a0098333e 100644 --- a/Src/Base/AMReX_ParmParse.H +++ b/Src/Base/AMReX_ParmParse.H @@ -32,18 +32,24 @@ class IntVect; // // Comments in an input file include all text from a '#' character to the // end of the line. Here is an example input file: -// -// niter = 100 # niter is an integer -// title = "Double Wammy" # example of a string with spaces -// cell_size = 0.5 0.75 # cell spacing in each dimension -// plot.var = Density 1 10 # a list of values -// plot.var = Energy 5 12 # another list of values -// bigarray = 1 2 3 4 5 6 7 8 # first part of array -// 9 10 11 12 # continuation of bigarray -// test = apple "boy blue" 10 20 30 40 -// FILE = prob_file # insert contents of this "prob_file" here -// -// The "FILE = " definition is special. Rather than just +/* + niter = 100 # niter is an integer + title = "Double Wammy" # example of a string with spaces + cell_size = 0.5 0.75 # cell spacing in each dimension + plot.var = Density 1 10 # a list of values + plot.var = Energy 5 12 # another list of values + bigarray = 1 2 3 4 5 6 7 8 \ + 9 10 11 12 # continuation of bigarray + multi_line_string = "This is a + multi-line string." + test = apple "boy blue" 10 20 30 40 + FILE = prob_file # insert contents of this "prob_file" here +*/ +// For values spanning multiple lines, one must use '\' at the end of a line +// for continuation, otherwise it's a runtime error. Note that there must be +// at least one space before the continuation character `\`. Multiple lines +// inside a pair of double quotes are considered a single string containing +// '\n's. The "FILE = " definition is special. Rather than just // adding this entry to the database, it reads the contents of // into the database. // @@ -229,10 +235,12 @@ class IntVect; * * plot.var = Energy 5 12 * -* bigarray = 1 2 3 4 5 6 7 8 -* +* bigarray = 1 2 3 4 5 6 7 8 \ * 9 10 11 12 * +* multi_line_string = "This is a +* multi-line string." +* * aBox = ((0,0) (5,5)) * * test = apple "boy blue" 10 20 30 40 @@ -1052,37 +1060,6 @@ public: //! Returns [prefix.]* parameters. [[nodiscard]] static std::set getEntries (const std::string& prefix = std::string()); - /** - * \brief Control multi-line support - * - * By default, ParmParse supports multi-line values. For example, - \verbatim - plot_vars = dens vx vy vx - energy entropy - \endverbatim - * This can be disabled by calling this function setMultiLineSupport(false) - * before amrex::Initialize(). This can avoid errors in inputs like, - \verbatim - algo.current_deposition = direct - - # Enable galilean - psatd.use_default_v_galilean # Unfortunately we forgot = 1 - \endverbatim - * With multi-line support, this is equivalent to - \verbatim - algo.current_deposition = direct psatd.use_default_v_galilean - \endverbatim - * With multi-line support disabled, it will abort. Note that after - * multi-line support is disabled, one is still allowed to have - \verbatim - f = "x + y - + sin(z)" - \endverbatim - * because here what's inside the pair of double quotes is considered a - * single string. - */ - static void setMultiLineSupport (bool b); - struct PP_entry; using Table = std::list; static void appendTable(ParmParse::Table& tab); diff --git a/Src/Base/AMReX_ParmParse.cpp b/Src/Base/AMReX_ParmParse.cpp index a503922ee5a..8fb37dab408 100644 --- a/Src/Base/AMReX_ParmParse.cpp +++ b/Src/Base/AMReX_ParmParse.cpp @@ -34,17 +34,8 @@ static bool finalize_verbose = false; static bool finalize_verbose = true; #endif -namespace { - bool g_multi_line_support = true; -} - std::string const ParmParse::FileKeyword = "FILE"; -void ParmParse::setMultiLineSupport (bool b) -{ - g_multi_line_support = b; -} - // // Used by constructor to build table. // @@ -287,6 +278,21 @@ eat_garbage (const char*& str) if (*str == '\n') { ++num_linefeeds; } str++; } + else if ( *str == '\\' ) // '\' followed by a line break is continuation to next line + { + // Unfortunately, a line break has three variants, \r, \n, and \r\n. + if (*(str+1) == '\n') { + str += 2; + } else if (*(str+1) == '\r') { + if (*(str+2) == '\n') { + str += 3; + } else { + str += 2; + } + } else { + break; + } + } else { break; @@ -703,14 +709,14 @@ bldTable (const char*& str, } AMREX_FALLTHROUGH; case pEOF: - if (! g_multi_line_support && - std::accumulate(cur_linefeeds.begin(), cur_linefeeds.end(), int(0)) > 0) + if (std::accumulate(cur_linefeeds.begin(), cur_linefeeds.end(), int(0)) > 0) { std::string error_message("ParmParse: Multiple lines in "); error_message.append(cur_name).append(" ="); for (auto const& x : cur_list) { error_message.append(" ").append(x); } + error_message.append(". Must use \\ for line continuation."); amrex::Abort(error_message); } addDefn(cur_name,cur_list,tab); @@ -725,14 +731,14 @@ bldTable (const char*& str, tmp_str = cur_list.back(); cur_list.pop_back(); cur_linefeeds.pop_back(); - if (! g_multi_line_support && - std::accumulate(cur_linefeeds.begin(), cur_linefeeds.end(), int(0)) > 0) + if (std::accumulate(cur_linefeeds.begin(), cur_linefeeds.end(), int(0)) > 0) { std::string error_message("ParmParse: Multiple lines in "); error_message.append(cur_name).append(" ="); for (auto const& x : cur_list) { error_message.append(" ").append(x); } + error_message.append(". Must use \\ for line continuation."); amrex::Abort(error_message); } addDefn(cur_name, cur_list, tab); @@ -754,14 +760,14 @@ bldTable (const char*& str, tmp_str = cur_list.back(); cur_list.pop_back(); cur_linefeeds.pop_back(); - if (! g_multi_line_support && - std::accumulate(cur_linefeeds.begin(), cur_linefeeds.end(), int(0)) > 0) + if (std::accumulate(cur_linefeeds.begin(), cur_linefeeds.end(), int(0)) > 0) { std::string error_message("ParmParse: Multiple lines in "); error_message.append(cur_name).append(" ="); for (auto const& x : cur_list) { error_message.append(" ").append(x); } + error_message.append(". Must use \\ for line continuation."); amrex::Abort(error_message); } addDefn(cur_name,cur_list,tab);