DeclException1 (ExcEntryUndeclared,
std::string,
<< "You can't ask for entry <" << arg1 << "> you have not yet declared.");
+
+ /**
+ * Exception for when there are an unequal number of 'subsection' and 'end'
+ * statements.
+ */
+ DeclException1 (ExcUnbalancedSubsections,
+ std::string,
+ << "There are unequal numbers of 'subsection' and 'end' "
+ "statements in the parameter file <" << arg1 << ">.");
+
+ /**
+ * Exception for when, during parsing of a parameter file, the parser
+ * encounters a subsection in the file that was not previously declared.
+ */
+ DeclException3 (ExcNoSubsection,
+ int, std::string, std::string,
+ << "Line <" << arg1 << "> of file <" << arg2 << ": There is "
+ "no such subsection to be entered: " << arg3);
+
+ /**
+ * General exception for a line that could not be parsed, taking, as
+ * arguments, the line number, file name, and a brief description of why the
+ * line cannot be parsed.
+ */
+ DeclException3 (ExcCannotParseLine,
+ int, std::string, std::string, << "Line <" << arg1 <<
+ "> of file <" << arg2 << ">: " << arg3);
+
+ /**
+ * Exception for an an entry in a parameter file that does not match the
+ * provided pattern. The arguments are, in order, the line number, file
+ * name, entry value, entry name, and a description of the pattern.
+ */
+ DeclException5 (ExcInvalidEntryForPattern,
+ int, std::string, std::string, std::string, std::string,
+ << "Line <" << arg1 << "> of file <" << arg2 << ">:\n"
+ " The entry value \n" << " " << arg3 << '\n' <<
+ " for the entry named\n" << " " << arg4 << '\n' <<
+ " does not match the given pattern:\n" << " " <<
+ arg5);
+
+ /**
+ * Exception for when the file given in an include statement cannot be
+ * open. The arguments are, in order, the line number of the include
+ * statement, current parameter file name, and the name of the file intended
+ * for inclusion.
+ */
+ DeclException3 (ExcCannotOpenIncludeStatementFile,
+ int, std::string, std::string,
+ << "Line <" << arg1 << "> of file <" << arg2 << ">: This line "
+ "contains an 'include' or 'INCLUDE' statement, but the given "
+ "file to include <" << arg3 << "> cannot be opened.");
+
//@}
private:
/**
/**
* Scan one line of input. <tt>input_filename</tt> and
- * <tt>current_line_n</tt> are the name of the input file and the current
- * number of the line presently scanned (for the logs if there are
- * messages). Return <tt>false</tt> if line contained stuff that could not
- * be understood, the uppermost subsection was to be left by an <tt>END</tt>
- * or <tt>end</tt> statement, a value for a non-declared entry was given or
- * the entry value did not match the regular expression. <tt>true</tt>
- * otherwise.
+ * <tt>current_line_n</tt> are the name of the input file and the number of
+ * the line presently scanned (these are used in exception messages to show
+ * where parse errors occurred). This function will raise an exception if
+ * the line contains an undeclared subsection or entry, if the line's entry
+ * does not match its given pattern, or if the line could not be understood
+ * as a valid parameter file expression.
*
* The function modifies its argument, but also takes it by value, so the
* caller's variable is not changed.
*/
- bool scan_line (std::string line,
+ void scan_line (std::string line,
const std::string &input_filename,
const unsigned int current_line_n);
if (!is_concatenated)
{
- status &= scan_line (fully_concatenated_line, filename, current_logical_line_n);
+ scan_line (fully_concatenated_line, filename, current_logical_line_n);
fully_concatenated_line.clear();
}
}
// the last line to end in a backslash.
if (is_concatenated)
{
- status &= scan_line (fully_concatenated_line, filename, current_line_n);
+ scan_line (fully_concatenated_line, filename, current_line_n);
}
if (status && (saved_path != subsection_path))
-bool
+void
ParameterHandler::scan_line (std::string line,
const std::string &input_filename,
const unsigned int current_line_n)
{
+ // save a copy for some error messages
+ const std::string original_line = line;
+
// if there is a comment, delete it
if (line.find('#') != std::string::npos)
line.erase (line.find("#"), std::string::npos);
// if line is now empty: leave
if (line.length() == 0)
- return true;
-
+ {
+ return;
+ }
// enter subsection
- if ((line.find ("SUBSECTION ") == 0) ||
- (line.find ("subsection ") == 0))
+ else if ((line.find ("SUBSECTION ") == 0) ||
+ (line.find ("subsection ") == 0))
{
// delete this prefix
line.erase (0, std::string("subsection").length()+1);
const std::string subsection = Utilities::trim(line);
// check whether subsection exists
- if (!entries->get_child_optional (get_current_full_path(subsection)))
- {
- std::cerr << "Line <" << current_line_n
- << "> of file <" << input_filename
- << ">: There is no such subsection to be entered: "
- << demangle(get_current_full_path(subsection)) << std::endl;
- for (unsigned int i=0; i<subsection_path.size(); ++i)
- std::cerr << std::setw(i*2+4) << " "
- << "subsection " << subsection_path[i] << std::endl;
- std::cerr << std::setw(subsection_path.size()*2+4) << " "
- << "subsection " << subsection << std::endl;
- return false;
- }
+ AssertThrow (entries->get_child_optional (get_current_full_path(subsection)),
+ ExcNoSubsection (current_line_n,
+ input_filename,
+ demangle(get_current_full_path(subsection))));
// subsection exists
subsection_path.push_back (subsection);
- return true;
}
-
// exit subsection
- if ((line.find ("END") == 0) ||
- (line.find ("end") == 0))
+ else if ((line.find ("END") == 0) ||
+ (line.find ("end") == 0))
{
line.erase (0, 3);
while ((line.size() > 0) && (std::isspace(line[0])))
line.erase (0, 1);
- if (line.size()>0)
- {
- std::cerr << "Line <" << current_line_n
- << "> of file <" << input_filename
- << ">: invalid content after 'end'!" << std::endl;
- return false;
- }
-
- if (subsection_path.size() == 0)
- {
- std::cerr << "Line <" << current_line_n
- << "> of file <" << input_filename
- << ">: There is no subsection to leave here!" << std::endl;
- return false;
- }
- else
- {
- leave_subsection ();
- return true;
- }
-
+ AssertThrow (line.size() == 0,
+ ExcCannotParseLine (current_line_n,
+ input_filename,
+ "Invalid content after 'end' or 'END' statement."));
+ AssertThrow (subsection_path.size() != 0,
+ ExcCannotParseLine (current_line_n,
+ input_filename,
+ "There is no subsection to leave here."));
+ leave_subsection ();
}
-
// regular entry
- if ((line.find ("SET ") == 0) ||
- (line.find ("set ") == 0))
+ else if ((line.find ("SET ") == 0) ||
+ (line.find ("set ") == 0))
{
// erase "set" statement
line.erase (0, 4);
std::string::size_type pos = line.find("=");
- if (pos == std::string::npos)
- {
- std::cerr << "Line <" << current_line_n
- << "> of file <" << input_filename
- << ">: invalid format of set expression!" << std::endl;
- return false;
- }
+ AssertThrow (pos != std::string::npos,
+ ExcCannotParseLine (current_line_n,
+ input_filename,
+ "Invalid format of 'set' or 'SET' statement."));
// extract entry name and value and trim
std::string entry_name = Utilities::trim(std::string(line, 0, pos));
{
const unsigned int pattern_index
= entries->get<unsigned int> (path + path_separator + "pattern");
- if (!patterns[pattern_index]->match(entry_value))
- {
- std::cerr << "Line <" << current_line_n
- << "> of file <" << input_filename
- << ">:" << std::endl
- << " The entry value" << std::endl
- << " " << entry_value << std::endl
- << " for the entry named" << std::endl
- << " " << entry_name << std::endl
- << " does not match the given pattern" << std::endl
- << " " << patterns[pattern_index]->description()
- << std::endl;
- return false;
- }
+ AssertThrow (patterns[pattern_index]->match (entry_value),
+ ExcInvalidEntryForPattern (current_line_n,
+ input_filename,
+ entry_value,
+ entry_name,
+ patterns[pattern_index]->description()));
}
entries->put (path + path_separator + "value",
entry_value);
- return true;
}
else
{
- std::cerr << "Line <" << current_line_n
- << "> of file <" << input_filename
- << ">: No such entry was declared:" << std::endl
- << " " << entry_name << std::endl
- << " <Present subsection:" << std::endl;
- for (unsigned int i=0; i<subsection_path.size(); ++i)
- std::cerr << std::setw(i*2+8) << " "
- << "subsection " << subsection_path[i] << std::endl;
- std::cerr << " >" << std::endl;
-
- return false;
+ AssertThrow (false,
+ ExcCannotParseLine(current_line_n,
+ input_filename,
+ ("No entry with name <" + entry_name +
+ "> was declared in the current subsection.")));
}
}
-
// an include statement?
- if ((line.find ("INCLUDE ") == 0) ||
- (line.find ("include ") == 0))
+ else if ((line.find ("INCLUDE ") == 0) ||
+ (line.find ("include ") == 0))
{
// erase "include " statement and eliminate spaces
line.erase (0, 7);
line.erase (0, 1);
// the remainder must then be a filename
- if (line.size() == 0)
- {
- std::cerr << "Line <" << current_line_n
- << "> of file <" << input_filename
- << "> is an include statement but does not name a file!"
- << std::endl;
-
- return false;
- }
+ AssertThrow (line.size() !=0,
+ ExcCannotParseLine (current_line_n,
+ input_filename,
+ "The current line is an 'include' or "
+ "'INCLUDE' statement, but it does not "
+ "name a file for inclusion."));
std::ifstream input (line.c_str());
- if (!input)
- {
- std::cerr << "Line <" << current_line_n
- << "> of file <" << input_filename
- << "> is an include statement but the file <"
- << line << "> could not be opened!"
- << std::endl;
-
- return false;
- }
- else
- return read_input (input);
+ AssertThrow (input, ExcCannotOpenIncludeStatementFile (current_line_n,
+ input_filename,
+ line));
+ read_input (input);
+ }
+ else
+ {
+ AssertThrow (false,
+ ExcCannotParseLine (current_line_n,
+ input_filename,
+ "The line\n\n"
+ " <"
+ + original_line
+ + ">\n\n"
+ "could not be parsed: please check to "
+ "make sure that the file is not missing a "
+ "'set', 'include', 'subsection', or 'end' "
+ "statement."));
}
-
- // this line matched nothing known
- std::cerr << "Line <" << current_line_n
- << "> of file <" << input_filename
- << ">: This line matched nothing known ('set' or 'subsection' missing!?):" << std::endl
- << " " << line << std::endl;
- return false;
}
// ---------------------------------------------------------------------
//
-// Copyright (C) 2002 - 2015 by the deal.II authors
+// Copyright (C) 2002 - 2016 by the deal.II authors
//
// This file is part of the deal.II library.
//
prm.declare_entry ("test_1", "3", Patterns::Integer());
std::ifstream in(p);
- const bool result = prm.read_input (in);
-
- deallog << result << std::endl;
- deallog << "test_1=" << prm.get ("test_1") << std::endl;
+ try
+ {
+ prm.read_input (in);
+
+ // The first line in the parameter file should not match the given
+ // pattern, so we should not get here
+ deallog << "test_1=" << prm.get ("test_1") << std::endl;
+ }
+ catch (ParameterHandler::ExcInvalidEntryForPattern &exc)
+ {
+ deallog << exc.get_exc_name() << std::endl;
+ exc.print_info(deallog.get_file_stream());
+ }
}
-DEAL::0
-DEAL::test_1=3
+DEAL::ExcInvalidEntryForPattern (current_line_n, input_filename, entry_value, entry_name, patterns[pattern_index]->description())
+Line <1> of file <input file>:
+ The entry value
+ 3.1415
+ for the entry named
+ test_1
+ does not match the given pattern
+ [Integer range -2147483648...2147483647 (inclusive)]
-// like _10 but for Patterns::Double::match
+// like _10 but for Patterns::Double::match : the first line of the parameter
+// file does not match the given pattern.
#include "../tests.h"
#include <deal.II/base/logstream.h>
prm.declare_entry ("test_1", "3", Patterns::Double());
std::ifstream in(p);
- const bool result = prm.read_input (in);
-
- deallog << result << std::endl;
- deallog << "test_1=" << prm.get ("test_1") << std::endl;
+ try
+ {
+ prm.read_input (in);
+
+ // The first line in the parameter file should not match the given
+ // pattern, so we should not get here
+ deallog << "test_1=" << prm.get ("test_1") << std::endl;
+ }
+ catch (ParameterHandler::ExcInvalidEntryForPattern &exc)
+ {
+ deallog << exc.get_exc_name() << std::endl;
+ exc.print_info(deallog.get_file_stream());
+ }
}
-DEAL::0
-DEAL::test_1=3
+DEAL::ExcInvalidEntryForPattern (current_line_n, input_filename, entry_value, entry_name, patterns[pattern_index]->description())
+Line <1> of file <input file>:
+ The entry value
+ 3.1415 something
+ for the entry named
+ test_1
+ does not match the given pattern
+ [Double -MAX_DOUBLE...MAX_DOUBLE (inclusive)]
Patterns::List(Patterns::Integer(-1,1),2,3));
std::ifstream in(p);
- bool status = prm.read_input (in);
- Assert (status == false, ExcInternalError());
-
+ try
+ {
+ prm.read_input (in);
+ }
+ catch (ParameterHandler::ExcCannotOpenIncludeStatementFile &exc)
+ {
+ deallog << exc.get_exc_name() << std::endl;
+ exc.print_info(deallog.get_file_stream());
+ }
+
+ // Even though the parameter handler failed to finish parsing, it should
+ // have still picked up the first statement:
deallog << "test_1=" << prm.get ("test_1") << std::endl;
}
+DEAL::ExcCannotOpenIncludeStatementFile (current_line_n, input_filename, line)
+Line <4> of file <input file>: This line contains an 'include' or 'INCLUDE' statement, but the given file to include <parameter_handler_1_include_fail.prm2> cannot be opened.
DEAL::test_1=1,1,1
std::stringstream ss(content);
- if (!foo.read_input(ss))
+ try
{
- deallog << "read_input() failed" << std::endl;
- return;
+ foo.read_input(ss);
+ deallog << "input: ";
+ foo.enter_subsection("bar");
+ deallog << foo.get_double ("val") << " ";
+ foo.leave_subsection();
+ deallog << foo.get_double ("val2") << std::endl;
}
- deallog << "input: ";
- foo.enter_subsection("bar");
- deallog << foo.get_double ("val") << " ";
- foo.leave_subsection();
- deallog << foo.get_double ("val2") << std::endl;
+ catch (ParameterHandler::ExcCannotParseLine &)
+ {
+ deallog << "read_input() failed" << std::endl;
+ }
}
int main ()
Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h")));
prm.leave_subsection ();
- // test both relevant read_input functions
- if (i == 0)
+ // test both relevant read_input functions. They should fail with a
+ // specific exception.
+ try
{
- prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_03.prm");
+ 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);
+ }
+
+ // read_input should fail and we should not get here
+ std::string list;
+ prm.enter_subsection ("Testing");
+ list = prm.get ("Function");
+ prm.leave_subsection ();
+
+ deallog << list << std::endl;
}
- else
+ catch (ParameterHandler::ExcInvalidEntryForPattern &exc)
{
- std::ifstream input_stream
- (SOURCE_DIR "/prm/parameter_handler_backslash_03.prm");
- prm.read_input(input_stream);
+ deallog << exc.get_exc_name() << std::endl;
+ exc.print_info(deallog.get_file_stream());
}
-
-
- std::string list;
- prm.enter_subsection ("Testing");
- list = prm.get ("Function");
- prm.leave_subsection ();
-
- deallog << list << std::endl;
}
return 0;
+++ /dev/null
-
-DEAL::a, b, c
-DEAL::a, b, c
--- /dev/null
+
+DEAL::ExcInvalidEntryForPattern (current_line_n, input_filename, entry_value, entry_name, patterns[pattern_index]->description())
+Line <4> of file <./prm/parameter_handler_backslash_03.prm>:
+ The entry value
+ a,\
+ for the entry named
+ Function
+ does not match the given pattern
+ [List list of <[Selection a|b|c|d|e|f|g|h ]> of length 0...4294967295 (inclusive)]
+DEAL::ExcInvalidEntryForPattern (current_line_n, input_filename, entry_value, entry_name, patterns[pattern_index]->description())
+Line <4> of file <input file>:
+ The entry value
+ a,\
+ for the entry named
+ Function
+ does not match the given pattern
+ [List list of <[Selection a|b|c|d|e|f|g|h ]> of length 0...4294967295 (inclusive)]
Patterns::List(Patterns::Selection("a|b|c|d|e|f|g|h")));
prm.leave_subsection ();
- // test both relevant read_input functions
- if (i == 0)
+ // test both relevant read_input functions. They should fail with a
+ // specific exception.
+ try
{
- prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_04.prm");
+ 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;
}
- else
+ catch (ParameterHandler::ExcInvalidEntryForPattern &exc)
{
- std::ifstream input_stream
- (SOURCE_DIR "/prm/parameter_handler_backslash_04.prm");
- prm.read_input(input_stream);
+ deallog << exc.get_exc_name() << std::endl;
+ exc.print_info(deallog.get_file_stream());
}
-
-
- std::string list;
- prm.enter_subsection ("Testing");
- list = prm.get ("Function");
- prm.leave_subsection ();
-
- deallog << list << std::endl;
}
return 0;
+++ /dev/null
-
-DEAL::a, b, c
-DEAL::a, b, c
--- /dev/null
+
+DEAL::ExcInvalidEntryForPattern (current_line_n, input_filename, entry_value, entry_name, patterns[pattern_index]->description())
+Line <4> of file <./prm/parameter_handler_backslash_04.prm>:
+ The entry value
+ a,\ b,
+ for the entry named
+ Function
+ does not match the given pattern
+ [List list of <[Selection a|b|c|d|e|f|g|h ]> of length 0...4294967295 (inclusive)]
+DEAL::ExcInvalidEntryForPattern (current_line_n, input_filename, entry_value, entry_name, patterns[pattern_index]->description())
+Line <4> of file <input file>:
+ The entry value
+ a,\ b,
+ for the entry named
+ Function
+ does not match the given pattern
+ [List list of <[Selection a|b|c|d|e|f|g|h ]> of length 0...4294967295 (inclusive)]
// test both relevant read_input functions
- if (i == 0)
+ try
{
- prm.read_input(SOURCE_DIR "/prm/parameter_handler_backslash_05.prm");
+ 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;
}
- else
+ catch (ParameterHandler::ExcCannotParseLine &exc)
{
- std::ifstream input_stream
- (SOURCE_DIR "/prm/parameter_handler_backslash_05.prm");
- prm.read_input(input_stream);
+ deallog << exc.get_exc_name() << std::endl;
+ exc.print_info(deallog.get_file_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;
+++ /dev/null
-
-DEAL::a, b, c
-DEAL::d, e, f
-DEAL::a, b, c
-DEAL::d, e, f
--- /dev/null
+
+DEAL::ExcCannotParseLine (current_line_n, input_filename, "The line\n\n" " <" + original_line + ">\n\n" "could not be parsed: please check to " "make sure that the file is not missing a " "'set', 'include', 'subsection', or 'end' " "statement.")
+Line <8> of file <./prm/parameter_handler_backslash_05.prm>: The line
+
+ <b, c>
+
+could not be parsed: please check to make sure that the file is not missing a 'set', 'include', 'subsection', or 'end' statement.
+DEAL::ExcCannotParseLine (current_line_n, input_filename, "The line\n\n" " <" + original_line + ">\n\n" "could not be parsed: please check to " "make sure that the file is not missing a " "'set', 'include', 'subsection', or 'end' " "statement.")
+Line <8> of file <input file>: The line
+
+ <b, c>
+
+could not be parsed: please check to make sure that the file is not missing a 'set', 'include', 'subsection', or 'end' statement.