From 191bda46165f703369a9cdf19a7d69bd55e32df4 Mon Sep 17 00:00:00 2001 From: wolf Date: Sun, 13 Dec 1998 20:59:22 +0000 Subject: [PATCH] Adapt programs to the changes in the exception handling mechanisms (run-time checks, which throw C++ exceptions). git-svn-id: https://svn.dealii.org/trunk@706 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/base/include/base/exceptions.h | 724 ++++++++++-------- deal.II/base/include/base/parameter_handler.h | 5 +- deal.II/base/include/base/tensor_base.h | 6 - deal.II/base/source/parameter_handler.cc | 14 +- .../deal.II/include/dofs/dof_constraints.h | 4 + deal.II/deal.II/include/grid/tria.h | 4 + deal.II/deal.II/include/numerics/data_io.h | 43 ++ .../deal.II/source/dofs/dof_constraints.cc | 3 +- deal.II/deal.II/source/grid/tria.cc | 38 +- deal.II/deal.II/source/numerics/data_io.cc | 52 +- deal.II/lac/include/lac/dfmatrix.h | 4 + deal.II/lac/include/lac/dsmatrix.h | 10 +- deal.II/lac/include/lac/dvector.h | 4 + deal.II/lac/source/dfmatrix.cc | 5 +- deal.II/lac/source/dsmatrix.cc | 9 +- deal.II/lac/source/dvector.cc | 3 +- 16 files changed, 548 insertions(+), 380 deletions(-) diff --git a/deal.II/base/include/base/exceptions.h b/deal.II/base/include/base/exceptions.h index fef9d1119d..e701c61d79 100644 --- a/deal.II/base/include/base/exceptions.h +++ b/deal.II/base/include/base/exceptions.h @@ -10,27 +10,273 @@ - #ifndef __GNUC__ # define __PRETTY_FUNCTION__ "(unknown)" #endif - /** - * This class should be used as a base class for - * all exception classes. Do not use its methods - * and variables directly since the interface - * and mechanism may be subject to change. Rather - * create new exception classes using the - * #DeclException# macro family. - * - * @see Assert - * @see DeclException0 - * @author Wolfgang Bangerth, November 1997 - */ + +/** + * This class should be used as a base class for + * all exception classes. Do not use its methods + * and variables directly since the interface + * and mechanism may be subject to change. Rather + * create new exception classes using the + * #DeclException# macro family. + * + * + * \section{General overview of the exception handling mechanism in #deal.II#} + * + * The error handling mechanism in #deal.II# is generally used in two ways. + * The first uses error checking in debug mode only and is useful for programs + * which are not fully tested. When the program shows no error anymore, one may + * switch off error handling and get better performance by this, since checks + * for errors are done quite frequently in the library (a typical speed up is + * a factor of four!). This mode of exception generation is most useful for + * internal consistency checks such as range checking or checking of the + * validity of function arguments. Errors of this kind usually are programming + * errors and the program should abort with as detailed a message as possible, + * including location and reason for the generation of the exception. + * + * The second mode is for error checks which should always be on, such as for + * I/O errors, failing memory requests and the like. It does not make much + * sense to turn this mode off, since this kind of errors may happen in tested + * and untested programs likewise. Exceptions of this kind do not terminate the + * program, rather they throw exceptions in the #C++# manner, allowing the + * program to catch them and eventually do something about it. As it may be + * useful to have some information printed out if an exception could not be + * handled properly, additional information is passed along as for the first + * mode. The latter makes it necessary to provide a family of macros which + * enter this additional information into the exception class; this could + * in principle be done by the programmer himself each time by hand, but since + * the information can be obtained automatically, a macro is provided for + * this. + * + * Both modes use exception classes, which need to have special features + * additionally to the #C++# standard's #exception# class. Such a class + * is declared by the following lines of code: + * \begin{verbatim} + * DeclException2 (ExcDomain, int, int, + * << "Index= " << arg1 << "Upper Bound= " << arg2); + * \end{verbatim} + * This declares an exception class named #ExcDomain#, which + * has two variables as additional information (named + * #arg1# and #arg2# by default) and which outputs the + * given sequence (which is appended to an #ostream# + * variable's name, thus the weird syntax). There are + * other #DeclExceptionN# macros for exception classes + * with more or no parameters. It is proposed to let start + * the name of all exceptions by #Exc...# and to declare them locally to + * the class it is to be used in. Declaring exceptions globally is possible + * but pollutes the global namespace, is less readable and thus unnecessary. + * + * Since exception classes are declared the same way for both modes of error + * checking, it is possible to use an exception declared through the + * #DeclExceptionN(...)# macro family in both modes; there is no need to + * declare different classes for each of these. + * + * + * \section{Use of the debug mode exceptions} + * + * To use the exception mechanism for debug mode error checking, write lines + * like the following in your source code: + * \begin{verbatim} + * Assert (nm, ExcSomewhat());# + * + * \subsection{How it works internally} + * If the #DEBUG# preprocessor directive is set, the call #Assert (cond, exc);# + * is converted by the preprocessor into the sequence + * \begin{verbatim} + * if (!(cond)) + * __IssueError_Assert (__FILE__, + * __LINE__, + * __PRETTY_FUNCTION__, + * #cond, + * #exc, + * &exc); + * \end{verbatim} + * i.e. if the given condition is violated, then the file and + * line in which the exception occured as well as + * the condition itself and the call sequence of the + * exception object is transferred. Additionally an object + * of the form given by #exc# is created (this is normally an + * unnamed object like in #ExcDomain (n, dim)# of class + * #ExcDomain#) and transferred to the #__IssueError_Assert# + * function. + * + * #__PRETTY__FUNCTION__# is a macro defined only by the GNU CC + * compiler and gives the name of the function. If another compiler + * is used, we set #__PRETTY_FUNCTION__ = "(unknown)"#. + * + * In #__IssueError# the given data + * is transferred into the #exc# object by calling the + * #SetFields# function; after that, the general error info + * is printed onto #cerr# using the #PrintError# function of + * #exc# and finally the exception specific data is printed + * using the user defined function #PrintError# (which is + * normally created using the #DeclException (...)# macro + * family. + * + * After printing all this information, #abort()# is called. + * This terminates the program, which is the right thing to do for + * this kind of error checking since it is used to detect programming + * errors rather than run-time errors; a program can, by definition, + * not recover from programming errors. + * + * If the preprocessor variable #DEBUG# is not set, then nothing + * happens, i.e. the #Assert# macro is expanded to #(void) 0;#. + * + * Sometimes, there is no useful condition for an exception other + * than that the program flow should not have reached a certain point, + * e.g. a #default# section of a #switch# statement. In this case, + * raise the exception by the following construct: + * \begin{verbatim} + * Assert (false, ExcInternalError()); + * \end{verbatim} + * + * + * \section{Use of run-time exceptions} + * + * For this mode, the standard #C++# #throw# and #catch# concept exists. We + * want to keep to this, but want to extend it a bit. In general, the + * structure is the same, i.e. you normally raise and exception by + * \begin{verbatim} + * if (!cond) + * throw ExcSomething(); + * \end{verbatim} + * and catch it using the statement + * \begin{verbatim} + * try { + * do_something (); + * } + * catch (exception &e) { + * cerr << "Exception occured:" << endl + * << e.what () + * << endl; + * do_something_to_reciver (); + * }; + * \end{verbatim} + * #exception# is a standard #C++# class providing basic functionality for + * exceptions, such as the virtual function #what()# which returns some + * information on the exception itself. This information is useful if an + * exception can't be handled properly, in which case as precise a description + * as possible should be printed. + * + * The problem here is that to get significant and useful information out + * of #what()#, it is necessary to overload this function in out exception + * class and call the #throw# operator with additional arguments to the + * exception class. The first thing, overloading the #what# function is + * done using the #DeclExceptionN# macros, but putting the right information, + * which is the same as explained above for the #Assert# expansion, requires + * some work if one would want to write it down each time: + * \begin{verbatim} + * if (!cond) + * { + * ExcSomething e(additional information); + * e.SetFields (__FILE__, __LINE__, __PRETTY_FUNCTION__, + * "condition as a string", + * "name of condition as a string"); + * throw e; + * }; + * \end{verbatim} + * + * For this purpose, the macro #AssertThrow# was invented. It does mainly + * the same job as does the #Assert# macro, but it does not kill the + * program, it rather throws an exception as shown above. The mode of usage + * is + * \begin{verbatim} + * AssertThrow (cond, ExcSomething(additional information)); + * \end{verabtim} + * The condition to be checked is incorporated into the macro in order to + * allow passing the violated condition as a string. The expansion of the + * #AssertThrow# macro is not affected by the #DEBUG# preprocessor variable. + * + * + * \section{Description of the #DeclExceptionN# macro family} + * + * Declare an exception class without any additional parameters. + * There is a whole family of #DeclException?# macros + * where #?# is to be replaced by the number of additional + * parameters (0 to 5 presently). + * + * The syntax is as follows: + * \begin{verbatim} + * DeclException2 (ExcDomain, + * int, + * int, + * << " i=" << arg1 << ", m=" << arg2); + * \end{verbatim} + * The first is the name of the exception class to be created. + * The next arguments are the types of the parameters (in this + * case there are two type names needed) and finally the output + * sequence with which you can print additional information. + * + * The syntax of the output sequence is a bit weird but gets + * clear once you see how this macro is defined: + * \begin{verbatim} + * class name : public ExceptionBase { + * public: + * name (const type1 a1, const type2 a2) : + * arg1 (a1), arg2(a2) {}; + * virtual void PrintInfo (ostream &out) const { + * out outsequence << endl; + * }; + * private: + * type1 arg1; + * type2 arg2; + * }; + * \end{verbatim} + * + * If declared as specified, you can later use this exception class + * in the following manner: + * \begin{verbatim} + * int i=5; + * int m=3; + * Assert (i of file . + * The violated condition was: + * i of file <" << file - << "> in function" << endl - << " " << function << endl - << "The violated condition was: "<< endl - << " " << cond << endl - << "The name and call sequence of the exception was:" << endl - << " " << exc << endl - << "Additional Information: " << endl; - }; + void PrintExcData (ostream &out) const; /** * Print more specific information about the * exception which occured. Overload this * function in your own exception classes. - * Since we use templates rather than derivation - * information, we need not declare this - * function as #virtual# and thus avoid problems - * with virtual functions in classes in which - * all functions are declared inline. */ - void PrintInfo (ostream &out) const { - out << "(none)" << endl; - }; + virtual void PrintInfo (ostream &out) const; /** @@ -123,142 +322,108 @@ class ExceptionBase : public exception { * This function is mainly used when using * exceptions declared by the * #DeclException*# macros with the #throw# - * mechanism or the #Assert_or_Throw# macro. + * mechanism or the #AssertThrow# macro. */ -// virtual const char * what () const; + virtual const char * what () const; - - const char *file; - int line; - const char *function; - const char *cond; - const char *exc; + protected: + /** + * Name of the file this exception happen in. + */ + const char *file; + + /** + * Line number in this file. + */ + unsigned int line; + + /** + * Name of the function, pretty printed. + */ + const char *function; + + /** + * The violated condition, as a string. + */ + const char *cond; + + /** + * Name of the exception and call sequence. + */ + const char *exc; }; - /** - * This routine does the main work for the - * exception generation mechanism. - * - * @see Assert - */ + +/** + * This routine does the main work for the + * exception generation mechanism used in the + * #Assert# macro. + * + * @see ExceptionBase + */ template -void __IssueError (const char *file, - int line, - const char *function, - const char *cond, - const char *exc_name, - exc e) { +void __IssueError_Assert (const char *file, + int line, + const char *function, + const char *cond, + const char *exc_name, + exc e) { // Fill the fields of the exception object - e.SetFields (file, line, function, cond, exc_name); - cerr << "--------------------------------------------------------" - << endl; - // print out general data - e.PrintExcData (cerr); - // print out exception specific data - e.PrintInfo (cerr); - cerr << "--------------------------------------------------------" - << endl; - - abort (); - }; + e.SetFields (file, line, function, cond, exc_name); + cerr << "--------------------------------------------------------" + << endl; + // print out general data + e.PrintExcData (cerr); + // print out exception specific data + e.PrintInfo (cerr); + cerr << "--------------------------------------------------------" + << endl; + + abort (); +}; + + + +/** + * This routine does the main work for the + * exception generation mechanism used in the + * #AssertThrow# macro. + * + * @see ExceptionBase + */ +template +void __IssueError_Throw (const char *file, + int line, + const char *function, + const char *cond, + const char *exc_name, + exc e) { + // Fill the fields of the exception object + e.SetFields (file, line, function, cond, exc_name); + throw e; +}; + #ifdef DEBUG //////////////////////////////////////// /** - This is the main routine in the exception mechanism. - Use it in the following way: declare an exception - class using the #DeclException# macros (see there), - for example - \begin{verbatim} - DeclException2 (ExcDomain, int, int, - << "Index= " << arg1 << "Upper Bound= " << arg2); - \end{verbatim} - to declare an exception class named #ExcDomain#, which - has two variables as additional information (named - #arg1# and #arg2# by default) and which outputs the - given sequence (which is appended to an #ostream# - variable's name, thus the weird syntax). There are - other #DeclExceptionN# macros for exception classes - with more or no parameters. It is proposed to let start - the name of all exceptions by #Exc...#. - - In your source code write lines like - \begin{verbatim} - Assert (nm, ExcSomewhat());# - - {\bf How it works internally:} - The call #Assert (cond, exc);# - is converted by the preprocessor into the sequence - \begin{verbatim} - if (!(cond)) - __IssueError (__FILE__, - __LINE__, - __PRETTY_FUNCTION__, - #cond, - #exc, - &exc); - \end{verbatim} - i.e. if the given condition is violated, then the file and - line in which the exception occured as well as - the condition itself and the call sequence of the - exception object is transferred. Additionally an object - of the form given by #exc# is created (this is normally an - unnamed object like in #ExcDomain (n, dim)# of class - #ExcDomain#) and transferred to the #__IssueError# - function. - - #__PRETTY__FUNCTION__# is a macro defined only by the GNU CC - compiler and gives the name of the function. If another compiler - is used, we set #__PRETTY_FUNCTION__ = "(unknown)"#. - - In #__IssueError# the given data - is transferred into the #exc# object by calling the - #SetFields# function; after that, the general error info - is printed onto #cerr# using the #PrintError# function of - #exc# and finally the exception specific data is printed - using the user defined function #PrintError# (which is - normally created using the #DeclException (...)# macro - family. - - After printing all this information, #abort()# is called. - This may in future versions be replaced by calling - #throw exc;#. - - If the preprocessor variable #DEBUG# is not set, then nothing - happens, i.e. the macro is expanded to #(void) 0;#. - - @memo Assert that a certain condition is fulfilled, otherwise - issue an error and abort the program. - - @see DeclException0 - @author Wolfgang Bangerth, November 1997 - */ -#define Assert(cond, exc) \ - if (!(cond)) \ - __IssueError (__FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__, #cond, #exc, exc) + * This is the main routine in the exception mechanism for debug mode + * error checking. See the + * #ExceptionBase# class for more information. + * + * @memo Assert that a certain condition is fulfilled, otherwise + * issue an error and abort the program. + * @see ExceptionBase + * @author Wolfgang Bangerth, November 1997, extensions 1998 + */ +#define Assert(cond, exc) \ + if (!(cond)) \ + __IssueError_Assert (__FILE__, \ + __LINE__, \ + __PRETTY_FUNCTION__, #cond, #exc, exc) #else //////////////////////////////////////// @@ -270,100 +435,62 @@ void __IssueError (const char *file, /** - Declare an exception class without any additional parameters. - There is a whole family of #DeclException?# macros - where #?# is to be replaced by the number of additional - parameters (0 to 5 presently). - - The syntax is as follows: - \begin{verbatim} - DeclException2 (ExcDomain, - int, - int, - << " i=" << arg1 << ", m=" << arg2); - \end{verbatim} - The first is the name of the exception class to be created. - The next arguments are the types of the parameters (in this - case there are two type names needed) and finally the output - sequence with which you can print additional information. - - The syntax of the output sequence is a bit weird but gets - clear once you see how this macro is defined: - \begin{verbatim} - class name : public ExceptionBase { - public: - name (const type1 a1, const type2 a2) : - arg1 (a1), arg2(a2) {}; - void PrintInfo (ostream &out) const { - out outsequence << endl; - }; - private: - type1 arg1; - type2 arg2; - }; - \end{verbatim} - The #PrintInfo# function is not declared #virtual# since we would - then create a class with virtual functions and only inlined code. - For this kind of class at least GNU C++ does not know where to put - the virtual method table and the program will not be compiled. - - If declared as specified, you can later use this exception class - in the following manner: - \begin{verbatim} - int i=5; - int m=3; - Assert (i of file . - The violated condition was: - i &p) { out << p[i] << ' '; out << p[dim-1]; - if (!out) - throw GlobalExcIO (); - return out; }; @@ -370,9 +367,6 @@ inline ostream & operator << (ostream &out, const Tensor<1,1> &p) { out << p[0]; - if (!out) - throw GlobalExcIO (); - return out; }; diff --git a/deal.II/base/source/parameter_handler.cc b/deal.II/base/source/parameter_handler.cc index 2cafb3adcf..186a07d722 100644 --- a/deal.II/base/source/parameter_handler.cc +++ b/deal.II/base/source/parameter_handler.cc @@ -131,8 +131,7 @@ ParameterHandler::~ParameterHandler () {}; bool ParameterHandler::read_input (istream &input) { - if (!input) - throw GlobalExcIO (); + AssertThrow (input, ExcIO()); string line; int lineno=0; @@ -361,9 +360,8 @@ ostream & ParameterHandler::print_parameters (ostream &out, OutputStyle style) { // given as "style" Assert ((style == Text) || (style == LaTeX), ExcNotImplemented()); - if (!out) - throw GlobalExcIO (); - + AssertThrow (out, ExcIO()); + switch (style) { case Text: @@ -406,8 +404,7 @@ void ParameterHandler::print_parameters_section (ostream &out, // given as "style" Assert ((style == Text) || (style == LaTeX), ExcNotImplemented()); - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); Section *pd = get_present_defaults_subsection (); Section *pc = get_present_changed_subsection (); @@ -728,8 +725,7 @@ MultipleParameterLoop::~MultipleParameterLoop () {}; bool MultipleParameterLoop::read_input (istream &input) { - if (!input) - throw GlobalExcIO (); + AssertThrow (input, ExcIO()); bool x = ParameterHandler::read_input (input); if (x) init_branches (); diff --git a/deal.II/deal.II/include/dofs/dof_constraints.h b/deal.II/deal.II/include/dofs/dof_constraints.h index 88daaf2bad..4afb7c20f5 100644 --- a/deal.II/deal.II/include/dofs/dof_constraints.h +++ b/deal.II/deal.II/include/dofs/dof_constraints.h @@ -289,6 +289,10 @@ class ConstraintMatrix { * Exception */ DeclException0 (ExcWrongDimension); + /** + * Exception + */ + DeclException0 (ExcIO); private: diff --git a/deal.II/deal.II/include/grid/tria.h b/deal.II/deal.II/include/grid/tria.h index b08baa758b..f51f9844ed 100644 --- a/deal.II/deal.II/include/grid/tria.h +++ b/deal.II/deal.II/include/grid/tria.h @@ -2423,6 +2423,10 @@ class Triangulation : public TriaDimensionInfo, public Subscriptor { * Exception */ DeclException0 (ExcInvalidParameterValue); + /** + * Exception + */ + DeclException0 (ExcIO); //@} protected: diff --git a/deal.II/deal.II/include/numerics/data_io.h b/deal.II/deal.II/include/numerics/data_io.h index 22974a278c..144def8426 100644 --- a/deal.II/deal.II/include/numerics/data_io.h +++ b/deal.II/deal.II/include/numerics/data_io.h @@ -170,6 +170,10 @@ class DataIn { * Exception */ DeclException0 (ExcInternalError); + /** + * Exception + */ + DeclException0 (ExcIO); private: /** @@ -423,6 +427,37 @@ class DataOut { * object of this class. */ static string default_suffix (const OutputFormat output_format); + + /** + * Return the #OutputFormat# value + * corresponding to the given string. If + * the string does not match any known + * format, an exception is thrown. + * + * Since this function does not need data + * from this object, it is static and can + * thus be called without creating an + * object of this class. Its main purpose + * is to allow a program to use any + * implemented output format without the + * need to extend the program's parser + * each time a new format is implemented. + * + * To get a list of presently available + * format names, e.g. to give it to the + * #ParameterHandler# class, use the + * function #get_output_format_names ()#. + */ + static OutputFormat parse_output_format (const string format_name); + + /** + * Return a list of implemented output + * formats. The different names are + * separated by vertical bar signs (#`|'#) + * as used by the #ParameterHandler# + * classes. + */ + static string get_output_format_names (); /** * Exception @@ -452,6 +487,14 @@ class DataOut { << "Please use only the characters [a-zA-Z0-9_<>()] for" << endl << "description strings since AVS will only accept these." << endl << "The string you gave was <" << arg1 << ">."); + /** + * Exception + */ + DeclException0 (ExcIO); + /** + * Exception + */ + DeclException0 (ExcInvalidState); private: diff --git a/deal.II/deal.II/source/dofs/dof_constraints.cc b/deal.II/deal.II/source/dofs/dof_constraints.cc index 12aec083a4..c06c3f6c66 100644 --- a/deal.II/deal.II/source/dofs/dof_constraints.cc +++ b/deal.II/deal.II/source/dofs/dof_constraints.cc @@ -706,6 +706,5 @@ void ConstraintMatrix::print (ostream &out) const { << " " << lines[i].entries[j].first << ": " << lines[i].entries[j].second << endl; - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); }; diff --git a/deal.II/deal.II/source/grid/tria.cc b/deal.II/deal.II/source/grid/tria.cc index 0b336ebe53..ce65300c09 100644 --- a/deal.II/deal.II/source/grid/tria.cc +++ b/deal.II/deal.II/source/grid/tria.cc @@ -2225,16 +2225,14 @@ void Triangulation::print_gnuplot (ostream &out, const unsigned int level) active_cell_iterator(end()) : begin_active (level+1)); - if (!out) - throw GlobalExcIO (); - + AssertThrow (out, ExcIO()); + out << "#Active cells on level " << level << ": " << n_active_cells (level) << endl; for (; cell != endc; ++cell) print_gnuplot (out, cell); - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); }; @@ -2244,15 +2242,13 @@ void Triangulation::print_gnuplot (ostream &out, const unsigned int level) template <> void Triangulation<1>::print_gnuplot (ostream &out, const active_cell_iterator & cell) const { - if (!out) - throw GlobalExcIO (); - + AssertThrow (out, ExcIO()); + out << cell->vertex(0) << " " << cell->level() << endl << cell->vertex(1) << " " << cell->level() << endl << endl; - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); }; #endif @@ -2263,9 +2259,8 @@ void Triangulation<1>::print_gnuplot (ostream &out, template <> void Triangulation<2>::print_gnuplot (ostream &out, const active_cell_iterator & cell) const { - if (!out) - throw GlobalExcIO (); - + AssertThrow (out, ExcIO()); + out << cell->vertex(0) << " " << cell->level() << endl << cell->vertex(1) << " " << cell->level() << endl << cell->vertex(2) << " " << cell->level() << endl @@ -2274,8 +2269,7 @@ void Triangulation<2>::print_gnuplot (ostream &out, << endl // double new line for gnuplot 3d plots << endl; - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); }; #endif @@ -3861,9 +3855,8 @@ void Triangulation::write_bool_vector (const unsigned int magic_number1, for (unsigned int position=0; position::write_bool_vector (const unsigned int magic_number1, delete[] flags; - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); }; @@ -3888,8 +3880,7 @@ void Triangulation::read_bool_vector (const unsigned int magic_number1, vector &v, const unsigned int magic_number2, istream &in) { - if (!in) - throw GlobalExcIO (); + AssertThrow (in, ExcIO()); unsigned int magic_number; in >> magic_number; @@ -3915,8 +3906,7 @@ void Triangulation::read_bool_vector (const unsigned int magic_number1, delete[] flags; - if (!in) - throw GlobalExcIO (); + AssertThrow (in, ExcIO()); }; diff --git a/deal.II/deal.II/source/numerics/data_io.cc b/deal.II/deal.II/source/numerics/data_io.cc index 0c2a00e2b5..9ab3f2b8fc 100644 --- a/deal.II/deal.II/source/numerics/data_io.cc +++ b/deal.II/deal.II/source/numerics/data_io.cc @@ -42,9 +42,8 @@ void DataIn::read_ucd (istream &in) { Assert (tria != 0, ExcNoTriangulationSelected()); Assert ((1<=dim) && (dim<=2), ExcNotImplemented()); - if (!in) - throw GlobalExcIO (); - + AssertThrow (in, ExcIO()); + // skip comments at start of file char c; while (in.get(c), c=='#') @@ -164,8 +163,7 @@ void DataIn::read_ucd (istream &in) { // check that no forbidden arrays are used Assert (subcelldata.check_consistency(dim), ExcInternalError()); - if (!in) - throw GlobalExcIO (); + AssertThrow (in, ExcIO()); tria->create_triangulation (vertices, cells, subcelldata); }; @@ -388,9 +386,9 @@ void DataOut::write_ucd (ostream &out) const { }; // no cell data // no model data - if (!out) - throw GlobalExcIO (); + // assert the stream is still ok + AssertThrow (out, ExcIO()); }; @@ -461,8 +459,7 @@ void DataOut::write_ucd_faces (ostream &out, ++index; }; - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); }; @@ -589,9 +586,8 @@ void DataOut::write_gnuplot (ostream &out, unsigned int accuracy) const out << endl; } delete [] values; - - if (!out) - throw GlobalExcIO (); + + AssertThrow (out, ExcIO()); } @@ -701,8 +697,7 @@ void DataOut::write_gnuplot_draft (ostream &out) const }; }; - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); }; @@ -797,8 +792,7 @@ void DataOut<2>::write_povray (ostream &out) const { }; out << "}"; - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); }; @@ -846,6 +840,32 @@ string DataOut::default_suffix (const OutputFormat output_format) { +template +DataOut::OutputFormat +DataOut::parse_output_format (const string format_name) { + if (format_name == "ucd") + return ucd; + + if (format_name == "gnuplot") + return gnuplot; + + if (format_name == "gnuplot draft") + return gnuplot_draft; + + if (format_name == "povray") + return povray; + + AssertThrow (false, ExcInvalidState ()); +}; + + + +template +string DataOut::get_output_format_names () { + return "ucd|gnuplot|gnuplot draft|povray"; +}; + + //explicite instantiations diff --git a/deal.II/lac/include/lac/dfmatrix.h b/deal.II/lac/include/lac/dfmatrix.h index a133e30372..34e85950a1 100644 --- a/deal.II/lac/include/lac/dfmatrix.h +++ b/deal.II/lac/include/lac/dfmatrix.h @@ -479,6 +479,10 @@ class dFMatrix int, << "This function is not implemented for the given" << " matrix dimension " << arg1); + /** + * Exception + */ + DeclException0 (ExcIO); }; diff --git a/deal.II/lac/include/lac/dsmatrix.h b/deal.II/lac/include/lac/dsmatrix.h index 4de7d590d6..4a8f5f3019 100644 --- a/deal.II/lac/include/lac/dsmatrix.h +++ b/deal.II/lac/include/lac/dsmatrix.h @@ -317,6 +317,10 @@ class dSMatrixStruct * Exception */ DeclException0 (ExcInternalError); + /** + * Exception + */ + DeclException0 (ExcIO); private: unsigned int max_dim; @@ -693,7 +697,11 @@ class dSMatrix * Exception */ DeclException0 (ExcDifferentSparsityPatterns); - + /** + * Exception + */ + DeclException0 (ExcIO); + private: const dSMatrixStruct * cols; double* val; diff --git a/deal.II/lac/include/lac/dvector.h b/deal.II/lac/include/lac/dvector.h index 2ed3a1452a..39f61eaf6e 100644 --- a/deal.II/lac/include/lac/dvector.h +++ b/deal.II/lac/include/lac/dvector.h @@ -410,6 +410,10 @@ class dVector { * Exception */ DeclException0 (ExcEmptyVector); + /** + * Exception + */ + DeclException0 (ExcIO); }; diff --git a/deal.II/lac/source/dfmatrix.cc b/deal.II/lac/source/dfmatrix.cc index 8dfd49e033..fb00b87441 100644 --- a/deal.II/lac/source/dfmatrix.cc +++ b/deal.II/lac/source/dfmatrix.cc @@ -1111,8 +1111,7 @@ void dFMatrix::print_formatted (ostream &out, const unsigned int precision) cons out << endl; }; - if (!out) - throw GlobalExcIO (); - + AssertThrow (out, ExcIO()); + out.setf (0, ios::floatfield); // reset output format }; diff --git a/deal.II/lac/source/dsmatrix.cc b/deal.II/lac/source/dsmatrix.cc index 89203aa238..cc1925ef70 100644 --- a/deal.II/lac/source/dsmatrix.cc +++ b/deal.II/lac/source/dsmatrix.cc @@ -332,8 +332,7 @@ dSMatrixStruct::print_gnuplot (ostream &out) const if (colnums[j]>=0) out << i << " " << -colnums[j] << endl; - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); } @@ -756,8 +755,7 @@ void dSMatrix::print (ostream &out) const { for (unsigned int j=cols->rowstart[i]; jrowstart[i+1]; ++j) out << "(" << i << "," << cols->colnums[j] << ") " << val[j] << endl; - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); }; @@ -778,8 +776,7 @@ void dSMatrix::print_formatted (ostream &out, const unsigned int precision) cons out << setw(precision+8) << " "; out << endl; }; - if (!out) - throw GlobalExcIO (); + AssertThrow (out, ExcIO()); out.setf (0, ios::floatfield); // reset output format }; diff --git a/deal.II/lac/source/dvector.cc b/deal.II/lac/source/dvector.cc index 6001a6b4a1..c033fe6fd7 100644 --- a/deal.II/lac/source/dvector.cc +++ b/deal.II/lac/source/dvector.cc @@ -512,8 +512,7 @@ void dVector::print (ostream &out) const { for (unsigned int i=0; i