kaldi-error.h
Go to the documentation of this file.
1 // base/kaldi-error.h
2 
3 // Copyright 2019 LAIX (Yi Sun)
4 // Copyright 2019 SmartAction LLC (kkm)
5 // Copyright 2016 Brno University of Technology (author: Karel Vesely)
6 // Copyright 2009-2011 Microsoft Corporation; Ondrej Glembek; Lukas Burget;
7 // Saarland University
8 
9 // See ../../COPYING for clarification regarding multiple authors
10 //
11 // Licensed under the Apache License, Version 2.0 (the "License");
12 // you may not use this file except in compliance with the License.
13 // You may obtain a copy of the License at
14 //
15 // http://www.apache.org/licenses/LICENSE-2.0
16 //
17 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
19 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
20 // MERCHANTABLITY OR NON-INFRINGEMENT.
21 // See the Apache 2 License for the specific language governing permissions and
22 // limitations under the License.
23 
24 #ifndef KALDI_BASE_KALDI_ERROR_H_
25 #define KALDI_BASE_KALDI_ERROR_H_ 1
26 
27 #include <cstdio>
28 #include <cstring>
29 #include <sstream>
30 #include <stdexcept>
31 #include <string>
32 #include <vector>
33 
34 #include "base/kaldi-types.h"
35 #include "base/kaldi-utils.h"
36 /* Important that this file does not depend on any other kaldi headers. */
37 
38 #ifdef _MSC_VER
39 #define __func__ __FUNCTION__
40 #endif
41 
42 namespace kaldi {
43 
46 
47 /***** PROGRAM NAME AND VERBOSITY LEVEL *****/
48 
53 void SetProgramName(const char *basename);
54 
58 
61 
64 inline void SetVerboseLevel(int32 i) { g_kaldi_verbose_level = i; }
65 
66 /***** KALDI LOGGING *****/
67 
74  enum Severity {
76  kError = -2,
77  kWarning = -1,
78  kInfo = 0,
79  };
80  int severity;
81  const char *func;
82  const char *file;
83  int32 line; //<! Line number in the source file.
84 };
85 
89 class KaldiFatalError : public std::runtime_error {
90 public:
91  explicit KaldiFatalError(const std::string &message)
92  : std::runtime_error(message) {}
93  explicit KaldiFatalError(const char *message) : std::runtime_error(message) {}
94 
96  virtual const char *what() const noexcept override {
97  return "kaldi::KaldiFatalError";
98  }
99 
101  const char *KaldiMessage() const { return std::runtime_error::what(); }
102 };
103 
104 // Class MessageLogger is the workhorse behind the KALDI_ASSERT, KALDI_ERR,
105 // KALDI_WARN, KALDI_LOG and KALDI_VLOG macros. It formats the message, then
106 // either prints it to stderr or passes to the custom logging handler if
107 // provided. Then, in case of the error, throws a KaldiFatalError exception, or
108 // in case of failed KALDI_ASSERT, calls std::abort().
110 public:
112  // identifies the location in source which is sending the message to log.
113  // The pointers to strings are stored internally, and not owned or copied,
114  // so that their storage must outlive this object.
116  const char *file, int32 line);
117 
118  // The stream insertion operator, used in e.g. 'KALDI_LOG << "Message"'.
119  template <typename T> MessageLogger &operator<<(const T &val) {
120  ss_ << val;
121  return *this;
122  }
123 
124  // When assigned a MessageLogger, log its contents.
125  struct Log final {
126  void operator=(const MessageLogger &logger) { logger.LogMessage(); }
127  };
128 
129  // When assigned a MessageLogger, log its contents and then throw
130  // a KaldiFatalError.
131  struct LogAndThrow final {
132  [[noreturn]] void operator=(const MessageLogger &logger) {
133  logger.LogMessage();
134  throw KaldiFatalError(logger.GetMessage());
135  }
136  };
137 
138 private:
139  std::string GetMessage() const { return ss_.str(); }
140  void LogMessage() const;
141 
143  std::ostringstream ss_;
144 };
145 
146 // Logging macros.
147 #define KALDI_ERR \
148  ::kaldi::MessageLogger::LogAndThrow() = ::kaldi::MessageLogger( \
149  ::kaldi::LogMessageEnvelope::kError, __func__, __FILE__, __LINE__)
150 #define KALDI_WARN \
151  ::kaldi::MessageLogger::Log() = ::kaldi::MessageLogger( \
152  ::kaldi::LogMessageEnvelope::kWarning, __func__, __FILE__, __LINE__)
153 #define KALDI_LOG \
154  ::kaldi::MessageLogger::Log() = ::kaldi::MessageLogger( \
155  ::kaldi::LogMessageEnvelope::kInfo, __func__, __FILE__, __LINE__)
156 #define KALDI_VLOG(v) \
157  if ((v) <= ::kaldi::GetVerboseLevel()) \
158  ::kaldi::MessageLogger::Log() = \
159  ::kaldi::MessageLogger((::kaldi::LogMessageEnvelope::Severity)(v), \
160  __func__, __FILE__, __LINE__)
161 
162 /***** KALDI ASSERTS *****/
163 
164 [[noreturn]] void KaldiAssertFailure_(const char *func, const char *file,
165  int32 line, const char *cond_str);
166 
167 // Note on KALDI_ASSERT and KALDI_PARANOID_ASSERT:
168 //
169 // A single block {} around if /else does not work, because it causes
170 // syntax error (unmatched else block) in the following code:
171 //
172 // if (condition)
173 // KALDI_ASSERT(condition2);
174 // else
175 // SomethingElse();
176 //
177 // do {} while(0) -- note there is no semicolon at the end! -- works nicely,
178 // and compilers will be able to optimize the loop away (as the condition
179 // is always false).
180 //
181 // Also see KALDI_COMPILE_TIME_ASSERT, defined in base/kaldi-utils.h, and
182 // KALDI_ASSERT_IS_INTEGER_TYPE and KALDI_ASSERT_IS_FLOATING_TYPE, also defined
183 // there.
184 #ifndef NDEBUG
185 #define KALDI_ASSERT(cond) \
186  do { \
187  if (cond) \
188  (void)0; \
189  else \
190  ::kaldi::KaldiAssertFailure_(__func__, __FILE__, __LINE__, #cond); \
191  } while (0)
192 #else
193 #define KALDI_ASSERT(cond) (void)0
194 #endif
195 
196 // Some more expensive asserts only checked if this defined.
197 #ifdef KALDI_PARANOID
198 #define KALDI_PARANOID_ASSERT(cond) \
199  do { \
200  if (cond) \
201  (void)0; \
202  else \
203  ::kaldi::KaldiAssertFailure_(__func__, __FILE__, __LINE__, #cond); \
204  } while (0)
205 #else
206 #define KALDI_PARANOID_ASSERT(cond) (void)0
207 #endif
208 
209 /***** THIRD-PARTY LOG-HANDLER *****/
210 
212 typedef void (*LogHandler)(const LogMessageEnvelope &envelope,
213  const char *message);
214 
221 
223 
224 // Functions within internal is exported for testing only, do not use.
225 namespace internal {
226 bool LocateSymbolRange(const std::string &trace_name, size_t *begin,
227  size_t *end);
228 } // namespace internal
229 } // namespace kaldi
230 
231 #endif // KALDI_BASE_KALDI_ERROR_H_
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
KaldiFatalError(const char *message)
Definition: kaldi-error.h:93
const char * func
Name of the function invoking the logging.
Definition: kaldi-error.h:81
void LogMessage() const
Definition: kaldi-error.cc:183
MessageLogger & operator<<(const T &val)
Definition: kaldi-error.h:119
const char * file
Source file name with up to 1 leading directory.
Definition: kaldi-error.h:82
int32 GetVerboseLevel()
Get verbosity level, usually set via command line &#39;–verbose=&#39; switch.
Definition: kaldi-error.h:60
std::ostringstream ss_
Definition: kaldi-error.h:143
void SetProgramName(const char *basename)
Called by ParseOptions to set base name (no directory) of the executing program.
Definition: kaldi-error.cc:50
void KaldiAssertFailure_(const char *func, const char *file, int32 line, const char *cond_str)
Definition: kaldi-error.cc:232
kaldi::int32 int32
void(* LogHandler)(const LogMessageEnvelope &envelope, const char *message)
Type of third-party logging function.
Definition: kaldi-error.h:212
Kaldi fatal runtime error exception.
Definition: kaldi-error.h:89
LogMessageEnvelope envelope_
Definition: kaldi-error.h:142
Informational message.
Definition: kaldi-error.h:78
void SetVerboseLevel(int32 i)
This should be rarely used, except by programs using Kaldi as library; command-line programs set the ...
Definition: kaldi-error.h:64
const char * KaldiMessage() const
Returns the Kaldi error message logged by KALDI_ERR.
Definition: kaldi-error.h:101
KaldiFatalError(const std::string &message)
Definition: kaldi-error.h:91
void operator=(const MessageLogger &logger)
Definition: kaldi-error.h:126
Severity
Message severity.
Definition: kaldi-error.h:74
LogHandler SetLogHandler(LogHandler handler)
Set logging handler.
Definition: kaldi-error.cc:243
std::string GetMessage() const
Definition: kaldi-error.h:139
Fatal error. KaldiFatalError will be thrown.
Definition: kaldi-error.h:76
int32 g_kaldi_verbose_level
This is set by util/parse-options.
Definition: kaldi-error.cc:46
void operator=(const MessageLogger &logger)
Definition: kaldi-error.h:132
virtual const char * what() const noexcept override
Returns the exception name, "kaldi::KaldiFatalError".
Definition: kaldi-error.h:96
Assertion failure. abort() will be called.
Definition: kaldi-error.h:75
bool LocateSymbolRange(const std::string &trace_name, size_t *begin, size_t *end)
Definition: kaldi-error.cc:79
Indicates a recoverable but abnormal condition.
Definition: kaldi-error.h:77
Log message severity and source location info.
Definition: kaldi-error.h:69
int severity
A Severity value, or positive verbosity level.
Definition: kaldi-error.h:80