-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate-exceptions
260 lines (217 loc) · 8.41 KB
/
generate-exceptions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# generate-exceptions: generate C++ files for Xapian's exception hierarchy.
#
# Copyright (C) 2003,2004,2006,2007,2008,2009,2011,2012,2013,2014,2015 Olly Betts
# Copyright (C) 2007 Richard Boulton
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
use strict;
use exception_data qw(
$copyright $generated_warning @baseclasses @classes %classcode
);
open HDR, ">include/xapian/error.h" or die $!;
open DISPATCH, ">include/xapian/errordispatch.h" or die $!;
print HDR <<'EOF';
/** @file error.h
* @brief Hierarchy of classes which Xapian can throw as exceptions.
*/
EOF
print HDR $generated_warning;
print DISPATCH $generated_warning;
print HDR $copyright;
print DISPATCH $copyright;
print HDR <<'EOF';
#ifndef XAPIAN_INCLUDED_ERROR_H
#define XAPIAN_INCLUDED_ERROR_H
#if !defined XAPIAN_IN_XAPIAN_H && !defined XAPIAN_LIB_BUILD
# error "Never use <xapian/error.h> directly; include <xapian.h> instead."
#endif
#include <string>
#include <xapian/attributes.h>
#include <xapian/visibility.h>
namespace Xapian {
class ErrorHandler;
/** All exceptions thrown by Xapian are subclasses of Xapian::Error.
*
* This class can not be instantiated directly - instead a subclass should
* be used.
*/
class XAPIAN_VISIBILITY_DEFAULT Error {
// ErrorHandler needs to be able to access Error::already_handled.
friend class ErrorHandler;
/// Message giving details of the error, intended for human consumption.
std::string msg;
/** Optional context information.
*
* This context is intended for use by Xapian::ErrorHandler (for example
* so it can know which remote server is unreliable and report the problem
* and remove that server from those being searched). But it's typically
* a plain-text string, and so also fit for human consumption.
*/
std::string context;
/** The error string derived from my_errno.
*
* This string is generated from my_errno lazily.
*/
mutable std::string error_string;
/// The type of this error (e.g. DocNotFoundError.)
const char * type;
/** Optional value of 'errno' associated with this error.
*
* If no value is associated, this member variable will be 0.
*
* On UNIX, if this value is < 0, it's an error code returned from
* getaddrinfo() (negated if such error codes are positive).
*
* On Windows, if this value is < 0, it's a negated Windows error code
* (as given by GetLastError()), while if it is >= WSABASEERR then it is a
* WinSock error code (as given by WSAGetLastError()). Prior to Xapian
* 1.2.20 and 1.3.3, WSAGetLastError() codes were also negated.
*
* NB We don't just call this member "errno" to avoid problems on
* platforms where errno is a preprocessor macro.
*/
int my_errno;
/// True if this error has already been passed to an ErrorHandler.
bool already_handled;
/// Don't allow assignment of the base class.
void operator=(const Error &o);
protected:
/** @private @internal
* @brief Constructor for use by constructors of derived classes.
*/
Error(const std::string &msg_, const std::string &context_,
const char * type_, const char * error_string_);
/** @private @internal
* @brief Constructor for use by constructors of derived classes.
*/
Error(const std::string &msg_, const std::string &context_,
const char * type_, int errno_)
: msg(msg_), context(context_), error_string(), type(type_),
my_errno(errno_), already_handled(false) { }
public:
/// The type of this error (e.g. "DocNotFoundError".)
const char * XAPIAN_NOTHROW(get_type() const) {
return type + 1;
}
/// Message giving details of the error, intended for human consumption.
const std::string & XAPIAN_NOTHROW(get_msg() const) {
return msg;
}
/** Optional context information.
*
* This context is intended for use by Xapian::ErrorHandler (for example
* so it can know which remote server is unreliable and report the problem
* and remove that server from those being searched). But it's typically
* a plain-text string, and so also fit for human consumption.
*/
const std::string & XAPIAN_NOTHROW(get_context() const) {
return context;
}
/** Returns any system error string associated with this exception.
*
* The system error string may come from errno, h_errno (on UNIX), or
* GetLastError() (on MS Windows). If there is no associated system
* error string, NULL is returned.
*/
const char * get_error_string() const;
/// Return a string describing this object.
std::string get_description() const;
};
EOF
print DISPATCH <<'EOF';
/* Note that this file isn't an external header - it's located in
* include/xapian in the source tree because it's generated so this
* is the simplest way to make inclusion work in a VPATH build.
*/
// DOXYGEN gets confused by this header-with-code.
#ifndef DOXYGEN
EOF
for (@baseclasses) {
chomp;
my ($class, $parent, $comment) = split /\t/, $_, 3;
print HDR <<EOF;
$comment
class XAPIAN_VISIBILITY_DEFAULT $class : public $parent {
protected:
/** \@private \@internal
* \@brief Constructor for use by constructors of derived classes.
*/
$class(const std::string \&msg_, const std::string \&context_, const char * type_, const char * error_string_)
: $parent(msg_, context_, type_, error_string_) {}
/** \@private \@internal
* \@brief Constructor for use by constructors of derived classes.
*/
$class(const std::string \&msg_, const std::string \&context_, const char * type_, int errno_)
: $parent(msg_, context_, type_, errno_) {}
};
EOF
}
for (@classes) {
chomp;
my ($class, $parent, $comment) = split /\t/, $_, 3;
my $code = sprintf('\%03o', $classcode{$class});
print DISPATCH "case '$code': throw Xapian::$class(msg, context, error_string);\n";
print HDR <<EOF;
$comment
class XAPIAN_VISIBILITY_DEFAULT $class : public $parent {
public:
/** \@private \@internal
* \@brief Private constructor for use by remote backend.
*
* \@param error_string_ Optional string describing error. May be NULL.
*/
$class(const std::string \&msg_, const std::string \&context_, const char * error_string_)
: $parent(msg_, context_, "$code$class", error_string_) {}
/** General purpose constructor.
*
* \@param msg_ Message giving details of the error, intended
* for human consumption.
* \@param context_ Optional context information for this error.
* \@param errno_ Optional errno value associated with this error.
*/
explicit $class(const std::string \&msg_, const std::string \&context_ = std::string(), int errno_ = 0)
: $parent(msg_, context_, "$code$class", errno_) {}
/** Construct from message and errno value.
*
* \@param msg_ Message giving details of the error, intended
* for human consumption.
* \@param errno_ Optional errno value associated with this error.
*/
$class(const std::string \&msg_, int errno_)
: $parent(msg_, std::string(), "$code$class", errno_) {}
protected:
/** \@private \@internal
* \@brief Constructor for use by constructors of derived classes.
*/
$class(const std::string \&msg_, const std::string \&context_, const char * type_, const char * error_string_)
: $parent(msg_, context_, type_, error_string_) {}
/** \@private \@internal
* \@brief Constructor for use by constructors of derived classes.
*/
$class(const std::string \&msg_, const std::string \&context_, const char * type_, int errno_)
: $parent(msg_, context_, type_, errno_) {}
};
EOF
}
print HDR <<'EOF';
}
#endif /* XAPIAN_INCLUDED_ERROR_H */
EOF
print DISPATCH <<'EOF';
#endif /* DOXYGEN */
EOF
close HDR or die $!;
close DISPATCH or die $!;
# vim: set syntax=perl: