17 #include <deal.II/base/logstream.h> 18 #include <deal.II/base/memory_consumption.h> 19 #include <deal.II/base/parameter_handler.h> 20 #include <deal.II/base/path_search.h> 21 #include <deal.II/base/utilities.h> 23 #include <boost/io/ios_state.hpp> 24 #include <boost/property_tree/json_parser.hpp> 25 #include <boost/property_tree/ptree.hpp> 26 #include <boost/property_tree/xml_parser.hpp> 39 DEAL_II_NAMESPACE_OPEN
43 : entries(new
boost::property_tree::ptree())
50 mangle(
const std::string &s)
59 const bool mangle_whole_string = (s ==
"value");
64 for (
unsigned int i = 0; i < s.size(); ++i)
66 static const std::string allowed_characters(
67 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
69 if ((!mangle_whole_string) &&
70 (allowed_characters.find(s[i]) != std::string::npos))
75 static const char hex[16] = {
'0',
91 u.push_back(hex[static_cast<unsigned char>(s[i]) / 16]);
92 u.push_back(hex[static_cast<unsigned char>(s[i]) % 16]);
102 demangle(
const std::string &s)
107 for (
unsigned int i = 0; i < s.size(); ++i)
113 ExcMessage(
"Trying to demangle an invalid string."));
223 u.push_back(static_cast<char>(c));
237 is_parameter_node(
const boost::property_tree::ptree &p)
239 return static_cast<bool>(p.get_optional<std::string>(
"value"));
248 is_alias_node(
const boost::property_tree::ptree &p)
250 return static_cast<bool>(p.get_optional<std::string>(
"alias"));
260 if (subsection_path.size() > 0)
262 std::string p = mangle(subsection_path[0]);
263 for (
unsigned int i = 1; i < subsection_path.size(); ++i)
266 p += mangle(subsection_path[i]);
287 if (path.empty() ==
false)
290 path += mangle(name);
299 const std::string &filename,
300 const std::string &last_line)
307 std::string input_line;
308 std::string fully_concatenated_line;
309 bool is_concatenated =
false;
313 unsigned int current_line_n = 0;
314 unsigned int current_logical_line_n = 0;
328 auto scan_line_or_cleanup = [
this,
329 &saved_path](
const std::string &line,
330 const std::string &filename,
331 const unsigned int line_number) {
346 while (std::getline(input, input_line))
349 if (!is_concatenated)
350 current_logical_line_n = current_line_n;
357 if (last_line.length() != 0 && input_line == last_line)
362 if (input_line.length() != 0 &&
363 input_line.find_last_of(
'\\') == input_line.length() - 1)
365 input_line.erase(input_line.length() - 1);
366 is_concatenated =
true;
368 fully_concatenated_line += input_line;
372 else if (is_concatenated)
374 fully_concatenated_line += input_line;
375 is_concatenated =
false;
381 fully_concatenated_line = input_line;
384 if (!is_concatenated)
386 scan_line_or_cleanup(fully_concatenated_line,
388 current_logical_line_n);
390 fully_concatenated_line.clear();
398 scan_line_or_cleanup(fully_concatenated_line, filename, current_line_n);
402 std::stringstream paths_message;
403 if (saved_path.size() > 0)
405 paths_message <<
"Path before loading input:\n";
408 paths_message << std::setw(i * 2 + 4) <<
" " 409 <<
"subsection " << saved_path[i] <<
'\n';
411 paths_message <<
"Current path:\n";
414 paths_message << std::setw(i * 2 + 4) <<
" " 430 const std::string &last_line)
434 std::string openname = search.
find(filename);
435 std::ifstream file_stream(openname.c_str());
443 const std::string &last_line)
445 std::istringstream input_stream(s);
446 parse_input(input_stream,
"input string", last_line);
459 read_xml_recursively(
460 const boost::property_tree::ptree &source,
461 const std::string & current_path,
463 const std::vector<std::unique_ptr<const Patterns::PatternBase>> &
patterns,
464 boost::property_tree::ptree &destination)
466 for (boost::property_tree::ptree::const_iterator p = source.begin();
471 if (p->second.get_optional<std::string>(
"value"))
475 const std::string full_path =
476 (current_path ==
"" ? p->first :
477 current_path + path_separator + p->first);
479 const std::string new_value = p->second.get<std::string>(
"value");
480 AssertThrow(destination.get_optional<std::string>(full_path) &&
481 destination.get_optional<std::string>(
482 full_path + path_separator +
"value"),
487 const unsigned int pattern_index = destination.get<
unsigned int>(
488 full_path + path_separator +
"pattern");
495 patterns[pattern_index]->description()));
498 destination.put(full_path + path_separator +
"value", new_value);
505 else if (p->second.get_optional<std::string>(
"alias"))
514 read_xml_recursively(p->second,
515 (current_path ==
"" ?
517 current_path + path_separator + p->first),
536 boost::property_tree::ptree single_node_tree;
539 read_xml(in, single_node_tree);
543 AssertThrow(single_node_tree.get_optional<std::string>(
"ParameterHandler"),
545 "called \"ParameterHandler\"."));
547 const std::size_t n_top_level_elements =
548 std::distance(single_node_tree.begin(), single_node_tree.end());
549 if (n_top_level_elements != 1)
551 std::ostringstream top_level_message;
552 top_level_message <<
"The ParameterHandler input parser found " 553 << n_top_level_elements
554 <<
" top level elements while reading\n " 555 <<
" an XML format input file, but there should be" 556 <<
" exactly one top level element.\n" 557 <<
" The top level elements are:\n";
559 unsigned int entry_n = 0;
560 for (boost::property_tree::ptree::iterator it = single_node_tree.begin();
561 it != single_node_tree.end();
566 << (entry_n != n_top_level_elements - 1 ?
"\n" :
"");
575 const boost::property_tree::ptree &my_entries =
576 single_node_tree.get_child(
"ParameterHandler");
587 boost::property_tree::ptree node_tree;
590 read_json(in, node_tree);
602 entries = std_cxx14::make_unique<boost::property_tree::ptree>();
609 const std::string & default_value,
611 const std::string & documentation)
623 static_cast<unsigned int>(
patterns.size() - 1));
634 "pattern_description",
647 const std::string & entry,
648 const std::function<
void(
const std::string &)> &action)
653 boost::optional<std::string> current_actions =
662 const std::string all_actions =
663 current_actions.get() +
"," +
674 const std::string default_value =
entries->get<std::string>(
676 action(default_value);
683 const std::string &alias_name,
684 const bool alias_is_deprecated)
689 ExcMessage(
"You are trying to declare an alias entry <" + alias_name +
690 "> that references an entry <" + existing_entry_name +
691 ">, but the latter does not exist."));
697 ExcMessage(
"You are trying to declare an alias entry <" + alias_name +
698 "> that references an entry <" + existing_entry_name +
699 ">, but the latter does not seem to be a " 700 "parameter declaration."));
710 ExcMessage(
"You are trying to declare an alias entry <" +
712 "> but a non-alias entry already exists in this " 713 "subsection (i.e., there is either a preexisting " 714 "further subsection, or a parameter entry, with " 715 "the same name as the alias)."));
720 "You are trying to declare an alias entry <" + alias_name +
721 "> but an alias entry already exists in this " 722 "subsection and this existing alias references a " 723 "different parameter entry. Specifically, " 724 "you are trying to reference the entry <" +
725 existing_entry_name +
726 "> whereas the existing alias references " 734 existing_entry_name);
736 "deprecation_status",
737 (alias_is_deprecated ?
"true" :
"false"));
748 boost::property_tree::ptree());
774 if (boost::optional<std::string> value =
entries->get_optional<std::string>(
796 ExcMessage(
"Can't convert the parameter value <" +
797 get(entry_string) +
"> for entry <" +
798 entry_string +
" to an integer."));
815 ExcMessage(
"Can't convert the parameter value <" +
816 get(entry_string) +
"> for entry <" +
818 " to a double precision variable."));
828 const std::string s =
get(entry_string);
830 AssertThrow((s ==
"true") || (s ==
"false") || (s ==
"yes") || (s ==
"no"),
831 ExcMessage(
"Can't convert the parameter value <" +
832 get(entry_string) +
"> for entry <" + entry_string +
834 if (s ==
"true" || s ==
"yes")
844 const std::string &new_value)
858 const unsigned int pattern_index =
864 "pattern_description")));
868 const boost::optional<std::string> action_indices_as_string =
870 if (action_indices_as_string)
874 for (
unsigned int index : action_indices)
875 if (
actions.size() >= index + 1)
891 set(entry_string, std::string(new_value));
898 std::ostringstream s;
899 s << std::setprecision(16);
904 set(entry_string, s.str());
911 const long int & new_value)
913 std::ostringstream s;
918 set(entry_string, s.str());
928 set(entry_string, (new_value ?
"true" :
"false"));
943 boost::io::ios_flags_saver restore_flags(out);
944 boost::io::basic_ios_fill_saver<char> restore_fill_state(out);
961 boost::property_tree::ptree single_node_tree;
962 single_node_tree.add_child(
"ParameterHandler", *
entries);
964 write_xml(out, single_node_tree);
978 out <<
"# Listing of Parameters" << std::endl
979 <<
"# ---------------------" << std::endl;
983 out <<
"\\subsection{Global parameters}" << std::endl;
984 out <<
"\\label{parameters:global}" << std::endl;
985 out << std::endl << std::endl;
989 out <<
"Listing of Parameters:" << std::endl << std::endl;
1001 std::vector<std::string>(),
1013 const std::vector<std::string> &target_subsection_path,
1015 const unsigned int indent_level,
1016 std::ostream & out)
const 1023 const boost::property_tree::ptree ¤t_section =
1026 unsigned int overall_indent_level = indent_level;
1040 std::size_t longest_name = 0;
1041 std::size_t longest_value = 0;
1042 for (boost::property_tree::ptree::const_iterator p =
1043 current_section.begin();
1044 p != current_section.end();
1046 if (is_parameter_node(p->second) ==
true)
1049 std::max(longest_name, demangle(p->first).length());
1051 std::max(longest_value,
1052 p->second.get<std::string>(
"value").length());
1057 bool first_entry =
true;
1058 for (boost::property_tree::ptree::const_assoc_iterator p =
1059 current_section.ordered_begin();
1060 p != current_section.not_found();
1062 if (is_parameter_node(p->second) ==
true)
1064 const std::string value = p->second.get<std::string>(
"value");
1071 if ((style ==
Text) &&
1072 !p->second.get<std::string>(
"documentation").empty())
1074 if (first_entry ==
false)
1077 first_entry =
false;
1079 const std::vector<std::string> doc_lines =
1081 p->second.get<std::string>(
"documentation"),
1082 78 - overall_indent_level * 2 - 2);
1084 for (
unsigned int i = 0; i < doc_lines.size(); ++i)
1085 out << std::setw(overall_indent_level * 2) <<
"" 1086 <<
"# " << doc_lines[i] <<
'\n';
1092 out << std::setw(overall_indent_level * 2) <<
"" 1093 <<
"set " << demangle(p->first)
1094 << std::setw(longest_name - demangle(p->first).length() + 1)
1100 if ((style ==
Text) &&
1101 value != p->second.get<std::string>(
"default_value"))
1103 out << std::setw(longest_value - value.length() + 1) <<
' ' 1106 << p->second.get<std::string>(
"default_value");
1117 auto escape = [](
const std::string &input) {
1118 return Patterns::internal::escape(input,
1124 bool parameters_exist_here =
false;
1125 for (boost::property_tree::ptree::const_assoc_iterator p =
1126 current_section.ordered_begin();
1127 p != current_section.not_found();
1129 if ((is_parameter_node(p->second) ==
true) ||
1130 (is_alias_node(p->second) ==
true))
1132 parameters_exist_here =
true;
1136 if (parameters_exist_here)
1138 out <<
"\\begin{itemize}" <<
'\n';
1142 for (boost::property_tree::ptree::const_assoc_iterator p =
1143 current_section.ordered_begin();
1144 p != current_section.not_found();
1146 if (is_parameter_node(p->second) ==
true)
1148 const std::string value =
1149 p->second.get<std::string>(
"value");
1152 out <<
"\\item {\\it Parameter name:} {\\tt " 1153 << escape(demangle(p->first)) <<
"}\n" 1154 <<
"\\phantomsection";
1157 std::string label =
"parameters:";
1158 for (
unsigned int i = 0;
1159 i < target_subsection_path.size();
1162 label.append(mangle(target_subsection_path[i]));
1165 label.append(p->first);
1168 if (label.find(
"_20") != std::string::npos)
1172 out <<
"\\label{" << label <<
"}\n";
1176 out <<
"\\index[prmindex]{" << escape(demangle(p->first))
1178 out <<
"\\index[prmindexfull]{";
1179 for (
unsigned int i = 0; i < target_subsection_path.size();
1181 out << escape(target_subsection_path[i]) <<
"!";
1182 out << escape(demangle(p->first)) <<
"}\n";
1185 out <<
"{\\it Value:} " << escape(value) <<
"\n\n" 1187 <<
"{\\it Default:} " 1188 << escape(p->second.get<std::string>(
"default_value"))
1194 if (!p->second.get<std::string>(
"documentation").empty())
1195 out <<
"{\\it Description:} " 1196 << p->second.get<std::string>(
"documentation")
1202 const unsigned int pattern_index =
1203 p->second.get<
unsigned int>(
"pattern");
1204 const std::string desc_str =
1205 patterns[pattern_index]->description(
1207 out <<
"{\\it Possible values:} " << desc_str <<
'\n';
1209 else if (is_alias_node(p->second) ==
true)
1211 const std::string alias =
1212 p->second.get<std::string>(
"alias");
1215 out <<
"\\item {\\it Parameter name:} {\\tt " 1216 << escape(demangle(p->first)) <<
"}\n" 1217 <<
"\\phantomsection";
1220 std::string label =
"parameters:";
1221 for (
unsigned int i = 0;
1222 i < target_subsection_path.size();
1225 label.append(mangle(target_subsection_path[i]));
1228 label.append(p->first);
1231 if (label.find(
"_20") != std::string::npos)
1235 out <<
"\\label{" << label <<
"}\n";
1239 out <<
"\\index[prmindex]{" << escape(demangle(p->first))
1241 out <<
"\\index[prmindexfull]{";
1242 for (
unsigned int i = 0; i < target_subsection_path.size();
1244 out << escape(target_subsection_path[i]) <<
"!";
1245 out << escape(demangle(p->first)) <<
"}\n";
1249 <<
"This parameter is an alias for the parameter ``\\texttt{" 1250 << escape(alias) <<
"}''." 1251 << (p->second.get<std::string>(
"deprecation_status") ==
1253 " Its use is deprecated." :
1258 out <<
"\\end{itemize}" <<
'\n';
1268 std::size_t longest_name = 0;
1269 for (boost::property_tree::ptree::const_iterator p =
1270 current_section.begin();
1271 p != current_section.end();
1273 if (is_parameter_node(p->second) ==
true)
1275 std::max(longest_name, demangle(p->first).length());
1279 for (boost::property_tree::ptree::const_assoc_iterator p =
1280 current_section.ordered_begin();
1281 p != current_section.not_found();
1283 if (is_parameter_node(p->second) ==
true)
1286 out << std::setw(overall_indent_level * 2) <<
"" 1287 <<
"set " << demangle(p->first)
1288 << std::setw(longest_name - demangle(p->first).length() + 1)
1293 const unsigned int pattern_index =
1294 p->second.get<
unsigned int>(
"pattern");
1295 const std::string full_desc_str =
1296 patterns[pattern_index]->description(
1298 const std::vector<std::string> description_str =
1300 full_desc_str, 78 - overall_indent_level * 2 - 2,
'|');
1301 if (description_str.size() > 1)
1304 for (
unsigned int i = 0; i < description_str.size(); ++i)
1305 out << std::setw(overall_indent_level * 2 + 6) <<
"" 1306 << description_str[i] <<
'\n';
1308 else if (description_str.empty() ==
false)
1309 out <<
" " << description_str[0] <<
'\n';
1314 if (p->second.get<std::string>(
"documentation").length() != 0)
1315 out << std::setw(overall_indent_level * 2 + longest_name + 10)
1317 <<
"(" << p->second.get<std::string>(
"documentation")
1332 unsigned int n_parameters = 0;
1333 unsigned int n_sections = 0;
1334 for (boost::property_tree::ptree::const_iterator p =
1335 current_section.begin();
1336 p != current_section.end();
1338 if (is_parameter_node(p->second) ==
true)
1340 else if (is_alias_node(p->second) ==
false)
1349 for (boost::property_tree::ptree::const_assoc_iterator p =
1350 current_section.ordered_begin();
1351 p != current_section.not_found();
1353 if ((is_parameter_node(p->second) ==
false) &&
1354 (is_alias_node(p->second) ==
false))
1362 out << std::setw(overall_indent_level * 2) <<
"" 1363 <<
"subsection " << demangle(p->first) <<
'\n';
1368 auto escape = [](
const std::string &input) {
1369 return Patterns::internal::escape(
1373 out <<
'\n' <<
"\\subsection{Parameters in section \\tt ";
1377 for (
unsigned int i = 0; i < target_subsection_path.size(); ++i)
1378 out << escape(target_subsection_path[i]) <<
"/";
1379 out << escape(demangle(p->first));
1382 out <<
"\\label{parameters:";
1383 for (
unsigned int i = 0; i < target_subsection_path.size(); ++i)
1384 out << mangle(target_subsection_path[i]) <<
"/";
1385 out << p->first <<
"}";
1397 const std::string subsection = demangle(p->first);
1398 std::vector<std::string> directory_path = target_subsection_path;
1399 directory_path.emplace_back(subsection);
1403 overall_indent_level + 1,
1411 out << std::setw(overall_indent_level * 2) <<
"" 1417 if (overall_indent_level == 0)
1427 out << std::setw(overall_indent_level * 2) <<
"" 1451 const unsigned int indent_level,
1452 const bool include_top_level_elements)
1456 const boost::property_tree::ptree ¤t_section =
1459 unsigned int overall_indent_level = indent_level;
1465 if (include_top_level_elements)
1476 boost::property_tree::ptree single_node_tree;
1483 single_node_tree.add_child(
"ParameterHandler", *
entries);
1487 std::string path(
"ParameterHandler");
1489 single_node_tree.add_child(path,
1490 boost::property_tree::ptree());
1493 single_node_tree.add_child(path, current_section);
1496 write_xml(out, single_node_tree);
1510 out << std::setw(overall_indent_level * 2) <<
"" 1513 overall_indent_level += 1;
1520 std::size_t longest_name = 0;
1521 for (boost::property_tree::ptree::const_iterator p =
1522 current_section.begin();
1523 p != current_section.end();
1525 if (is_parameter_node(p->second) ==
true)
1527 std::max(longest_name, demangle(p->first).length());
1531 std::size_t longest_value = 0;
1532 for (boost::property_tree::ptree::const_iterator p =
1533 current_section.begin();
1534 p != current_section.end();
1536 if (is_parameter_node(p->second) ==
true)
1538 std::max(longest_value,
1539 p->second.get<std::string>(
"value").length());
1544 bool first_entry =
true;
1545 for (boost::property_tree::ptree::const_assoc_iterator p =
1546 current_section.ordered_begin();
1547 p != current_section.not_found();
1549 if (is_parameter_node(p->second) ==
true)
1551 const std::string value = p->second.get<std::string>(
"value");
1558 if ((!(style & 128)) &&
1559 !p->second.get<std::string>(
"documentation").empty())
1561 if (first_entry ==
false)
1564 first_entry =
false;
1566 const std::vector<std::string> doc_lines =
1568 p->second.get<std::string>(
"documentation"),
1569 78 - overall_indent_level * 2 - 2);
1571 for (
unsigned int i = 0; i < doc_lines.size(); ++i)
1572 out << std::setw(overall_indent_level * 2) <<
"" 1573 <<
"# " << doc_lines[i] << std::endl;
1579 out << std::setw(overall_indent_level * 2) <<
"" 1580 <<
"set " << demangle(p->first)
1581 << std::setw(longest_name - demangle(p->first).length() + 1)
1587 if ((!(style & 64)) &&
1588 value != p->second.get<std::string>(
"default_value"))
1590 out << std::setw(longest_value - value.length() + 1) <<
' ' 1593 << p->second.get<std::string>(
"default_value");
1604 auto escape = [](
const std::string &input) {
1605 return Patterns::internal::escape(input,
1611 bool parameters_exist_here =
false;
1612 for (boost::property_tree::ptree::const_assoc_iterator p =
1613 current_section.ordered_begin();
1614 p != current_section.not_found();
1616 if ((is_parameter_node(p->second) ==
true) ||
1617 (is_alias_node(p->second) ==
true))
1619 parameters_exist_here =
true;
1623 if (parameters_exist_here)
1625 out <<
"\\begin{itemize}" << std::endl;
1629 for (boost::property_tree::ptree::const_assoc_iterator p =
1630 current_section.ordered_begin();
1631 p != current_section.not_found();
1633 if (is_parameter_node(p->second) ==
true)
1635 const std::string value =
1636 p->second.get<std::string>(
"value");
1639 out <<
"\\item {\\it Parameter name:} {\\tt " 1640 << escape(demangle(p->first)) <<
"}\n" 1641 <<
"\\phantomsection\\label{parameters:";
1645 out <<
"}\n\n" << std::endl;
1647 out <<
"\\index[prmindex]{" << escape(demangle(p->first))
1649 out <<
"\\index[prmindexfull]{";
1652 out << escape(demangle(p->first)) <<
"}\n";
1655 out <<
"{\\it Value:} " << escape(value) <<
"\n\n" 1657 <<
"{\\it Default:} " 1658 << escape(p->second.get<std::string>(
"default_value"))
1663 if (!p->second.get<std::string>(
"documentation").empty())
1664 out <<
"{\\it Description:} " 1665 << p->second.get<std::string>(
"documentation")
1670 const unsigned int pattern_index =
1671 p->second.get<
unsigned int>(
"pattern");
1672 const std::string desc_str =
1673 patterns[pattern_index]->description(
1675 out <<
"{\\it Possible values:} " << desc_str << std::endl;
1677 else if (is_alias_node(p->second) ==
true)
1679 const std::string alias =
1680 p->second.get<std::string>(
"alias");
1683 out <<
"\\item {\\it Parameter name:} {\\tt " 1684 << escape(demangle(p->first)) <<
"}\n" 1685 <<
"\\phantomsection\\label{parameters:";
1689 out <<
"}\n\n" << std::endl;
1691 out <<
"\\index[prmindex]{" << escape(demangle(p->first))
1693 out <<
"\\index[prmindexfull]{";
1696 out << escape(demangle(p->first)) <<
"}\n";
1700 <<
"This parameter is an alias for the parameter ``\\texttt{" 1701 << escape(alias) <<
"}''." 1702 << (p->second.get<std::string>(
"deprecation_status") ==
1704 " Its use is deprecated." :
1709 out <<
"\\end{itemize}" << std::endl;
1721 out << std::setw(overall_indent_level * 2) <<
"" 1724 overall_indent_level += 1;
1729 std::size_t longest_name = 0;
1730 for (boost::property_tree::ptree::const_iterator p =
1731 current_section.begin();
1732 p != current_section.end();
1734 if (is_parameter_node(p->second) ==
true)
1736 std::max(longest_name, demangle(p->first).length());
1740 for (boost::property_tree::ptree::const_assoc_iterator p =
1741 current_section.ordered_begin();
1742 p != current_section.not_found();
1744 if (is_parameter_node(p->second) ==
true)
1747 out << std::setw(overall_indent_level * 2) <<
"" 1748 <<
"set " << demangle(p->first)
1749 << std::setw(longest_name - demangle(p->first).length() + 1)
1754 const unsigned int pattern_index =
1755 p->second.get<
unsigned int>(
"pattern");
1756 const std::string full_desc_str =
1757 patterns[pattern_index]->description(
1759 const std::vector<std::string> description_str =
1761 full_desc_str, 78 - overall_indent_level * 2 - 2,
'|');
1762 if (description_str.size() > 1)
1765 for (
unsigned int i = 0; i < description_str.size(); ++i)
1766 out << std::setw(overall_indent_level * 2 + 6) <<
"" 1767 << description_str[i] << std::endl;
1769 else if (description_str.empty() ==
false)
1770 out <<
" " << description_str[0] << std::endl;
1775 if (p->second.get<std::string>(
"documentation").length() != 0)
1776 out << std::setw(overall_indent_level * 2 + longest_name + 10)
1778 <<
"(" << p->second.get<std::string>(
"documentation")
1779 <<
")" << std::endl;
1794 unsigned int n_parameters = 0;
1795 unsigned int n_sections = 0;
1796 for (boost::property_tree::ptree::const_iterator p =
1797 current_section.begin();
1798 p != current_section.end();
1800 if (is_parameter_node(p->second) ==
true)
1802 else if (is_alias_node(p->second) ==
false)
1805 if ((style !=
Description) && (!(style & 128)) && (n_parameters != 0) &&
1807 out << std::endl << std::endl;
1810 for (boost::property_tree::ptree::const_assoc_iterator p =
1811 current_section.ordered_begin();
1812 p != current_section.not_found();
1814 if ((is_parameter_node(p->second) ==
false) &&
1815 (is_alias_node(p->second) ==
false))
1823 out << std::setw(overall_indent_level * 2) <<
"" 1824 <<
"subsection " << demangle(p->first) << std::endl;
1828 auto escape = [](
const std::string &input) {
1829 return Patterns::internal::escape(
1834 <<
"\\subsection{Parameters in section \\tt ";
1840 out << escape(demangle(p->first));
1842 out <<
"}" << std::endl;
1843 out <<
"\\label{parameters:";
1846 out << p->first <<
"}";
1866 out << std::setw(overall_indent_level * 2) <<
"" 1867 <<
"end" << std::endl
1872 if (overall_indent_level == 0)
1880 out << std::setw(overall_indent_level * 2) <<
"" 1881 <<
"end" << std::endl;
1904 overall_indent_level -= 1;
1905 out << std::setw(overall_indent_level * 2) <<
"" 1906 <<
"end" << std::endl;
1922 out.
push(
"parameters");
1934 const boost::property_tree::ptree ¤t_section =
1941 for (boost::property_tree::ptree::const_assoc_iterator p =
1942 current_section.ordered_begin();
1943 p != current_section.not_found();
1945 if (is_parameter_node(p->second) ==
true)
1946 out << demangle(p->first) <<
": " << p->second.get<std::string>(
"value")
1952 for (boost::property_tree::ptree::const_assoc_iterator p =
1953 current_section.ordered_begin();
1954 p != current_section.not_found();
1956 if (is_parameter_node(p->second) ==
false)
1958 out.
push(demangle(p->first));
1970 const std::string &input_filename,
1971 const unsigned int current_line_n)
1974 const std::string original_line = line;
1977 if (line.find(
'#') != std::string::npos)
1978 line.erase(line.find(
'#'), std::string::npos);
1981 while (line.find(
'\t') != std::string::npos)
1982 line.replace(line.find(
'\t'), 1,
" ");
1988 if (line.length() == 0)
1997 line.erase(0, std::string(
"subsection").length() + 1);
2016 while ((line.size() > 0) && (std::isspace(line[0])))
2023 "Invalid content after 'end' or 'END' statement."));
2027 "There is no subsection to leave here."));
2037 std::string::size_type pos = line.find(
'=');
2039 pos != std::string::npos,
2042 "Invalid format of 'set' or 'SET' statement."));
2046 std::string entry_value =
2055 "deprecation_status") ==
"true")
2057 std::cerr <<
"Warning in line <" << current_line_n
2058 <<
"> of file <" << input_filename
2059 <<
">: You are using the deprecated spelling <" 2060 << entry_name <<
"> of the parameter <" 2063 <<
">." << std::endl;
2080 if (entry_value.find(
'{') == std::string::npos)
2083 const unsigned int pattern_index =
2091 patterns[pattern_index]->description()));
2095 const boost::optional<std::string> action_indices_as_string =
2098 if (action_indices_as_string)
2100 std::vector<int> action_indices =
2102 action_indices_as_string.get()));
2103 for (
unsigned int index : action_indices)
2104 if (
actions.size() >= index + 1)
2118 (
"No entry with name <" + entry_name +
2119 "> was declared in the current subsection.")));
2128 while ((line.size() > 0) && (line[0] ==
' '))
2135 "The current line is an 'include' or " 2136 "'INCLUDE' statement, but it does not " 2137 "name a file for inclusion."));
2139 std::ifstream input(line.c_str());
2156 "could not be parsed: please check to " 2157 "make sure that the file is not missing a " 2158 "'set', 'include', 'subsection', or 'end' " 2180 for (
unsigned int j = 0; j <
patterns.size(); ++j)
2191 std::ostringstream o1, o2;
2193 write_json(o2, *prm2.
entries);
2194 return (o1.str() == o2.str());
2207 const std::string &filename,
2208 const std::string &last_line)
2224 for (
unsigned int run_no = 0; run_no <
n_branches; ++run_no)
2256 std::cerr <<
" The entry value" << std::endl
2258 <<
" for the entry named" << std::endl
2260 <<
" does not have the right number of entries for the " 2263 <<
" variant runs that will be performed." << std::endl;
2270 for (
unsigned int i = 0; i <
n_branches; ++i)
2279 const boost::property_tree::ptree ¤t_section =
2290 for (boost::property_tree::ptree::const_assoc_iterator p =
2291 current_section.ordered_begin();
2292 p != current_section.not_found();
2294 if (is_parameter_node(p->second) ==
true)
2296 const std::string value = p->second.get<std::string>(
"value");
2297 if (value.find(
'{') != std::string::npos)
2304 for (boost::property_tree::ptree::const_iterator p = current_section.begin();
2305 p != current_section.end();
2307 if (is_parameter_node(p->second) ==
false)
2320 unsigned int possibilities = 1;
2322 std::vector<Entry>::iterator choice;
2326 const unsigned int selection =
2327 (run_no / possibilities) % choice->different_values.size();
2328 std::string entry_value;
2330 entry_value = choice->different_values[selection];
2333 if (run_no >= choice->different_values.size())
2336 <<
"The given array for entry <" << choice->entry_name
2337 <<
"> does not contain enough elements! Taking empty string instead." 2342 entry_value = choice->different_values[run_no];
2354 set(choice->entry_name, entry_value);
2359 possibilities *= choice->different_values.size();
2378 const std::string & Name,
2379 const std::string & Value)
2382 , entry_value(Value)
2383 , type(
Entry::array)
2404 if (multiple[0] ==
'{')
2405 multiple.erase(0, 1);
2406 if (multiple[multiple.size() - 1] ==
'}')
2407 multiple.erase(multiple.size() - 1, 1);
2410 while (std::isspace(multiple[0]))
2411 multiple.erase(0, 1);
2412 while (std::isspace(multiple[multiple.size() - 1]))
2413 multiple.erase(multiple.size() - 1, 1);
2416 while (multiple.find(
" |") != std::string::npos)
2417 multiple.replace(multiple.find(
" |"), 2,
"|");
2418 while (multiple.find(
"| ") != std::string::npos)
2419 multiple.replace(multiple.find(
"| "), 2,
"|");
2421 while (multiple.find(
'|') != std::string::npos)
2424 prefix + std::string(multiple, 0, multiple.find(
'|')) + postfix);
2425 multiple.erase(0, multiple.find(
'|') + 1);
2432 if ((
entry_value.find(
"{{") != std::string::npos) &&
2450 DEAL_II_NAMESPACE_CLOSE
bool operator==(const ParameterHandler &prm2) const
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
std::vector< Entry > multiple_choices
static const char path_separator
static std::string collate_path_string(const std::vector< std::string > &subsection_path)
std::string get_current_full_path(const std::string &name) const
static::ExceptionBase & ExcInvalidEntryForPatternXML(std::string arg1, std::string arg2, std::string arg3)
static::ExceptionBase & ExcCannotOpenIncludeStatementFile(int arg1, std::string arg2, std::string arg3)
static::ExceptionBase & ExcIO()
virtual void run(ParameterHandler &prm)=0
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="") override
static::ExceptionBase & ExcEntryUndeclared(std::string arg1)
std::size_t memory_consumption() const
std::string trim(const std::string &input)
static::ExceptionBase & ExcUnbalancedSubsections(std::string arg1, std::string arg2)
void log_parameters(LogStream &out)
virtual std::unique_ptr< PatternBase > clone() const =0
void set(const std::string &entry_name, const std::string &new_value)
virtual void parse_input_from_json(std::istream &input)
void log_parameters_section(LogStream &out)
std::vector< std::string > subsection_path
#define AssertThrow(cond, exc)
std::string get(const std::string &entry_string) const
static::ExceptionBase & ExcValueDoesNotMatchPattern(std::string arg1, std::string arg2)
std::vector< std::string > subsection_path
double string_to_double(const std::string &s)
std::size_t memory_consumption() const
void init_branches_current_section()
void enter_subsection(const std::string &subsection)
virtual void parse_input_from_xml(std::istream &input)
static::ExceptionBase & ExcInvalidXMLParameterFile()
static::ExceptionBase & ExcMessage(std::string arg1)
virtual void create_new(const unsigned int run_no)=0
static::ExceptionBase & ExcCannotParseLine(int arg1, std::string arg2, std::string arg3)
std::ostream & print_parameters(std::ostream &out, const OutputStyle style) const
#define Assert(cond, exc)
bool match_at_string_start(const std::string &name, const std::string &pattern)
std::string get_current_path() const
std::unique_ptr< boost::property_tree::ptree > entries
void fill_entry_values(const unsigned int run_no)
virtual void parse_input_from_string(const char *s, const std::string &last_line="")
static::ExceptionBase & ExcAlreadyAtTopLevel()
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
std::string replace_in_string(const std::string &input, const std::string &from, const std::string &to)
std::vector< std::unique_ptr< const Patterns::PatternBase > > patterns
virtual bool match(const std::string &test_string) const =0
bool get_bool(const std::string &entry_name) const
std::string find(const std::string &filename, const char *open_mode="r")
std::vector< std::string > break_text_into_lines(const std::string &original_text, const unsigned int width, const char delimiter= ' ')
void push(const std::string &text)
virtual std::string description(const OutputStyle style=Machine) const =0
void add_action(const std::string &entry, const std::function< void(const std::string &value)> &action)
double get_double(const std::string &entry_name) const
void print_parameters_section(std::ostream &out, const OutputStyle style, const unsigned int indent_level, const bool include_top_level_elements=false)
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation=std::string())
int string_to_int(const std::string &s)
static::ExceptionBase & ExcNotImplemented()
std::vector< std::string > different_values
void scan_line(std::string line, const std::string &input_filename, const unsigned int current_line_n)
static::ExceptionBase & ExcInvalidEntryForPattern(int arg1, std::string arg2, std::string arg3, std::string arg4, std::string arg5)
std::vector< std::function< void(const std::string &)> > actions
void recursively_print_parameters(const std::vector< std::string > &target_subsection_path, const OutputStyle style, const unsigned int indent_level, std::ostream &out) const
static::ExceptionBase & ExcNoSubsection(int arg1, std::string arg2, std::string arg3)
void split_different_values()
void declare_alias(const std::string &existing_entry_name, const std::string &alias_name, const bool alias_is_deprecated=false)
std::size_t memory_consumption() const
long int get_integer(const std::string &entry_string) const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static::ExceptionBase & ExcInternalError()
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="")