Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ParmParse: Line Continuation #3437

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 22 additions & 45 deletions Src/Base/AMReX_ParmParse.H
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <filename>" 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 = <filename>" definition is special. Rather than just
// adding this entry to the database, it reads the contents of <filename>
// into the database.
//
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1052,37 +1060,6 @@ public:
//! Returns [prefix.]* parameters.
[[nodiscard]] static std::set<std::string> 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<PP_entry>;
static void appendTable(ParmParse::Table& tab);
Expand Down
36 changes: 21 additions & 15 deletions Src/Base/AMReX_ParmParse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
Loading