Index: src/lemon/error.h
===================================================================
--- src/lemon/error.h	(revision 1164)
+++ src/lemon/error.h	(revision 1207)
@@ -33,6 +33,64 @@
 namespace lemon {
 
-/// \addtogroup exceptions
-/// @{
+  /// \addtogroup exceptions
+  /// @{
+  
+  /// \brief Exception safe wrapper class.
+  ///
+  /// Exception safe wrapper class to implement the members of exceptions.
+  template <typename _Type>
+  class ExceptionMember {
+  public:
+    typedef _Type Type;
+
+    ExceptionMember() throw () {
+      try {
+	ptr.reset(new Type());
+      } catch (...) {}
+    }
+
+    ExceptionMember(const Type& type) throw () {
+      try {
+	ptr.reset(new Type());
+	if (ptr.get() == 0) return;
+	*ptr = type;
+      } catch (...) {}
+    }
+
+    ExceptionMember(const ExceptionMember& copy) throw() {
+      try {
+	if (!copy.valid()) return;
+	ptr.reset(new Type());
+	if (ptr.get() == 0) return;
+	*ptr = copy.get();
+      } catch (...) {}
+    }
+
+    ExceptionMember& operator=(const ExceptionMember& copy) {
+      if (ptr.get() == 0) return;
+      try {
+	if (!copy.valid()) return;
+ 	*ptr = copy.get();
+      } catch (...) {}
+    }
+
+    void set(const Type& type) {
+      if (ptr.get() == 0) return;
+      try {
+	*ptr = type;
+      } catch (...) {}
+    }
+
+    const Type& get() const {
+      return *ptr;
+    }
+
+    bool valid() const {
+      return ptr.get() != 0;
+    }
+    
+  private:
+    std::auto_ptr<_Type> ptr;
+  };
 
   /// Exception-safe convenient "error message" class.
@@ -89,4 +147,5 @@
 	buf.reset();
       }
+      return *this;
     }
 
@@ -191,20 +250,19 @@
   class DataFormatError : public IOError {
   protected:
-    const char *_message;
+    ExceptionMember<std::string> _message;
+    ExceptionMember<std::string> _file;
     int _line;
 
-    ///\todo Much better solution is boost::shared_ptr
-    mutable
-    std::auto_ptr<std::string> _file;
-
+    mutable ExceptionMember<std::string> _message_holder;
   public:
 
     DataFormatError(const DataFormatError &dfe) : 
-      IOError(dfe), _message(dfe._message), _line(dfe._line),
-      _file(dfe._file) {}
+      IOError(dfe), _message(dfe._message), _file(dfe._file),
+      _line(dfe._line) {}
 
     ///\e 
     explicit DataFormatError(const char *the_message)
       : _message(the_message), _line(0) {}
+
     ///\e 
     DataFormatError(const std::string &file_name, int line_num,
@@ -213,50 +271,48 @@
 
     ///\e 
-    void line(int line_num) { _line=line_num; }
-    ///\e 
-    void message(char *the_message) { _message=the_message; }
-    ///\e 
-    void file(const std::string &file_name) {
-      try {
-	_file.reset(new std::string);
-	*_file = file_name;
-      }
-      catch(...) {
-	_file.reset();
-      }
-    }
-
+    void line(int line) { _line = line; }
+    ///\e 
+    void message(const std::string& message) { _message.set(message); }
+    ///\e 
+    void file(const std::string &file) { _file.set(file); }
+ 
     ///\e
     int line() const { return _line; }
     ///\e
-    const char* message() const { return _message; }
+    const char* message() const { 
+      if (_message.valid() && !_message.get().empty()) {
+	return _message.get().c_str();
+      } else {
+	return 0;
+      }
+    }
 
     /// \brief Returns the filename.
     ///
-    /// Returns \e "(unknown)" if the filename was not specified.
+    /// Returns \e null if the filename was not specified.
     const char* file() const {
-      if( _file.get() )
-	return _file->c_str();
-      else
-	return "(unknown)";
+      if (_file.valid() && !_file.get().empty()) {
+	return _file.get().c_str();
+      } else {
+	return 0;
+      }
     }
 
     ///\e 
     virtual const char* what() const throw() {
-      const char *mes = 0;
       try {
 	std::ostringstream ostr;
-	ostr << _message;
-	if( _file.get() || _line ) {
+	if (message()) ostr << message();
+	if( file() || line() != 0 ) {
 	  ostr << " (";
-	  if( _file.get() ) ostr << "in file '" << *_file << "'";
-	  if( _file.get() && _line ) ostr << " ";
-	  if( _line ) ostr << "at line " << _line;
+	  if( file() ) ostr << "in file '" << file() << "'";
+	  if( file() && line() != 0 ) ostr << " ";
+	  if( line() != 0 ) ostr << "at line " << line();
 	  ostr << ")";
 	}
-	mes = ostr.str().c_str();
-      }
-      catch(...) {}
-      if( mes ) return mes;
+	_message_holder.set(ostr.str());
+      }
+      catch (...) {}
+      if( _message_holder.valid()) return _message_holder.get().c_str();
       return exceptionName();
     }
@@ -267,4 +323,70 @@
 
     virtual ~DataFormatError() throw() {}
+  };
+
+  class IOLogicError : public IOError, public LogicError {
+  protected:
+    ExceptionMember<std::string> _message;
+    ExceptionMember<std::string> _file;
+    int _line;
+
+    mutable ExceptionMember<std::string> _message_holder;
+  public:
+
+    IOLogicError(const IOLogicError &ile) : 
+      IOError(ile), LogicError(ile), 
+      _message(ile._message), _file(ile._file) {}
+
+    ///\e 
+    explicit IOLogicError(const char *the_message)
+      : _message(the_message), _line(0) {}
+
+    ///\e 
+    IOLogicError(const char *file_name, const char *the_message)
+      : _message(file_name), _file(file_name) {}
+
+     ///\e 
+    void message(const std::string& message) { _message.set(message); }
+    ///\e 
+    void file(const std::string &file) { _file.set(file); }
+ 
+     ///\e
+    const char* message() const { 
+      if (_message.valid()) {
+	return _message.get().c_str();
+      } else {
+	return 0;
+      }
+    }
+
+    /// \brief Returns the filename.
+    ///
+    /// Returns \e null if the filename was not specified.
+    const char* file() const {
+      if (_file.valid()) {
+	return _file.get().c_str();
+      } else {
+	return 0;
+      }
+    }
+
+    ///\e 
+    virtual const char* what() const throw() {
+      try {
+	std::ostringstream ostr;
+	if (message()) ostr << message();
+	if (file()) ostr << "(when reading file '" << file() << "')";
+	_message_holder.set(ostr.str());
+      }
+      catch (...) {}
+      if( _message_holder.valid() ) return _message_holder.get().c_str();
+      return exceptionName();
+    }
+
+    virtual const char* exceptionName() const {
+      return "lemon::IOLogicError";
+    }
+
+    virtual ~IOLogicError() throw() {}
   };
 
@@ -308,4 +430,6 @@
 	  ostr << " (assertion '" << assertion << "' failed)";
 	mes = ostr.str().c_str();
+	/// \bug Szerintem a 'mes'-re nem szabad hivatkozni, mert
+	/// az elobb felszabadul. 
       }
       catch(...) {}
