Update for 1.4.18
[xapian.git] / xapian-core / generate-exceptions
blobc574bfb35ab44501e1542d1be831c4a9d322a1e8
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
20 use strict;
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 $!;
28 print HDR <<'EOF';
29 /** @file
30  *  @brief Hierarchy of classes which Xapian can throw as exceptions.
31  */
32 EOF
34 print HDR $generated_warning;
35 print DISPATCH $generated_warning;
37 print HDR $copyright;
38 print DISPATCH $copyright;
40 print HDR <<'EOF';
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.
47 #endif
49 #include <string>
50 #include <xapian/attributes.h>
51 #include <xapian/visibility.h>
53 namespace Xapian {
55 class ErrorHandler;
57 /** All exceptions thrown by Xapian are subclasses of Xapian::Error.
58  *
59  *  This class can not be instantiated directly - instead a subclass should
60  *  be used.
61  */
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.
67     std::string msg;
69     /** Optional context information.
70      *
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.
75      */
76     std::string context;
78     /** The error string derived from my_errno.
79      *
80      *  This string is generated from my_errno lazily.
81      */
82     mutable std::string error_string;
84     /// The type of this error (e.g. DocNotFoundError.)
85     const char * type;
87     /** Optional value of 'errno' associated with this error.
88      *
89      *  If no value is associated, this member variable will be 0.
90      *
91      *  On UNIX, if this value is < 0, it's an error code returned from
92      *  getaddrinfo() (negated if such error codes are positive).
93      *
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.
98      *
99      *  NB We don't just call this member "errno" to avoid problems on
100      *  platforms where errno is a preprocessor macro.
101      */
102     int my_errno;
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);
110   protected:
111     /** @private @internal
112      *  @brief Constructor for use by constructors of derived classes.
113      */
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.
119      */
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) { }
125   public:
126 #if __cplusplus >= 201103L
127     /** Default copy constructor.
128      *
129      *  We explicitly specify this to avoid warnings from GCC 9 (from
130      *  -Wdeprecated-copy which is enabled by -Wextra).
131      */
132     Error(const Error&) = default;
133 #endif
135     /// The type of this error (e.g. "DocNotFoundError".)
136     const char * XAPIAN_NOTHROW(get_type() const) {
137         return type + 1;
138     }
140     /// Message giving details of the error, intended for human consumption.
141     const std::string & XAPIAN_NOTHROW(get_msg() const) {
142         return msg;
143     }
145     /** Optional context information.
146      *
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.
151      */
152     const std::string & XAPIAN_NOTHROW(get_context() const) {
153         return context;
154     }
156     /** Returns any system error string associated with this exception.
157      *
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.
161      */
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.
174  */
176 // DOXYGEN gets confused by this header-with-code.
177 #ifndef DOXYGEN
180 # Format description for embedding in C /* ... */ comment.
181 sub c_format_description {
182     my $d = shift;
183     if (defined $d && $d ne '') {
184         $d =~ s!^! *  !mg;
185         $d =~ s! +$!!mg;
186         $d = " *\n" . $d;
187     } else {
188         $d = '';
189     }
190     return $d;
193 for (@baseclasses) {
194     chomp;
195     my ($class, $parent, $synopsis, $description) = @{$_};
196     $description = c_format_description($description);
197     print HDR <<EOF;
199 /** $synopsis
200 $description */
201 class XAPIAN_VISIBILITY_DEFAULT $class : public $parent {
202   protected:
203     /** \@private \@internal
204      *  \@brief Constructor for use by constructors of derived classes.
205      */
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.
211      */
212     $class(const std::string \&msg_, const std::string \&context_, const char * type_, int errno_)
213         : $parent(msg_, context_, type_, errno_) {}
218 for (@classes) {
219     chomp;
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";
226     print HDR <<EOF;
228 /** $synopsis
229 $description */
230 class XAPIAN_VISIBILITY_DEFAULT $class : public $parent {
231   public:
232     /** \@private \@internal
233      *  \@brief Private constructor for use by remote backend.
234      *
235      *  \@param error_string_   Optional string describing error.  May be NULL.
236      */
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.
240      *
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.
245      */
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.
249      *
250      *  \@param msg_            Message giving details of the error, intended
251      *                          for human consumption.
252      *  \@param errno_          Optional errno value associated with this error.
253      */
254     $class(const std::string \&msg_, int errno_)
255         : $parent(msg_, std::string(), "$code$class", errno_) {}
256   protected:
257     /** \@private \@internal
258      *  \@brief Constructor for use by constructors of derived classes.
259      */
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.
265      */
266     $class(const std::string \&msg_, const std::string \&context_, const char * type_, int errno_)
267         : $parent(msg_, context_, type_, errno_) {}
272 print HDR <<'EOF';
276 #endif /* XAPIAN_INCLUDED_ERROR_H */
279 print DISPATCH <<'EOF';
280 #endif /* DOXYGEN */
283 close HDR or die $!;
284 close DISPATCH or die $!;
286 # vim: set syntax=perl: