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");
62 for (
const char c : s)
64 static const std::string allowed_characters(
65 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
67 if ((!mangle_whole_string) &&
68 (allowed_characters.find(c) != std::string::npos))
73 static const char hex[16] = {
'0',
89 u.push_back(hex[static_cast<unsigned char>(c) / 16]);
90 u.push_back(hex[static_cast<unsigned char>(c) % 16]);
100 demangle(
const std::string &s)
105 for (
unsigned int i = 0; i < s.size(); ++i)
111 ExcMessage(
"Trying to demangle an invalid string."));
221 u.push_back(static_cast<char>(c));
235 is_parameter_node(
const boost::property_tree::ptree &p)
237 return static_cast<bool>(p.get_optional<std::string>(
"value"));
246 is_alias_node(
const boost::property_tree::ptree &p)
248 return static_cast<bool>(p.get_optional<std::string>(
"alias"));
256 const std::vector<std::string> &subsection_path)
285 if (path.empty() ==
false)
288 path += mangle(name);
297 const std::vector<std::string> &sub_path,
298 const std::string & name)
const 301 if (path.empty() ==
false)
304 if (sub_path.empty() ==
false)
307 path += mangle(name);
316 const std::string &filename,
317 const std::string &last_line,
318 const bool skip_undefined)
325 std::string input_line;
326 std::string fully_concatenated_line;
327 bool is_concatenated =
false;
331 unsigned int current_line_n = 0;
332 unsigned int current_logical_line_n = 0;
346 auto scan_line_or_cleanup = [
this,
348 &saved_path](
const std::string &line,
349 const std::string &filename,
350 const unsigned int line_number) {
353 scan_line(line, filename, line_number, skip_undefined);
365 while (std::getline(input, input_line))
368 if (!is_concatenated)
369 current_logical_line_n = current_line_n;
376 if (last_line.length() != 0 && input_line == last_line)
381 if (input_line.length() != 0 &&
382 input_line.find_last_of(
'\\') == input_line.length() - 1)
384 input_line.erase(input_line.length() - 1);
385 is_concatenated =
true;
387 fully_concatenated_line += input_line;
391 else if (is_concatenated)
393 fully_concatenated_line += input_line;
394 is_concatenated =
false;
400 fully_concatenated_line = input_line;
403 if (!is_concatenated)
405 scan_line_or_cleanup(fully_concatenated_line,
407 current_logical_line_n);
409 fully_concatenated_line.clear();
417 scan_line_or_cleanup(fully_concatenated_line, filename, current_line_n);
421 std::stringstream paths_message;
422 if (saved_path.size() > 0)
424 paths_message <<
"Path before loading input:\n";
427 paths_message << std::setw(i * 2 + 4) <<
" " 428 <<
"subsection " << saved_path[i] <<
'\n';
430 paths_message <<
"Current path:\n";
433 paths_message << std::setw(i * 2 + 4) <<
" " 449 const std::string &last_line,
450 const bool skip_undefined)
454 std::string openname = search.
find(filename);
455 std::ifstream file_stream(openname.c_str());
456 parse_input(file_stream, filename, last_line, skip_undefined);
463 const std::string &last_line,
464 const bool skip_undefined)
466 std::istringstream input_stream(s);
467 parse_input(input_stream,
"input string", last_line, skip_undefined);
480 read_xml_recursively(
481 const boost::property_tree::ptree &source,
482 const std::string & current_path,
483 const char path_separator,
484 const std::vector<std::unique_ptr<const Patterns::PatternBase>> &patterns,
485 boost::property_tree::ptree &destination)
487 for (boost::property_tree::ptree::const_iterator p = source.begin();
492 if (p->second.get_optional<std::string>(
"value"))
496 const std::string full_path =
497 (current_path.empty() ? p->first :
498 current_path + path_separator + p->first);
500 const std::string new_value = p->second.get<std::string>(
"value");
501 AssertThrow(destination.get_optional<std::string>(full_path) &&
502 destination.get_optional<std::string>(
503 full_path + path_separator +
"value"),
508 const unsigned int pattern_index = destination.get<
unsigned int>(
509 full_path + path_separator +
"pattern");
510 AssertThrow(patterns[pattern_index]->match(new_value),
516 patterns[pattern_index]->description()));
519 destination.put(full_path + path_separator +
"value", new_value);
526 else if (p->second.get_optional<std::string>(
"alias"))
535 read_xml_recursively(p->second,
536 (current_path.empty() ?
538 current_path + path_separator + p->first),
557 boost::property_tree::ptree single_node_tree;
560 read_xml(in, single_node_tree);
564 AssertThrow(single_node_tree.get_optional<std::string>(
"ParameterHandler"),
566 "called \"ParameterHandler\"."));
568 const std::size_t n_top_level_elements =
569 std::distance(single_node_tree.begin(), single_node_tree.end());
570 if (n_top_level_elements != 1)
572 std::ostringstream top_level_message;
573 top_level_message <<
"The ParameterHandler input parser found " 574 << n_top_level_elements
575 <<
" top level elements while reading\n " 576 <<
" an XML format input file, but there should be" 577 <<
" exactly one top level element.\n" 578 <<
" The top level elements are:\n";
580 unsigned int entry_n = 0;
581 for (boost::property_tree::ptree::iterator it = single_node_tree.begin();
582 it != single_node_tree.end();
587 << (entry_n != n_top_level_elements - 1 ?
"\n" :
"");
596 const boost::property_tree::ptree &my_entries =
597 single_node_tree.get_child(
"ParameterHandler");
608 boost::property_tree::ptree node_tree;
611 read_json(in, node_tree);
623 entries = std_cxx14::make_unique<boost::property_tree::ptree>();
630 const std::string & default_value,
632 const std::string & documentation)
644 static_cast<unsigned int>(
patterns.size() - 1));
655 "pattern_description",
668 const std::string & entry,
669 const std::function<
void(
const std::string &)> &action)
674 boost::optional<std::string> current_actions =
683 const std::string all_actions =
684 current_actions.get() +
"," +
695 const std::string default_value =
entries->get<std::string>(
697 action(default_value);
704 const std::string &alias_name,
705 const bool alias_is_deprecated)
710 ExcMessage(
"You are trying to declare an alias entry <" + alias_name +
711 "> that references an entry <" + existing_entry_name +
712 ">, but the latter does not exist."));
718 ExcMessage(
"You are trying to declare an alias entry <" + alias_name +
719 "> that references an entry <" + existing_entry_name +
720 ">, but the latter does not seem to be a " 721 "parameter declaration."));
731 ExcMessage(
"You are trying to declare an alias entry <" +
733 "> but a non-alias entry already exists in this " 734 "subsection (i.e., there is either a preexisting " 735 "further subsection, or a parameter entry, with " 736 "the same name as the alias)."));
741 "You are trying to declare an alias entry <" + alias_name +
742 "> but an alias entry already exists in this " 743 "subsection and this existing alias references a " 744 "different parameter entry. Specifically, " 745 "you are trying to reference the entry <" +
746 existing_entry_name +
747 "> whereas the existing alias references " 755 existing_entry_name);
757 "deprecation_status",
758 (alias_is_deprecated ?
"true" :
"false"));
769 boost::property_tree::ptree());
795 if (boost::optional<std::string> value =
entries->get_optional<std::string>(
809 const std::string & entry_string)
const 813 if (boost::optional<std::string> value =
entries->get_optional<std::string>(
838 ExcMessage(
"Can't convert the parameter value <" +
839 get(entry_string) +
"> for entry <" +
840 entry_string +
"> to an integer."));
849 const std::vector<std::string> &entry_subsection_path,
850 const std::string & entry_string)
const 860 "Can't convert the parameter value <" +
861 get(entry_subsection_path, entry_string) +
"> for entry <" +
864 "> to an integer."));
881 ExcMessage(
"Can't convert the parameter value <" +
882 get(entry_string) +
"> for entry <" +
884 "> to a double precision variable."));
893 const std::vector<std::string> &entry_subsection_path,
894 const std::string & entry_string)
const 899 get(entry_subsection_path, entry_string));
905 "Can't convert the parameter value <" +
906 get(entry_subsection_path, entry_string) +
"> for entry <" +
909 "> to a double precision variable."));
919 const std::string s =
get(entry_string);
921 AssertThrow((s ==
"true") || (s ==
"false") || (s ==
"yes") || (s ==
"no"),
922 ExcMessage(
"Can't convert the parameter value <" +
923 get(entry_string) +
"> for entry <" + entry_string +
925 if (s ==
"true" || s ==
"yes")
935 const std::vector<std::string> &entry_subsection_path,
936 const std::string & entry_string)
const 938 const std::string s =
get(entry_subsection_path, entry_string);
940 AssertThrow((s ==
"true") || (s ==
"false") || (s ==
"yes") || (s ==
"no"),
941 ExcMessage(
"Can't convert the parameter value <" +
942 get(entry_subsection_path, entry_string) +
947 if (s ==
"true" || s ==
"yes")
957 const std::string &new_value)
971 const unsigned int pattern_index =
977 "pattern_description")));
981 const boost::optional<std::string> action_indices_as_string =
983 if (action_indices_as_string)
987 for (
const unsigned int index : action_indices)
988 if (
actions.size() >= index + 1)
1004 set(entry_string, std::string(new_value));
1011 std::ostringstream s;
1012 s << std::setprecision(16);
1017 set(entry_string, s.str());
1025 std::ostringstream s;
1030 set(entry_string, s.str());
1040 set(entry_string, (new_value ?
"true" :
"false"));
1055 boost::io::ios_flags_saver restore_flags(out);
1056 boost::io::basic_ios_fill_saver<char> restore_fill_state(out);
1073 boost::property_tree::ptree single_node_tree;
1074 single_node_tree.add_child(
"ParameterHandler", *
entries);
1076 write_xml(out, single_node_tree);
1090 out <<
"# Listing of Parameters" << std::endl
1091 <<
"# ---------------------" << std::endl;
1095 out <<
"\\subsection{Global parameters}" << std::endl;
1096 out <<
"\\label{parameters:global}" << std::endl;
1097 out << std::endl << std::endl;
1101 out <<
"Listing of Parameters:" << std::endl << std::endl;
1113 std::vector<std::string>(),
1125 const std::vector<std::string> &target_subsection_path,
1127 const unsigned int indent_level,
1128 std::ostream & out)
const 1135 const boost::property_tree::ptree ¤t_section =
1138 unsigned int overall_indent_level = indent_level;
1152 std::size_t longest_name = 0;
1153 std::size_t longest_value = 0;
1154 for (boost::property_tree::ptree::const_iterator p =
1155 current_section.begin();
1156 p != current_section.end();
1158 if (is_parameter_node(p->second) ==
true)
1161 std::max(longest_name, demangle(p->first).length());
1163 std::max(longest_value,
1164 p->second.get<std::string>(
"value").length());
1169 bool first_entry =
true;
1170 for (boost::property_tree::ptree::const_assoc_iterator p =
1171 current_section.ordered_begin();
1172 p != current_section.not_found();
1174 if (is_parameter_node(p->second) ==
true)
1176 const std::string value = p->second.get<std::string>(
"value");
1183 if ((style ==
Text) &&
1184 !p->second.get<std::string>(
"documentation").empty())
1186 if (first_entry ==
false)
1189 first_entry =
false;
1191 const std::vector<std::string> doc_lines =
1193 p->second.get<std::string>(
"documentation"),
1194 78 - overall_indent_level * 2 - 2);
1196 for (
const auto &doc_line : doc_lines)
1197 out << std::setw(overall_indent_level * 2) <<
"" 1198 <<
"# " << doc_line <<
'\n';
1204 out << std::setw(overall_indent_level * 2) <<
"" 1205 <<
"set " << demangle(p->first)
1206 << std::setw(longest_name - demangle(p->first).length() + 1)
1212 if ((style ==
Text) &&
1213 value != p->second.get<std::string>(
"default_value"))
1215 out << std::setw(longest_value - value.length() + 1) <<
' ' 1218 << p->second.get<std::string>(
"default_value");
1229 auto escape = [](
const std::string &input) {
1230 return Patterns::internal::escape(input,
1236 bool parameters_exist_here =
false;
1237 for (boost::property_tree::ptree::const_assoc_iterator p =
1238 current_section.ordered_begin();
1239 p != current_section.not_found();
1241 if ((is_parameter_node(p->second) ==
true) ||
1242 (is_alias_node(p->second) ==
true))
1244 parameters_exist_here =
true;
1248 if (parameters_exist_here)
1250 out <<
"\\begin{itemize}" <<
'\n';
1254 for (boost::property_tree::ptree::const_assoc_iterator p =
1255 current_section.ordered_begin();
1256 p != current_section.not_found();
1258 if (is_parameter_node(p->second) ==
true)
1260 const std::string value =
1261 p->second.get<std::string>(
"value");
1264 out <<
"\\item {\\it Parameter name:} {\\tt " 1265 << escape(demangle(p->first)) <<
"}\n" 1266 <<
"\\phantomsection";
1269 std::string label =
"parameters:";
1270 for (
const auto &path : target_subsection_path)
1272 label.append(mangle(path));
1275 label.append(p->first);
1278 if (label.find(
"_20") != std::string::npos)
1282 out <<
"\\label{" << label <<
"}\n";
1286 out <<
"\\index[prmindex]{" << escape(demangle(p->first))
1288 out <<
"\\index[prmindexfull]{";
1289 for (
const auto &path : target_subsection_path)
1290 out << escape(path) <<
"!";
1291 out << escape(demangle(p->first)) <<
"}\n";
1294 out <<
"{\\it Value:} " << escape(value) <<
"\n\n" 1296 <<
"{\\it Default:} " 1297 << escape(p->second.get<std::string>(
"default_value"))
1303 if (!p->second.get<std::string>(
"documentation").empty())
1304 out <<
"{\\it Description:} " 1305 << p->second.get<std::string>(
"documentation")
1311 const unsigned int pattern_index =
1312 p->second.get<
unsigned int>(
"pattern");
1313 const std::string desc_str =
1314 patterns[pattern_index]->description(
1316 out <<
"{\\it Possible values:} " << desc_str <<
'\n';
1318 else if (is_alias_node(p->second) ==
true)
1320 const std::string alias =
1321 p->second.get<std::string>(
"alias");
1324 out <<
"\\item {\\it Parameter name:} {\\tt " 1325 << escape(demangle(p->first)) <<
"}\n" 1326 <<
"\\phantomsection";
1329 std::string label =
"parameters:";
1330 for (
const auto &path : target_subsection_path)
1332 label.append(mangle(path));
1335 label.append(p->first);
1338 if (label.find(
"_20") != std::string::npos)
1342 out <<
"\\label{" << label <<
"}\n";
1346 out <<
"\\index[prmindex]{" << escape(demangle(p->first))
1348 out <<
"\\index[prmindexfull]{";
1349 for (
const auto &path : target_subsection_path)
1350 out << escape(path) <<
"!";
1351 out << escape(demangle(p->first)) <<
"}\n";
1355 <<
"This parameter is an alias for the parameter ``\\texttt{" 1356 << escape(alias) <<
"}''." 1357 << (p->second.get<std::string>(
"deprecation_status") ==
1359 " Its use is deprecated." :
1364 out <<
"\\end{itemize}" <<
'\n';
1374 std::size_t longest_name = 0;
1375 for (boost::property_tree::ptree::const_iterator p =
1376 current_section.begin();
1377 p != current_section.end();
1379 if (is_parameter_node(p->second) ==
true)
1381 std::max(longest_name, demangle(p->first).length());
1385 for (boost::property_tree::ptree::const_assoc_iterator p =
1386 current_section.ordered_begin();
1387 p != current_section.not_found();
1389 if (is_parameter_node(p->second) ==
true)
1392 out << std::setw(overall_indent_level * 2) <<
"" 1393 <<
"set " << demangle(p->first)
1394 << std::setw(longest_name - demangle(p->first).length() + 1)
1399 const unsigned int pattern_index =
1400 p->second.get<
unsigned int>(
"pattern");
1401 const std::string full_desc_str =
1402 patterns[pattern_index]->description(
1404 const std::vector<std::string> description_str =
1406 full_desc_str, 78 - overall_indent_level * 2 - 2,
'|');
1407 if (description_str.size() > 1)
1410 for (
const auto &description : description_str)
1411 out << std::setw(overall_indent_level * 2 + 6) <<
"" 1412 << description <<
'\n';
1414 else if (description_str.empty() ==
false)
1415 out <<
" " << description_str[0] <<
'\n';
1420 if (p->second.get<std::string>(
"documentation").length() != 0)
1421 out << std::setw(overall_indent_level * 2 + longest_name + 10)
1423 <<
"(" << p->second.get<std::string>(
"documentation")
1438 unsigned int n_parameters = 0;
1439 unsigned int n_sections = 0;
1440 for (boost::property_tree::ptree::const_iterator p =
1441 current_section.begin();
1442 p != current_section.end();
1444 if (is_parameter_node(p->second) ==
true)
1446 else if (is_alias_node(p->second) ==
false)
1455 for (boost::property_tree::ptree::const_assoc_iterator p =
1456 current_section.ordered_begin();
1457 p != current_section.not_found();
1459 if ((is_parameter_node(p->second) ==
false) &&
1460 (is_alias_node(p->second) ==
false))
1468 out << std::setw(overall_indent_level * 2) <<
"" 1469 <<
"subsection " << demangle(p->first) <<
'\n';
1474 auto escape = [](
const std::string &input) {
1475 return Patterns::internal::escape(
1479 out <<
'\n' <<
"\\subsection{Parameters in section \\tt ";
1483 for (
const auto &path : target_subsection_path)
1484 out << escape(path) <<
"/";
1485 out << escape(demangle(p->first));
1488 out <<
"\\label{parameters:";
1489 for (
const auto &path : target_subsection_path)
1490 out << mangle(path) <<
"/";
1491 out << p->first <<
"}";
1503 const std::string subsection = demangle(p->first);
1504 std::vector<std::string> directory_path = target_subsection_path;
1505 directory_path.emplace_back(subsection);
1509 overall_indent_level + 1,
1517 out << std::setw(overall_indent_level * 2) <<
"" 1523 if (overall_indent_level == 0)
1533 out << std::setw(overall_indent_level * 2) <<
"" 1557 const unsigned int indent_level,
1558 const bool include_top_level_elements)
1562 const boost::property_tree::ptree ¤t_section =
1565 unsigned int overall_indent_level = indent_level;
1571 if (include_top_level_elements)
1582 boost::property_tree::ptree single_node_tree;
1589 single_node_tree.add_child(
"ParameterHandler", *
entries);
1593 std::string path(
"ParameterHandler");
1595 single_node_tree.add_child(path,
1596 boost::property_tree::ptree());
1599 single_node_tree.add_child(path, current_section);
1602 write_xml(out, single_node_tree);
1616 out << std::setw(overall_indent_level * 2) <<
"" 1617 <<
"subsection " << demangle(path) << std::endl;
1618 overall_indent_level += 1;
1625 std::size_t longest_name = 0;
1626 for (boost::property_tree::ptree::const_iterator p =
1627 current_section.begin();
1628 p != current_section.end();
1630 if (is_parameter_node(p->second) ==
true)
1632 std::max(longest_name, demangle(p->first).length());
1636 std::size_t longest_value = 0;
1637 for (boost::property_tree::ptree::const_iterator p =
1638 current_section.begin();
1639 p != current_section.end();
1641 if (is_parameter_node(p->second) ==
true)
1643 std::max(longest_value,
1644 p->second.get<std::string>(
"value").length());
1649 bool first_entry =
true;
1650 for (boost::property_tree::ptree::const_assoc_iterator p =
1651 current_section.ordered_begin();
1652 p != current_section.not_found();
1654 if (is_parameter_node(p->second) ==
true)
1656 const std::string value = p->second.get<std::string>(
"value");
1663 if ((!(style & 128)) &&
1664 !p->second.get<std::string>(
"documentation").empty())
1666 if (first_entry ==
false)
1669 first_entry =
false;
1671 const std::vector<std::string> doc_lines =
1673 p->second.get<std::string>(
"documentation"),
1674 78 - overall_indent_level * 2 - 2);
1676 for (
const auto &doc_line : doc_lines)
1677 out << std::setw(overall_indent_level * 2) <<
"" 1678 <<
"# " << doc_line << std::endl;
1684 out << std::setw(overall_indent_level * 2) <<
"" 1685 <<
"set " << demangle(p->first)
1686 << std::setw(longest_name - demangle(p->first).length() + 1)
1692 if ((!(style & 64)) &&
1693 value != p->second.get<std::string>(
"default_value"))
1695 out << std::setw(longest_value - value.length() + 1) <<
' ' 1698 << p->second.get<std::string>(
"default_value");
1709 auto escape = [](
const std::string &input) {
1710 return Patterns::internal::escape(input,
1716 bool parameters_exist_here =
false;
1717 for (boost::property_tree::ptree::const_assoc_iterator p =
1718 current_section.ordered_begin();
1719 p != current_section.not_found();
1721 if ((is_parameter_node(p->second) ==
true) ||
1722 (is_alias_node(p->second) ==
true))
1724 parameters_exist_here =
true;
1728 if (parameters_exist_here)
1730 out <<
"\\begin{itemize}" << std::endl;
1734 for (boost::property_tree::ptree::const_assoc_iterator p =
1735 current_section.ordered_begin();
1736 p != current_section.not_found();
1738 if (is_parameter_node(p->second) ==
true)
1740 const std::string value =
1741 p->second.get<std::string>(
"value");
1744 out <<
"\\item {\\it Parameter name:} {\\tt " 1745 << escape(demangle(p->first)) <<
"}\n" 1746 <<
"\\phantomsection\\label{parameters:";
1748 out << mangle(path) <<
"/";
1750 out <<
"}\n\n" << std::endl;
1752 out <<
"\\index[prmindex]{" << escape(demangle(p->first))
1754 out <<
"\\index[prmindexfull]{";
1756 out << escape(path) <<
"!";
1757 out << escape(demangle(p->first)) <<
"}\n";
1760 out <<
"{\\it Value:} " << escape(value) <<
"\n\n" 1762 <<
"{\\it Default:} " 1763 << escape(p->second.get<std::string>(
"default_value"))
1768 if (!p->second.get<std::string>(
"documentation").empty())
1769 out <<
"{\\it Description:} " 1770 << p->second.get<std::string>(
"documentation")
1775 const unsigned int pattern_index =
1776 p->second.get<
unsigned int>(
"pattern");
1777 const std::string desc_str =
1778 patterns[pattern_index]->description(
1780 out <<
"{\\it Possible values:} " << desc_str << std::endl;
1782 else if (is_alias_node(p->second) ==
true)
1784 const std::string alias =
1785 p->second.get<std::string>(
"alias");
1788 out <<
"\\item {\\it Parameter name:} {\\tt " 1789 << escape(demangle(p->first)) <<
"}\n" 1790 <<
"\\phantomsection\\label{parameters:";
1792 out << mangle(path) <<
"/";
1794 out <<
"}\n\n" << std::endl;
1796 out <<
"\\index[prmindex]{" << escape(demangle(p->first))
1798 out <<
"\\index[prmindexfull]{";
1800 out << escape(path) <<
"!";
1801 out << escape(demangle(p->first)) <<
"}\n";
1805 <<
"This parameter is an alias for the parameter ``\\texttt{" 1806 << escape(alias) <<
"}''." 1807 << (p->second.get<std::string>(
"deprecation_status") ==
1809 " Its use is deprecated." :
1814 out <<
"\\end{itemize}" << std::endl;
1826 out << std::setw(overall_indent_level * 2) <<
"" 1827 <<
"subsection " << demangle(path) << std::endl;
1828 overall_indent_level += 1;
1833 std::size_t longest_name = 0;
1834 for (boost::property_tree::ptree::const_iterator p =
1835 current_section.begin();
1836 p != current_section.end();
1838 if (is_parameter_node(p->second) ==
true)
1840 std::max(longest_name, demangle(p->first).length());
1844 for (boost::property_tree::ptree::const_assoc_iterator p =
1845 current_section.ordered_begin();
1846 p != current_section.not_found();
1848 if (is_parameter_node(p->second) ==
true)
1851 out << std::setw(overall_indent_level * 2) <<
"" 1852 <<
"set " << demangle(p->first)
1853 << std::setw(longest_name - demangle(p->first).length() + 1)
1858 const unsigned int pattern_index =
1859 p->second.get<
unsigned int>(
"pattern");
1860 const std::string full_desc_str =
1861 patterns[pattern_index]->description(
1863 const std::vector<std::string> description_str =
1865 full_desc_str, 78 - overall_indent_level * 2 - 2,
'|');
1866 if (description_str.size() > 1)
1869 for (
const auto &description : description_str)
1870 out << std::setw(overall_indent_level * 2 + 6) <<
"" 1871 << description << std::endl;
1873 else if (description_str.empty() ==
false)
1874 out <<
" " << description_str[0] << std::endl;
1879 if (p->second.get<std::string>(
"documentation").length() != 0)
1880 out << std::setw(overall_indent_level * 2 + longest_name + 10)
1882 <<
"(" << p->second.get<std::string>(
"documentation")
1883 <<
")" << std::endl;
1898 unsigned int n_parameters = 0;
1899 unsigned int n_sections = 0;
1900 for (boost::property_tree::ptree::const_iterator p =
1901 current_section.begin();
1902 p != current_section.end();
1904 if (is_parameter_node(p->second) ==
true)
1906 else if (is_alias_node(p->second) ==
false)
1909 if ((style !=
Description) && (!(style & 128)) && (n_parameters != 0) &&
1911 out << std::endl << std::endl;
1914 for (boost::property_tree::ptree::const_assoc_iterator p =
1915 current_section.ordered_begin();
1916 p != current_section.not_found();
1918 if ((is_parameter_node(p->second) ==
false) &&
1919 (is_alias_node(p->second) ==
false))
1927 out << std::setw(overall_indent_level * 2) <<
"" 1928 <<
"subsection " << demangle(p->first) << std::endl;
1932 auto escape = [](
const std::string &input) {
1933 return Patterns::internal::escape(
1938 <<
"\\subsection{Parameters in section \\tt ";
1943 out << escape(path) <<
"/";
1944 out << escape(demangle(p->first));
1946 out <<
"}" << std::endl;
1947 out <<
"\\label{parameters:";
1949 out << mangle(path) <<
"/";
1950 out << p->first <<
"}";
1970 out << std::setw(overall_indent_level * 2) <<
"" 1971 <<
"end" << std::endl
1976 if (overall_indent_level == 0)
1984 out << std::setw(overall_indent_level * 2) <<
"" 1985 <<
"end" << std::endl;
2008 overall_indent_level -= 1;
2009 out << std::setw(overall_indent_level * 2) <<
"" 2010 <<
"end" << std::endl;
2026 out.
push(
"parameters");
2038 const boost::property_tree::ptree ¤t_section =
2045 for (boost::property_tree::ptree::const_assoc_iterator p =
2046 current_section.ordered_begin();
2047 p != current_section.not_found();
2049 if (is_parameter_node(p->second) ==
true)
2050 out << demangle(p->first) <<
": " << p->second.get<std::string>(
"value")
2056 for (boost::property_tree::ptree::const_assoc_iterator p =
2057 current_section.ordered_begin();
2058 p != current_section.not_found();
2060 if (is_parameter_node(p->second) ==
false)
2062 out.
push(demangle(p->first));
2074 const std::string &input_filename,
2075 const unsigned int current_line_n,
2076 const bool skip_undefined)
2079 const std::string original_line = line;
2082 if (line.find(
'#') != std::string::npos)
2083 line.erase(line.find(
'#'), std::string::npos);
2086 while (line.find(
'\t') != std::string::npos)
2087 line.replace(line.find(
'\t'), 1,
" ");
2093 if (line.length() == 0)
2102 line.erase(0, std::string(
"subsection").length() + 1);
2121 while ((line.size() > 0) && (std::isspace(line[0])))
2128 "Invalid content after 'end' or 'END' statement."));
2132 "There is no subsection to leave here."));
2142 std::string::size_type pos = line.find(
'=');
2144 pos != std::string::npos,
2147 "Invalid format of 'set' or 'SET' statement."));
2151 std::string entry_value =
2160 "deprecation_status") ==
"true")
2162 std::cerr <<
"Warning in line <" << current_line_n
2163 <<
"> of file <" << input_filename
2164 <<
">: You are using the deprecated spelling <" 2165 << entry_name <<
"> of the parameter <" 2168 <<
">." << std::endl;
2182 if (entry_value.find(
'{') == std::string::npos)
2185 const unsigned int pattern_index =
2193 patterns[pattern_index]->description()));
2197 const boost::optional<std::string> action_indices_as_string =
2200 if (action_indices_as_string)
2202 std::vector<int> action_indices =
2204 action_indices_as_string.get()));
2205 for (
const unsigned int index : action_indices)
2206 if (
actions.size() >= index + 1)
2220 (
"No entry with name <" + entry_name +
2221 "> was declared in the current subsection.")));
2230 while ((line.size() > 0) && (line[0] ==
' '))
2237 "The current line is an 'include' or " 2238 "'INCLUDE' statement, but it does not " 2239 "name a file for inclusion."));
2241 std::ifstream input(line.c_str());
2258 "could not be parsed: please check to " 2259 "make sure that the file is not missing a " 2260 "'set', 'include', 'subsection', or 'end' " 2282 for (
unsigned int j = 0; j <
patterns.size(); ++j)
2293 std::ostringstream o1, o2;
2295 write_json(o2, *prm2.
entries);
2296 return (o1.str() == o2.str());
2309 const std::string &filename,
2310 const std::string &last_line,
2311 const bool skip_undefined)
2327 for (
unsigned int run_no = 0; run_no <
n_branches; ++run_no)
2346 multiple_choice.split_different_values();
2352 n_branches *= multiple_choice.different_values.size();
2358 if (multiple_choice.different_values.size() !=
n_branches)
2359 std::cerr <<
" The entry value" << std::endl
2360 <<
" " << multiple_choice.entry_value << std::endl
2361 <<
" for the entry named" << std::endl
2362 <<
" " << multiple_choice.entry_name << std::endl
2363 <<
" does not have the right number of entries for the " 2366 <<
" variant runs that will be performed." << std::endl;
2373 for (
unsigned int i = 0; i <
n_branches; ++i)
2382 const boost::property_tree::ptree ¤t_section =
2393 for (boost::property_tree::ptree::const_assoc_iterator p =
2394 current_section.ordered_begin();
2395 p != current_section.not_found();
2397 if (is_parameter_node(p->second) ==
true)
2399 const std::string value = p->second.get<std::string>(
"value");
2400 if (value.find(
'{') != std::string::npos)
2407 for (boost::property_tree::ptree::const_iterator p = current_section.begin();
2408 p != current_section.end();
2410 if (is_parameter_node(p->second) ==
false)
2423 unsigned int possibilities = 1;
2425 std::vector<Entry>::iterator choice;
2429 const unsigned int selection =
2430 (run_no / possibilities) % choice->different_values.size();
2431 std::string entry_value;
2433 entry_value = choice->different_values[selection];
2436 if (run_no >= choice->different_values.size())
2439 <<
"The given array for entry <" << choice->entry_name
2440 <<
"> does not contain enough elements! Taking empty string instead." 2445 entry_value = choice->different_values[run_no];
2457 set(choice->entry_name, entry_value);
2462 possibilities *= choice->different_values.size();
2473 mem += multiple_choice.memory_consumption();
2481 const std::string & Name,
2482 const std::string & Value)
2483 : subsection_path(ssp)
2485 , entry_value(Value)
2486 , type(
Entry::array)
2498 std::string prefix(entry_value, 0, entry_value.find(
'{'));
2499 std::string multiple(entry_value,
2500 entry_value.find(
'{') + 1,
2501 entry_value.rfind(
'}') - entry_value.find(
'{') - 1);
2502 std::string postfix(entry_value,
2503 entry_value.rfind(
'}') + 1,
2507 if (multiple[0] ==
'{')
2508 multiple.erase(0, 1);
2509 if (multiple[multiple.size() - 1] ==
'}')
2510 multiple.erase(multiple.size() - 1, 1);
2513 while (std::isspace(multiple[0]))
2514 multiple.erase(0, 1);
2515 while (std::isspace(multiple[multiple.size() - 1]))
2516 multiple.erase(multiple.size() - 1, 1);
2519 while (multiple.find(
" |") != std::string::npos)
2520 multiple.replace(multiple.find(
" |"), 2,
"|");
2521 while (multiple.find(
"| ") != std::string::npos)
2522 multiple.replace(multiple.find(
"| "), 2,
"|");
2524 while (multiple.find(
'|') != std::string::npos)
2526 different_values.push_back(
2527 prefix + std::string(multiple, 0, multiple.find(
'|')) + postfix);
2528 multiple.erase(0, multiple.find(
'|') + 1);
2532 different_values.push_back(prefix + multiple + postfix);
2535 if ((entry_value.find(
"{{") != std::string::npos) &&
2536 (entry_value.find(
"}}") != std::string::npos))
2553 DEAL_II_NAMESPACE_CLOSE
std::vector< std::string > split_string_list(const std::string &s, const std::string &delimiter=",")
std::vector< Entry > multiple_choices
long int get_integer(const std::string &entry_string) const
static const char path_separator
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation="")
static std::string collate_path_string(const std::vector< std::string > &subsection_path)
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
std::string get_current_path() const
static ::ExceptionBase & ExcEntryUndeclared(std::string arg1)
std::string trim(const std::string &input)
std::string get(const std::string &entry_string) const
static ::ExceptionBase & ExcUnbalancedSubsections(std::string arg1, std::string arg2)
std::ostream & print_parameters(std::ostream &out, const OutputStyle style) const
void log_parameters(LogStream &out)
std::vector< std::string > break_text_into_lines(const std::string &original_text, const unsigned int width, const char delimiter=' ')
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false) override
virtual void parse_input_from_string(const std::string &s, const std::string &last_line="", const bool skip_undefined=false)
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)
#define AssertThrow(cond, exc)
void scan_line(std::string line, const std::string &input_filename, const unsigned int current_line_n, const bool skip_undefined)
static ::ExceptionBase & ExcValueDoesNotMatchPattern(std::string arg1, std::string arg2)
std::vector< std::string > subsection_path
double string_to_double(const std::string &s)
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)
double get_double(const std::string &entry_name) const
std::size_t memory_consumption() const
#define Assert(cond, exc)
std::string get_current_full_path(const std::string &name) const
bool match_at_string_start(const std::string &name, const std::string &pattern)
std::unique_ptr< boost::property_tree::ptree > entries
void fill_entry_values(const unsigned int run_no)
virtual void parse_input(std::istream &input, const std::string &filename="input file", const std::string &last_line="", const bool skip_undefined=false)
bool get_bool(const std::string &entry_name) const
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 operator==(const ParameterHandler &prm2) const
std::string find(const std::string &filename, const char *open_mode="r")
std::size_t memory_consumption() const
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)
void print_parameters_section(std::ostream &out, const OutputStyle style, const unsigned int indent_level, const bool include_top_level_elements=false)
int string_to_int(const std::string &s)
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 & ExcNotImplemented()
std::size_t memory_consumption() const
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
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::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static ::ExceptionBase & ExcInternalError()