diff options
| author | Kenneth Heafield <kenlm@kheafield.com> | 2011-07-07 21:01:38 -0400 | 
|---|---|---|
| committer | Kenneth Heafield <kenlm@kheafield.com> | 2011-07-07 21:01:38 -0400 | 
| commit | f68aaa588a2e1eb7cef5a57d57dd7e86fd4b0c9a (patch) | |
| tree | e2b6bc873303f5aac6e05961d30b316a6b3dcce3 | |
| parent | 71daf4bf0b91a247d0d1663ae7850a3db85a378d (diff) | |
Exception update
| -rw-r--r-- | klm/util/exception.cc | 28 | ||||
| -rw-r--r-- | klm/util/exception.hh | 56 | ||||
| -rw-r--r-- | klm/util/file_piece.cc | 42 | ||||
| -rw-r--r-- | klm/util/file_piece.hh | 34 | 
4 files changed, 117 insertions, 43 deletions
| diff --git a/klm/util/exception.cc b/klm/util/exception.cc index 84f9fe7c..62280970 100644 --- a/klm/util/exception.cc +++ b/klm/util/exception.cc @@ -1,5 +1,9 @@  #include "util/exception.hh" +#ifdef __GXX_RTTI +#include <typeinfo> +#endif +  #include <errno.h>  #include <string.h> @@ -22,6 +26,30 @@ const char *Exception::what() const throw() {    return text_.c_str();  } +void Exception::SetLocation(const char *file, unsigned int line, const char *func, const char *child_name, const char *condition) { +  /* The child class might have set some text, but we want this to come first. +   * Another option would be passing this information to the constructor, but +   * then child classes would have to accept constructor arguments and pass +   * them down.   +   */ +  text_ = stream_.str(); +  stream_.str(""); +  stream_ << file << ':' << line; +  if (func) stream_ << " in " << func << " threw "; +  if (child_name) { +    stream_ << child_name; +  } else { +#ifdef __GXX_RTTI +    stream_ << typeid(this).name(); +#else +    stream_ << "an exception"; +#endif +  } +  if (condition) stream_ << " because `" << condition; +  stream_ << "'.\n"; +  stream_ << text_; +} +  namespace {  // The XOPEN version.  const char *HandleStrerror(int ret, const char *buf) { diff --git a/klm/util/exception.hh b/klm/util/exception.hh index c6936914..81675a57 100644 --- a/klm/util/exception.hh +++ b/klm/util/exception.hh @@ -1,8 +1,6 @@  #ifndef UTIL_EXCEPTION__  #define UTIL_EXCEPTION__ -#include "util/string_piece.hh" -  #include <exception>  #include <sstream>  #include <string> @@ -22,6 +20,14 @@ class Exception : public std::exception {      // Not threadsafe, but probably doesn't matter.  FWIW, Boost's exception guidance implies that what() isn't threadsafe.        const char *what() const throw(); +    // For use by the UTIL_THROW macros.   +    void SetLocation( +        const char *file, +        unsigned int line, +        const char *func, +        const char *child_name, +        const char *condition); +    private:      template <class Except, class Data> friend typename Except::template ExceptionTag<Except&>::Identity operator<<(Except &e, const Data &data); @@ -43,7 +49,49 @@ template <class Except, class Data> typename Except::template ExceptionTag<Excep    return e;  } -#define UTIL_THROW(Exception, Modify) { Exception UTIL_e; {UTIL_e << Modify;} throw UTIL_e; } +#ifdef __GNUC__ +#define UTIL_FUNC_NAME __PRETTY_FUNCTION__ +#else +#ifdef _WIN32 +#define UTIL_FUNC_NAME __FUNCTION__ +#else +#define UTIL_FUNC_NAME NULL +#endif +#endif + +#define UTIL_SET_LOCATION(UTIL_e, child, condition) do { \ +  (UTIL_e).SetLocation(__FILE__, __LINE__, UTIL_FUNC_NAME, (child), (condition)); \ +} while (0) + +/* Create an instance of Exception, add the message Modify, and throw it. + * Modify is appended to the what() message and can contain << for ostream + * operations.   + * + * do .. while kludge to swallow trailing ; character + * http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html .   + */ +#define UTIL_THROW(Exception, Modify) do { \ +  Exception UTIL_e; \ +  UTIL_SET_LOCATION(UTIL_e, #Exception, NULL); \ +  UTIL_e << Modify; \ +  throw UTIL_e; \ +} while (0) + +#define UTIL_THROW_VAR(Var, Modify) do { \ +  Exception &UTIL_e = (Var); \ +  UTIL_SET_LOCATION(UTIL_e, NULL, NULL); \ +  UTIL_e << Modify; \ +  throw UTIL_e; \ +} while (0) + +#define UTIL_THROW_IF(Condition, Exception, Modify) do { \ +  if (Condition) { \ +    Exception UTIL_e; \ +    UTIL_SET_LOCATION(UTIL_e, #Exception, #Condition); \ +    UTIL_e << Modify; \ +    throw UTIL_e; \ +  } \ +} while (0)  class ErrnoException : public Exception {    public: @@ -51,7 +99,7 @@ class ErrnoException : public Exception {      virtual ~ErrnoException() throw(); -    int Error() { return errno_; } +    int Error() const throw() { return errno_; }    private:      int errno_; diff --git a/klm/util/file_piece.cc b/klm/util/file_piece.cc index f447a70c..cbe4234f 100644 --- a/klm/util/file_piece.cc +++ b/klm/util/file_piece.cc @@ -41,8 +41,8 @@ GZException::GZException(void *file) {  const bool kSpaces[256] = {0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  int OpenReadOrThrow(const char *name) { -  int ret = open(name, O_RDONLY); -  if (ret == -1) UTIL_THROW(ErrnoException, "in open (" << name << ") for reading"); +  int ret; +  UTIL_THROW_IF(-1 == (ret = open(name, O_RDONLY)), ErrnoException, "while opening " << name);    return ret;  } @@ -52,13 +52,13 @@ off_t SizeFile(int fd) {    return sb.st_size;  } -FilePiece::FilePiece(const char *name, std::ostream *show_progress, off_t min_buffer) throw (GZException) :  +FilePiece::FilePiece(const char *name, std::ostream *show_progress, off_t min_buffer) :     file_(OpenReadOrThrow(name)), total_size_(SizeFile(file_.get())), page_(sysconf(_SC_PAGE_SIZE)),    progress_(total_size_ == kBadSize ? NULL : show_progress, std::string("Reading ") + name, total_size_) {    Initialize(name, show_progress, min_buffer);  } -FilePiece::FilePiece(int fd, const char *name, std::ostream *show_progress, off_t min_buffer) throw (GZException) :  +FilePiece::FilePiece(int fd, const char *name, std::ostream *show_progress, off_t min_buffer)  :     file_(fd), total_size_(SizeFile(file_.get())), page_(sysconf(_SC_PAGE_SIZE)),    progress_(total_size_ == kBadSize ? NULL : show_progress, std::string("Reading ") + name, total_size_) {    Initialize(name, show_progress, min_buffer); @@ -78,7 +78,7 @@ FilePiece::~FilePiece() {  #endif  } -StringPiece FilePiece::ReadLine(char delim) throw (GZException, EndOfFileException) { +StringPiece FilePiece::ReadLine(char delim) {    size_t skip = 0;    while (true) {      for (const char *i = position_ + skip; i < position_end_; ++i) { @@ -97,20 +97,20 @@ StringPiece FilePiece::ReadLine(char delim) throw (GZException, EndOfFileExcepti    }  } -float FilePiece::ReadFloat() throw(GZException, EndOfFileException, ParseNumberException) { +float FilePiece::ReadFloat() {    return ReadNumber<float>();  } -double FilePiece::ReadDouble() throw(GZException, EndOfFileException, ParseNumberException) { +double FilePiece::ReadDouble() {    return ReadNumber<double>();  } -long int FilePiece::ReadLong() throw(GZException, EndOfFileException, ParseNumberException) { +long int FilePiece::ReadLong() {    return ReadNumber<long int>();  } -unsigned long int FilePiece::ReadULong() throw(GZException, EndOfFileException, ParseNumberException) { +unsigned long int FilePiece::ReadULong() {    return ReadNumber<unsigned long int>();  } -void FilePiece::Initialize(const char *name, std::ostream *show_progress, off_t min_buffer) throw (GZException) { +void FilePiece::Initialize(const char *name, std::ostream *show_progress, off_t min_buffer)  {  #ifdef HAVE_ZLIB    gz_file_ = NULL;  #endif @@ -163,7 +163,7 @@ void ParseNumber(const char *begin, char *&end, unsigned long int &out) {  }  } // namespace -template <class T> T FilePiece::ReadNumber() throw(GZException, EndOfFileException, ParseNumberException) { +template <class T> T FilePiece::ReadNumber() {    SkipSpaces();    while (last_space_ < position_) {      if (at_end_) { @@ -186,7 +186,7 @@ template <class T> T FilePiece::ReadNumber() throw(GZException, EndOfFileExcepti    return ret;  } -const char *FilePiece::FindDelimiterOrEOF(const bool *delim) throw (GZException, EndOfFileException) { +const char *FilePiece::FindDelimiterOrEOF(const bool *delim)  {    size_t skip = 0;    while (true) {      for (const char *i = position_ + skip; i < position_end_; ++i) { @@ -201,7 +201,7 @@ const char *FilePiece::FindDelimiterOrEOF(const bool *delim) throw (GZException,    }  } -void FilePiece::Shift() throw(GZException, EndOfFileException) { +void FilePiece::Shift() {    if (at_end_) {      progress_.Finished();      throw EndOfFileException(); @@ -217,7 +217,7 @@ void FilePiece::Shift() throw(GZException, EndOfFileException) {    }  } -void FilePiece::MMapShift(off_t desired_begin) throw() { +void FilePiece::MMapShift(off_t desired_begin) {    // Use mmap.      off_t ignore = desired_begin % page_;    // Duplicate request for Shift means give more data.   @@ -259,25 +259,23 @@ void FilePiece::MMapShift(off_t desired_begin) throw() {    progress_.Set(desired_begin);  } -void FilePiece::TransitionToRead() throw (GZException) { +void FilePiece::TransitionToRead() {    assert(!fallback_to_read_);    fallback_to_read_ = true;    data_.reset();    data_.reset(malloc(default_map_size_), default_map_size_, scoped_memory::MALLOC_ALLOCATED); -  if (!data_.get()) UTIL_THROW(ErrnoException, "malloc failed for " << default_map_size_); +  UTIL_THROW_IF(!data_.get(), ErrnoException, "malloc failed for " << default_map_size_);    position_ = data_.begin();    position_end_ = position_;  #ifdef HAVE_ZLIB    assert(!gz_file_);    gz_file_ = gzdopen(file_.get(), "r"); -  if (!gz_file_) { -    UTIL_THROW(GZException, "zlib failed to open " << file_name_); -  } +  UTIL_THROW_IF(!gz_file_, GZException, "zlib failed to open " << file_name_);  #endif  } -void FilePiece::ReadShift() throw(GZException, EndOfFileException) { +void FilePiece::ReadShift() {    assert(fallback_to_read_);    // Bytes [data_.begin(), position_) have been consumed.      // Bytes [position_, position_end_) have been read into the buffer.   @@ -297,7 +295,7 @@ void FilePiece::ReadShift() throw(GZException, EndOfFileException) {        std::size_t valid_length = position_end_ - position_;        default_map_size_ *= 2;        data_.call_realloc(default_map_size_); -      if (!data_.get()) UTIL_THROW(ErrnoException, "realloc failed for " << default_map_size_); +      UTIL_THROW_IF(!data_.get(), ErrnoException, "realloc failed for " << default_map_size_);        position_ = data_.begin();        position_end_ = position_ + valid_length;      } else { @@ -320,7 +318,7 @@ void FilePiece::ReadShift() throw(GZException, EndOfFileException) {    }  #else    read_return = read(file_.get(), static_cast<char*>(data_.get()) + already_read, default_map_size_ - already_read); -  if (read_return == -1) UTIL_THROW(ErrnoException, "read failed"); +  UTIL_THROW_IF(read_return == -1, ErrnoException, "read failed");    progress_.Set(mapped_offset_);  #endif    if (read_return == 0) { diff --git a/klm/util/file_piece.hh b/klm/util/file_piece.hh index 870ae5a3..a5c00910 100644 --- a/klm/util/file_piece.hh +++ b/klm/util/file_piece.hh @@ -45,13 +45,13 @@ off_t SizeFile(int fd);  class FilePiece {    public:      // 32 MB default. -    explicit FilePiece(const char *file, std::ostream *show_progress = NULL, off_t min_buffer = 33554432) throw(GZException); +    explicit FilePiece(const char *file, std::ostream *show_progress = NULL, off_t min_buffer = 33554432);      // Takes ownership of fd.  name is used for messages.   -    explicit FilePiece(int fd, const char *name, std::ostream *show_progress = NULL, off_t min_buffer = 33554432) throw(GZException); +    explicit FilePiece(int fd, const char *name, std::ostream *show_progress = NULL, off_t min_buffer = 33554432);      ~FilePiece(); -    char get() throw(GZException, EndOfFileException) {  +    char get() {         if (position_ == position_end_) {          Shift();          if (at_end_) throw EndOfFileException(); @@ -60,22 +60,22 @@ class FilePiece {      }      // Leaves the delimiter, if any, to be returned by get().  Delimiters defined by isspace().   -    StringPiece ReadDelimited(const bool *delim = kSpaces) throw(GZException, EndOfFileException) { +    StringPiece ReadDelimited(const bool *delim = kSpaces) {        SkipSpaces(delim);        return Consume(FindDelimiterOrEOF(delim));      }      // Unlike ReadDelimited, this includes leading spaces and consumes the delimiter.      // It is similar to getline in that way.   -    StringPiece ReadLine(char delim = '\n') throw(GZException, EndOfFileException); +    StringPiece ReadLine(char delim = '\n'); -    float ReadFloat() throw(GZException, EndOfFileException, ParseNumberException); -    double ReadDouble() throw(GZException, EndOfFileException, ParseNumberException); -    long int ReadLong() throw(GZException, EndOfFileException, ParseNumberException); -    unsigned long int ReadULong() throw(GZException, EndOfFileException, ParseNumberException); +    float ReadFloat(); +    double ReadDouble(); +    long int ReadLong(); +    unsigned long int ReadULong();      // Skip spaces defined by isspace.   -    void SkipSpaces(const bool *delim = kSpaces) throw (GZException, EndOfFileException) { +    void SkipSpaces(const bool *delim = kSpaces) {        for (; ; ++position_) {          if (position_ == position_end_) Shift();          if (!delim[static_cast<unsigned char>(*position_)]) return; @@ -89,9 +89,9 @@ class FilePiece {      const std::string &FileName() const { return file_name_; }    private: -    void Initialize(const char *name, std::ostream *show_progress, off_t min_buffer) throw(GZException); +    void Initialize(const char *name, std::ostream *show_progress, off_t min_buffer); -    template <class T> T ReadNumber() throw(GZException, EndOfFileException, ParseNumberException); +    template <class T> T ReadNumber();      StringPiece Consume(const char *to) {        StringPiece ret(position_, to - position_); @@ -99,14 +99,14 @@ class FilePiece {        return ret;      } -    const char *FindDelimiterOrEOF(const bool *delim = kSpaces) throw (GZException, EndOfFileException); +    const char *FindDelimiterOrEOF(const bool *delim = kSpaces); -    void Shift() throw (EndOfFileException, GZException); +    void Shift();      // Backends to Shift(). -    void MMapShift(off_t desired_begin) throw (); +    void MMapShift(off_t desired_begin); -    void TransitionToRead() throw (GZException); -    void ReadShift() throw (GZException, EndOfFileException); +    void TransitionToRead(); +    void ReadShift();      const char *position_, *last_space_, *position_end_; | 
