1 # generate-exceptions: generate C++ files for Xapian's exception hierarchy.
3 # Copyright (C) 2003,2004,2006,2007,2008,2009,2011,2012,2013,2014,2015,2019 Olly Betts
4 # Copyright (C) 2007 Richard Boulton
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License as
8 # published by the Free Software Foundation; either version 2 of the
9 # License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 use exception_data qw(
22 $copyright $generated_warning @baseclasses @classes %classcode
25 open HDR, ">include/xapian/error.h" or die $!;
26 open DISPATCH, ">include/xapian/errordispatch.h" or die $!;
30 * @brief Hierarchy of classes which Xapian can throw as exceptions.
34 print HDR $generated_warning;
35 print DISPATCH $generated_warning;
38 print DISPATCH $copyright;
42 #ifndef XAPIAN_INCLUDED_ERROR_H
43 #define XAPIAN_INCLUDED_ERROR_H
45 #if !defined XAPIAN_IN_XAPIAN_H && !defined XAPIAN_LIB_BUILD
46 # error Never use <xapian/error.h> directly; include <xapian.h> instead.
50 #include <xapian/attributes.h>
51 #include <xapian/visibility.h>
57 /** All exceptions thrown by Xapian are subclasses of Xapian::Error.
59 * This class can not be instantiated directly - instead a subclass should
62 class XAPIAN_VISIBILITY_DEFAULT Error {
63 // ErrorHandler needs to be able to access Error::already_handled.
64 friend class ErrorHandler;
66 /// Message giving details of the error, intended for human consumption.
69 /** Optional context information.
71 * This context is intended for use by Xapian::ErrorHandler (for example
72 * so it can know which remote server is unreliable and report the problem
73 * and remove that server from those being searched). But it's typically
74 * a plain-text string, and so also fit for human consumption.
78 /** The error string derived from my_errno.
80 * This string is generated from my_errno lazily.
82 mutable std::string error_string;
84 /// The type of this error (e.g. DocNotFoundError.)
87 /** Optional value of 'errno' associated with this error.
89 * If no value is associated, this member variable will be 0.
91 * On UNIX, if this value is < 0, it's an error code returned from
92 * getaddrinfo() (negated if such error codes are positive).
94 * On Windows, if this value is < 0, it's a negated Windows error code
95 * (as given by GetLastError()), while if it is >= WSABASEERR then it is a
96 * WinSock error code (as given by WSAGetLastError()). Prior to Xapian
97 * 1.2.20 and 1.3.3, WSAGetLastError() codes were also negated.
99 * NB We don't just call this member "errno" to avoid problems on
100 * platforms where errno is a preprocessor macro.
104 /// True if this error has already been passed to an ErrorHandler.
105 bool already_handled;
107 /// Don't allow assignment of the base class.
108 void operator=(const Error &o);
111 /** @private @internal
112 * @brief Constructor for use by constructors of derived classes.
114 Error(const std::string &msg_, const std::string &context_,
115 const char * type_, const char * error_string_);
117 /** @private @internal
118 * @brief Constructor for use by constructors of derived classes.
120 Error(const std::string &msg_, const std::string &context_,
121 const char * type_, int errno_)
122 : msg(msg_), context(context_), error_string(), type(type_),
123 my_errno(errno_), already_handled(false) { }
126 #if __cplusplus >= 201103L
127 /** Default copy constructor.
129 * We explicitly specify this to avoid warnings from GCC 9 (from
130 * -Wdeprecated-copy which is enabled by -Wextra).
132 Error(const Error&) = default;
135 /// The type of this error (e.g. "DocNotFoundError".)
136 const char * XAPIAN_NOTHROW(get_type() const) {
140 /// Message giving details of the error, intended for human consumption.
141 const std::string & XAPIAN_NOTHROW(get_msg() const) {
145 /** Optional context information.
147 * This context is intended for use by Xapian::ErrorHandler (for example
148 * so it can know which remote server is unreliable and report the problem
149 * and remove that server from those being searched). But it's typically
150 * a plain-text string, and so also fit for human consumption.
152 const std::string & XAPIAN_NOTHROW(get_context() const) {
156 /** Returns any system error string associated with this exception.
158 * The system error string may come from errno, h_errno (on UNIX), or
159 * GetLastError() (on MS Windows). If there is no associated system
160 * error string, NULL is returned.
162 const char * get_error_string() const;
164 /// Return a string describing this object.
165 std::string get_description() const;
169 print DISPATCH <<'EOF';
171 /* Note that this file isn't an external header - it's located in
172 * include/xapian in the source tree because it's generated so this
173 * is the simplest way to make inclusion work in a VPATH build.
176 // DOXYGEN gets confused by this header-with-code.
180 # Format description for embedding in C /* ... */ comment.
181 sub c_format_description {
183 if (defined $d && $d ne '') {
195 my ($class, $parent, $synopsis, $description) = @{$_};
196 $description = c_format_description($description);
201 class XAPIAN_VISIBILITY_DEFAULT $class : public $parent {
203 /** \@private \@internal
204 * \@brief Constructor for use by constructors of derived classes.
206 $class(const std::string \&msg_, const std::string \&context_, const char * type_, const char * error_string_)
207 : $parent(msg_, context_, type_, error_string_) {}
209 /** \@private \@internal
210 * \@brief Constructor for use by constructors of derived classes.
212 $class(const std::string \&msg_, const std::string \&context_, const char * type_, int errno_)
213 : $parent(msg_, context_, type_, errno_) {}
220 my ($class, $parent, $synopsis, $description) = @{$_};
221 $description = c_format_description($description);
222 my $code = sprintf('\%03o', $classcode{$class});
224 print DISPATCH "case '$code': throw Xapian::$class(msg, context, error_string);\n";
230 class XAPIAN_VISIBILITY_DEFAULT $class : public $parent {
232 /** \@private \@internal
233 * \@brief Private constructor for use by remote backend.
235 * \@param error_string_ Optional string describing error. May be NULL.
237 $class(const std::string \&msg_, const std::string \&context_, const char * error_string_)
238 : $parent(msg_, context_, "$code$class", error_string_) {}
239 /** General purpose constructor.
241 * \@param msg_ Message giving details of the error, intended
242 * for human consumption.
243 * \@param context_ Optional context information for this error.
244 * \@param errno_ Optional errno value associated with this error.
246 explicit $class(const std::string \&msg_, const std::string \&context_ = std::string(), int errno_ = 0)
247 : $parent(msg_, context_, "$code$class", errno_) {}
248 /** Construct from message and errno value.
250 * \@param msg_ Message giving details of the error, intended
251 * for human consumption.
252 * \@param errno_ Optional errno value associated with this error.
254 $class(const std::string \&msg_, int errno_)
255 : $parent(msg_, std::string(), "$code$class", errno_) {}
257 /** \@private \@internal
258 * \@brief Constructor for use by constructors of derived classes.
260 $class(const std::string \&msg_, const std::string \&context_, const char * type_, const char * error_string_)
261 : $parent(msg_, context_, type_, error_string_) {}
263 /** \@private \@internal
264 * \@brief Constructor for use by constructors of derived classes.
266 $class(const std::string \&msg_, const std::string \&context_, const char * type_, int errno_)
267 : $parent(msg_, context_, type_, errno_) {}
276 #endif /* XAPIAN_INCLUDED_ERROR_H */
279 print DISPATCH <<'EOF';
284 close DISPATCH or die $!;
286 # vim: set syntax=perl: