blob: be9627c4a60d45fe70115e6ac27ed96a3a10a2fd [file] [log] [blame]
Georg Brandl43ab1002006-05-28 20:57:09 +00001/*
2 * New exceptions.c written in Iceland by Richard Jones and Georg Brandl.
3 *
4 * Thanks go to Tim Peters and Michael Hudson for debugging.
5 */
6
Richard Jones7b9558d2006-05-27 12:29:24 +00007#define PY_SSIZE_T_CLEAN
8#include <Python.h>
9#include "structmember.h"
10#include "osdefs.h"
11
12#define MAKE_IT_NONE(x) (x) = Py_None; Py_INCREF(Py_None);
13#define EXC_MODULE_NAME "exceptions."
14
Richard Jonesc5b2a2e2006-05-27 16:07:28 +000015/* NOTE: If the exception class hierarchy changes, don't forget to update
16 * Lib/test/exception_hierarchy.txt
17 */
18
19PyDoc_STRVAR(exceptions_doc, "Python's standard exception class hierarchy.\n\
20\n\
21Exceptions found here are defined both in the exceptions module and the\n\
22built-in namespace. It is recommended that user-defined exceptions\n\
23inherit from Exception. See the documentation for the exception\n\
24inheritance hierarchy.\n\
25");
26
Richard Jones7b9558d2006-05-27 12:29:24 +000027/*
28 * BaseException
29 */
30static PyObject *
31BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
32{
33 PyBaseExceptionObject *self;
34
35 self = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
36 /* the dict is created on the fly in PyObject_GenericSetAttr */
37 self->message = self->dict = NULL;
38
39 self->args = PyTuple_New(0);
40 if (!self->args) {
41 Py_DECREF(self);
42 return NULL;
43 }
44
Michael W. Hudson22a80e72006-05-28 15:51:40 +000045 self->message = PyString_FromString("");
Richard Jones7b9558d2006-05-27 12:29:24 +000046 if (!self->message) {
47 Py_DECREF(self);
48 return NULL;
49 }
50
51 return (PyObject *)self;
52}
53
54static int
55BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
56{
Georg Brandlb0432bc2006-05-30 08:17:00 +000057 if (!_PyArg_NoKeywords(self->ob_type->tp_name, kwds))
58 return -1;
59
Richard Jones7b9558d2006-05-27 12:29:24 +000060 Py_DECREF(self->args);
61 self->args = args;
62 Py_INCREF(self->args);
63
64 if (PyTuple_GET_SIZE(self->args) == 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +000065 Py_CLEAR(self->message);
Richard Jones7b9558d2006-05-27 12:29:24 +000066 self->message = PyTuple_GET_ITEM(self->args, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +000067 Py_INCREF(self->message);
Richard Jones7b9558d2006-05-27 12:29:24 +000068 }
69 return 0;
70}
71
Michael W. Hudson96495ee2006-05-28 17:40:29 +000072static int
Richard Jones7b9558d2006-05-27 12:29:24 +000073BaseException_clear(PyBaseExceptionObject *self)
74{
75 Py_CLEAR(self->dict);
76 Py_CLEAR(self->args);
77 Py_CLEAR(self->message);
78 return 0;
79}
80
81static void
82BaseException_dealloc(PyBaseExceptionObject *self)
83{
84 BaseException_clear(self);
85 self->ob_type->tp_free((PyObject *)self);
86}
87
Michael W. Hudson96495ee2006-05-28 17:40:29 +000088static int
Richard Jones7b9558d2006-05-27 12:29:24 +000089BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
90{
Michael W. Hudson22a80e72006-05-28 15:51:40 +000091 Py_VISIT(self->dict);
Richard Jones7b9558d2006-05-27 12:29:24 +000092 Py_VISIT(self->args);
93 Py_VISIT(self->message);
94 return 0;
95}
96
97static PyObject *
98BaseException_str(PyBaseExceptionObject *self)
99{
100 PyObject *out;
101
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000102 switch (PyTuple_GET_SIZE(self->args)) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000103 case 0:
104 out = PyString_FromString("");
105 break;
106 case 1:
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000107 out = PyObject_Str(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +0000108 break;
Richard Jones7b9558d2006-05-27 12:29:24 +0000109 default:
110 out = PyObject_Str(self->args);
111 break;
112 }
113
114 return out;
115}
116
117static PyObject *
118BaseException_repr(PyBaseExceptionObject *self)
119{
Richard Jones7b9558d2006-05-27 12:29:24 +0000120 PyObject *repr_suffix;
121 PyObject *repr;
122 char *name;
123 char *dot;
124
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000125 repr_suffix = PyObject_Repr(self->args);
126 if (!repr_suffix)
Richard Jones7b9558d2006-05-27 12:29:24 +0000127 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000128
129 name = (char *)self->ob_type->tp_name;
130 dot = strrchr(name, '.');
131 if (dot != NULL) name = dot+1;
132
133 repr = PyString_FromString(name);
134 if (!repr) {
135 Py_DECREF(repr_suffix);
136 return NULL;
137 }
138
139 PyString_ConcatAndDel(&repr, repr_suffix);
140 return repr;
141}
142
143/* Pickling support */
144static PyObject *
145BaseException_reduce(PyBaseExceptionObject *self)
146{
Georg Brandlddba4732006-05-30 07:04:55 +0000147 if (self->args && self->dict)
148 return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000149 else
Georg Brandlddba4732006-05-30 07:04:55 +0000150 return PyTuple_Pack(2, self->ob_type, self->args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000151}
152
Georg Brandl85ac8502006-06-01 06:39:19 +0000153/*
154 * Needed for backward compatibility, since exceptions used to store
155 * all their attributes in the __dict__. Code is taken from cPickle's
156 * load_build function.
157 */
158static PyObject *
159BaseException_setstate(PyObject *self, PyObject *state)
160{
161 PyObject *d_key, *d_value;
162 Py_ssize_t i = 0;
163
164 if (state != Py_None) {
165 if (!PyDict_Check(state)) {
166 PyErr_SetString(PyExc_TypeError, "state is not a dictionary");
167 return NULL;
168 }
169 while (PyDict_Next(state, &i, &d_key, &d_value)) {
170 if (PyObject_SetAttr(self, d_key, d_value) < 0)
171 return NULL;
172 }
173 }
174 Py_RETURN_NONE;
175}
Richard Jones7b9558d2006-05-27 12:29:24 +0000176
177#ifdef Py_USING_UNICODE
178/* while this method generates fairly uninspired output, it a least
179 * guarantees that we can display exceptions that have unicode attributes
180 */
181static PyObject *
182BaseException_unicode(PyBaseExceptionObject *self)
183{
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000184 if (PyTuple_GET_SIZE(self->args) == 0)
Richard Jones7b9558d2006-05-27 12:29:24 +0000185 return PyUnicode_FromUnicode(NULL, 0);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000186 if (PyTuple_GET_SIZE(self->args) == 1)
187 return PyObject_Unicode(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +0000188 return PyObject_Unicode(self->args);
189}
190#endif /* Py_USING_UNICODE */
191
192static PyMethodDef BaseException_methods[] = {
193 {"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
Georg Brandl85ac8502006-06-01 06:39:19 +0000194 {"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
Richard Jones7b9558d2006-05-27 12:29:24 +0000195#ifdef Py_USING_UNICODE
196 {"__unicode__", (PyCFunction)BaseException_unicode, METH_NOARGS },
197#endif
198 {NULL, NULL, 0, NULL},
199};
200
201
202
203static PyObject *
204BaseException_getitem(PyBaseExceptionObject *self, Py_ssize_t index)
205{
206 return PySequence_GetItem(self->args, index);
207}
208
209static PySequenceMethods BaseException_as_sequence = {
210 0, /* sq_length; */
211 0, /* sq_concat; */
212 0, /* sq_repeat; */
213 (ssizeargfunc)BaseException_getitem, /* sq_item; */
214 0, /* sq_slice; */
215 0, /* sq_ass_item; */
216 0, /* sq_ass_slice; */
217 0, /* sq_contains; */
218 0, /* sq_inplace_concat; */
219 0 /* sq_inplace_repeat; */
220};
221
222static PyMemberDef BaseException_members[] = {
223 {"message", T_OBJECT, offsetof(PyBaseExceptionObject, message), 0,
224 PyDoc_STR("exception message")},
225 {NULL} /* Sentinel */
226};
227
228
229static PyObject *
230BaseException_get_dict(PyBaseExceptionObject *self)
231{
232 if (self->dict == NULL) {
233 self->dict = PyDict_New();
234 if (!self->dict)
235 return NULL;
236 }
237 Py_INCREF(self->dict);
238 return self->dict;
239}
240
241static int
242BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
243{
244 if (val == NULL) {
245 PyErr_SetString(PyExc_TypeError, "__dict__ may not be deleted");
246 return -1;
247 }
248 if (!PyDict_Check(val)) {
249 PyErr_SetString(PyExc_TypeError, "__dict__ must be a dictionary");
250 return -1;
251 }
252 Py_CLEAR(self->dict);
253 Py_INCREF(val);
254 self->dict = val;
255 return 0;
256}
257
258static PyObject *
259BaseException_get_args(PyBaseExceptionObject *self)
260{
261 if (self->args == NULL) {
262 Py_INCREF(Py_None);
263 return Py_None;
264 }
265 Py_INCREF(self->args);
266 return self->args;
267}
268
269static int
270BaseException_set_args(PyBaseExceptionObject *self, PyObject *val)
271{
272 PyObject *seq;
273 if (val == NULL) {
274 PyErr_SetString(PyExc_TypeError, "args may not be deleted");
275 return -1;
276 }
277 seq = PySequence_Tuple(val);
278 if (!seq) return -1;
Georg Brandlc7c51142006-05-29 09:46:51 +0000279 Py_CLEAR(self->args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000280 self->args = seq;
281 return 0;
282}
283
284static PyGetSetDef BaseException_getset[] = {
285 {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict},
286 {"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
287 {NULL},
288};
289
290
291static PyTypeObject _PyExc_BaseException = {
292 PyObject_HEAD_INIT(NULL)
293 0, /*ob_size*/
294 EXC_MODULE_NAME "BaseException", /*tp_name*/
295 sizeof(PyBaseExceptionObject), /*tp_basicsize*/
296 0, /*tp_itemsize*/
297 (destructor)BaseException_dealloc, /*tp_dealloc*/
298 0, /*tp_print*/
299 0, /*tp_getattr*/
300 0, /*tp_setattr*/
301 0, /* tp_compare; */
302 (reprfunc)BaseException_repr, /*tp_repr*/
303 0, /*tp_as_number*/
304 &BaseException_as_sequence, /*tp_as_sequence*/
305 0, /*tp_as_mapping*/
306 0, /*tp_hash */
307 0, /*tp_call*/
308 (reprfunc)BaseException_str, /*tp_str*/
309 PyObject_GenericGetAttr, /*tp_getattro*/
310 PyObject_GenericSetAttr, /*tp_setattro*/
311 0, /*tp_as_buffer*/
312 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
313 PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
314 (traverseproc)BaseException_traverse, /* tp_traverse */
315 (inquiry)BaseException_clear, /* tp_clear */
316 0, /* tp_richcompare */
317 0, /* tp_weaklistoffset */
318 0, /* tp_iter */
319 0, /* tp_iternext */
320 BaseException_methods, /* tp_methods */
321 BaseException_members, /* tp_members */
322 BaseException_getset, /* tp_getset */
323 0, /* tp_base */
324 0, /* tp_dict */
325 0, /* tp_descr_get */
326 0, /* tp_descr_set */
327 offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
328 (initproc)BaseException_init, /* tp_init */
329 0, /* tp_alloc */
330 BaseException_new, /* tp_new */
331};
332/* the CPython API expects exceptions to be (PyObject *) - both a hold-over
333from the previous implmentation and also allowing Python objects to be used
334in the API */
335PyObject *PyExc_BaseException = (PyObject *)&_PyExc_BaseException;
336
Richard Jones2d555b32006-05-27 16:15:11 +0000337/* note these macros omit the last semicolon so the macro invocation may
338 * include it and not look strange.
339 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000340#define SimpleExtendsException(EXCBASE, EXCNAME, EXCDOC) \
341static PyTypeObject _PyExc_ ## EXCNAME = { \
342 PyObject_HEAD_INIT(NULL) \
343 0, \
344 EXC_MODULE_NAME # EXCNAME, \
345 sizeof(PyBaseExceptionObject), \
346 0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
347 0, 0, 0, 0, 0, 0, 0, \
348 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
349 PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
350 (inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
351 0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
352 (initproc)BaseException_init, 0, BaseException_new,\
353}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000354PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000355
356#define MiddlingExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDOC) \
357static PyTypeObject _PyExc_ ## EXCNAME = { \
358 PyObject_HEAD_INIT(NULL) \
359 0, \
360 EXC_MODULE_NAME # EXCNAME, \
361 sizeof(Py ## EXCSTORE ## Object), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000362 0, (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000363 0, 0, 0, 0, 0, \
364 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000365 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
366 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
Richard Jones7b9558d2006-05-27 12:29:24 +0000367 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000368 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000369}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000370PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000371
372#define ComplexExtendsException(EXCBASE, EXCNAME, EXCSTORE, EXCDEALLOC, EXCMETHODS, EXCMEMBERS, EXCSTR, EXCDOC) \
373static PyTypeObject _PyExc_ ## EXCNAME = { \
374 PyObject_HEAD_INIT(NULL) \
375 0, \
376 EXC_MODULE_NAME # EXCNAME, \
377 sizeof(Py ## EXCSTORE ## Object), 0, \
378 (destructor)EXCSTORE ## _dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
379 (reprfunc)EXCSTR, 0, 0, 0, \
380 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
381 PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
382 (inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
383 EXCMEMBERS, 0, &_ ## EXCBASE, \
384 0, 0, 0, offsetof(Py ## EXCSTORE ## Object, dict), \
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000385 (initproc)EXCSTORE ## _init, 0, BaseException_new,\
Richard Jones7b9558d2006-05-27 12:29:24 +0000386}; \
Richard Jones2d555b32006-05-27 16:15:11 +0000387PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
Richard Jones7b9558d2006-05-27 12:29:24 +0000388
389
390/*
391 * Exception extends BaseException
392 */
393SimpleExtendsException(PyExc_BaseException, Exception,
Richard Jones2d555b32006-05-27 16:15:11 +0000394 "Common base class for all non-exit exceptions.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000395
396
397/*
398 * StandardError extends Exception
399 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000400SimpleExtendsException(PyExc_Exception, StandardError,
Richard Jones7b9558d2006-05-27 12:29:24 +0000401 "Base class for all standard Python exceptions that do not represent\n"
Richard Jones2d555b32006-05-27 16:15:11 +0000402 "interpreter exiting.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000403
404
405/*
406 * TypeError extends StandardError
407 */
408SimpleExtendsException(PyExc_StandardError, TypeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000409 "Inappropriate argument type.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000410
411
412/*
413 * StopIteration extends Exception
414 */
415SimpleExtendsException(PyExc_Exception, StopIteration,
Richard Jones2d555b32006-05-27 16:15:11 +0000416 "Signal the end from iterator.next().");
Richard Jones7b9558d2006-05-27 12:29:24 +0000417
418
419/*
420 * GeneratorExit extends Exception
421 */
422SimpleExtendsException(PyExc_Exception, GeneratorExit,
Richard Jones2d555b32006-05-27 16:15:11 +0000423 "Request that a generator exit.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000424
425
426/*
427 * SystemExit extends BaseException
428 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000429
430static int
431SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds)
432{
433 Py_ssize_t size = PyTuple_GET_SIZE(args);
434
435 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
436 return -1;
437
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000438 if (size == 0)
439 return 0;
440 Py_CLEAR(self->code);
Richard Jones7b9558d2006-05-27 12:29:24 +0000441 if (size == 1)
442 self->code = PyTuple_GET_ITEM(args, 0);
443 else if (size > 1)
444 self->code = args;
445 Py_INCREF(self->code);
446 return 0;
447}
448
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000449static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000450SystemExit_clear(PySystemExitObject *self)
451{
452 Py_CLEAR(self->code);
453 return BaseException_clear((PyBaseExceptionObject *)self);
454}
455
456static void
457SystemExit_dealloc(PySystemExitObject *self)
458{
459 SystemExit_clear(self);
460 self->ob_type->tp_free((PyObject *)self);
461}
462
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000463static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000464SystemExit_traverse(PySystemExitObject *self, visitproc visit, void *arg)
465{
466 Py_VISIT(self->code);
467 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
468}
469
470static PyMemberDef SystemExit_members[] = {
471 {"message", T_OBJECT, offsetof(PySystemExitObject, message), 0,
472 PyDoc_STR("exception message")},
473 {"code", T_OBJECT, offsetof(PySystemExitObject, code), 0,
474 PyDoc_STR("exception code")},
475 {NULL} /* Sentinel */
476};
477
478ComplexExtendsException(PyExc_BaseException, SystemExit, SystemExit,
479 SystemExit_dealloc, 0, SystemExit_members, 0,
Richard Jones2d555b32006-05-27 16:15:11 +0000480 "Request to exit from the interpreter.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000481
482/*
483 * KeyboardInterrupt extends BaseException
484 */
485SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,
Richard Jones2d555b32006-05-27 16:15:11 +0000486 "Program interrupted by user.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000487
488
489/*
490 * ImportError extends StandardError
491 */
492SimpleExtendsException(PyExc_StandardError, ImportError,
Richard Jones2d555b32006-05-27 16:15:11 +0000493 "Import can't find module, or can't find name in module.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000494
495
496/*
497 * EnvironmentError extends StandardError
498 */
499
Richard Jones7b9558d2006-05-27 12:29:24 +0000500/* Where a function has a single filename, such as open() or some
501 * of the os module functions, PyErr_SetFromErrnoWithFilename() is
502 * called, giving a third argument which is the filename. But, so
503 * that old code using in-place unpacking doesn't break, e.g.:
504 *
505 * except IOError, (errno, strerror):
506 *
507 * we hack args so that it only contains two items. This also
508 * means we need our own __str__() which prints out the filename
509 * when it was supplied.
510 */
511static int
512EnvironmentError_init(PyEnvironmentErrorObject *self, PyObject *args,
513 PyObject *kwds)
514{
515 PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL;
516 PyObject *subslice = NULL;
517
518 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
519 return -1;
520
521 if (PyTuple_GET_SIZE(args) <= 1) {
522 return 0;
523 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000524
525 if (!PyArg_UnpackTuple(args, "EnvironmentError", 2, 3,
Richard Jones7b9558d2006-05-27 12:29:24 +0000526 &myerrno, &strerror, &filename)) {
527 return -1;
528 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000529 Py_CLEAR(self->myerrno); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000530 self->myerrno = myerrno;
531 Py_INCREF(self->myerrno);
532
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000533 Py_CLEAR(self->strerror); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000534 self->strerror = strerror;
535 Py_INCREF(self->strerror);
536
537 /* self->filename will remain Py_None otherwise */
538 if (filename != NULL) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000539 Py_CLEAR(self->filename); /* replacing */
Richard Jones7b9558d2006-05-27 12:29:24 +0000540 self->filename = filename;
541 Py_INCREF(self->filename);
542
543 subslice = PyTuple_GetSlice(args, 0, 2);
544 if (!subslice)
545 return -1;
546
547 Py_DECREF(self->args); /* replacing args */
548 self->args = subslice;
549 }
550 return 0;
551}
552
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000553static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000554EnvironmentError_clear(PyEnvironmentErrorObject *self)
555{
556 Py_CLEAR(self->myerrno);
557 Py_CLEAR(self->strerror);
558 Py_CLEAR(self->filename);
559 return BaseException_clear((PyBaseExceptionObject *)self);
560}
561
562static void
563EnvironmentError_dealloc(PyEnvironmentErrorObject *self)
564{
565 EnvironmentError_clear(self);
566 self->ob_type->tp_free((PyObject *)self);
567}
568
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000569static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000570EnvironmentError_traverse(PyEnvironmentErrorObject *self, visitproc visit,
571 void *arg)
572{
573 Py_VISIT(self->myerrno);
574 Py_VISIT(self->strerror);
575 Py_VISIT(self->filename);
576 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
577}
578
579static PyObject *
580EnvironmentError_str(PyEnvironmentErrorObject *self)
581{
582 PyObject *rtnval = NULL;
583
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000584 if (self->filename) {
585 PyObject *fmt;
586 PyObject *repr;
587 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000588
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000589 fmt = PyString_FromString("[Errno %s] %s: %s");
590 if (!fmt)
591 return NULL;
592
593 repr = PyObject_Repr(self->filename);
594 if (!repr) {
595 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000596 return NULL;
597 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000598 tuple = PyTuple_New(3);
599 if (!tuple) {
600 Py_DECREF(repr);
601 Py_DECREF(fmt);
602 return NULL;
603 }
604
605 if (self->myerrno) {
606 Py_INCREF(self->myerrno);
607 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
608 }
609 else {
610 Py_INCREF(Py_None);
611 PyTuple_SET_ITEM(tuple, 0, Py_None);
612 }
613 if (self->strerror) {
614 Py_INCREF(self->strerror);
615 PyTuple_SET_ITEM(tuple, 1, self->strerror);
616 }
617 else {
618 Py_INCREF(Py_None);
619 PyTuple_SET_ITEM(tuple, 1, Py_None);
620 }
621
Richard Jones7b9558d2006-05-27 12:29:24 +0000622 PyTuple_SET_ITEM(tuple, 2, repr);
623
624 rtnval = PyString_Format(fmt, tuple);
625
626 Py_DECREF(fmt);
627 Py_DECREF(tuple);
628 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000629 else if (self->myerrno && self->strerror) {
630 PyObject *fmt;
631 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000632
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000633 fmt = PyString_FromString("[Errno %s] %s");
634 if (!fmt)
635 return NULL;
636
637 tuple = PyTuple_New(2);
638 if (!tuple) {
639 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000640 return NULL;
641 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000642
643 if (self->myerrno) {
644 Py_INCREF(self->myerrno);
645 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
646 }
647 else {
648 Py_INCREF(Py_None);
649 PyTuple_SET_ITEM(tuple, 0, Py_None);
650 }
651 if (self->strerror) {
652 Py_INCREF(self->strerror);
653 PyTuple_SET_ITEM(tuple, 1, self->strerror);
654 }
655 else {
656 Py_INCREF(Py_None);
657 PyTuple_SET_ITEM(tuple, 1, Py_None);
658 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000659
660 rtnval = PyString_Format(fmt, tuple);
661
662 Py_DECREF(fmt);
663 Py_DECREF(tuple);
664 }
665 else
666 rtnval = BaseException_str((PyBaseExceptionObject *)self);
667
668 return rtnval;
669}
670
671static PyMemberDef EnvironmentError_members[] = {
672 {"message", T_OBJECT, offsetof(PyEnvironmentErrorObject, message), 0,
673 PyDoc_STR("exception message")},
674 {"errno", T_OBJECT, offsetof(PyEnvironmentErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000675 PyDoc_STR("exception errno")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000676 {"strerror", T_OBJECT, offsetof(PyEnvironmentErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000677 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000678 {"filename", T_OBJECT, offsetof(PyEnvironmentErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000679 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000680 {NULL} /* Sentinel */
681};
682
683
684static PyObject *
685EnvironmentError_reduce(PyEnvironmentErrorObject *self)
686{
687 PyObject *args = self->args;
688 PyObject *res = NULL, *tmp;
Georg Brandl05f97bf2006-05-30 07:13:29 +0000689
Richard Jones7b9558d2006-05-27 12:29:24 +0000690 /* self->args is only the first two real arguments if there was a
691 * file name given to EnvironmentError. */
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000692 if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
Richard Jones7b9558d2006-05-27 12:29:24 +0000693 args = PyTuple_New(3);
694 if (!args) return NULL;
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000695
696 tmp = PyTuple_GET_ITEM(self->args, 0);
Richard Jones7b9558d2006-05-27 12:29:24 +0000697 Py_INCREF(tmp);
698 PyTuple_SET_ITEM(args, 0, tmp);
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000699
700 tmp = PyTuple_GET_ITEM(self->args, 1);
Richard Jones7b9558d2006-05-27 12:29:24 +0000701 Py_INCREF(tmp);
702 PyTuple_SET_ITEM(args, 1, tmp);
703
704 Py_INCREF(self->filename);
705 PyTuple_SET_ITEM(args, 2, self->filename);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000706 } else
Richard Jones7b9558d2006-05-27 12:29:24 +0000707 Py_INCREF(args);
Georg Brandl05f97bf2006-05-30 07:13:29 +0000708
709 if (self->dict)
710 res = PyTuple_Pack(3, self->ob_type, args, self->dict);
711 else
712 res = PyTuple_Pack(2, self->ob_type, args);
Richard Jones7b9558d2006-05-27 12:29:24 +0000713 Py_DECREF(args);
714 return res;
715}
716
717
718static PyMethodDef EnvironmentError_methods[] = {
719 {"__reduce__", (PyCFunction)EnvironmentError_reduce, METH_NOARGS},
720 {NULL}
721};
722
723ComplexExtendsException(PyExc_StandardError, EnvironmentError,
724 EnvironmentError, EnvironmentError_dealloc,
725 EnvironmentError_methods, EnvironmentError_members,
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000726 EnvironmentError_str,
Richard Jones2d555b32006-05-27 16:15:11 +0000727 "Base class for I/O related errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000728
729
730/*
731 * IOError extends EnvironmentError
732 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000733MiddlingExtendsException(PyExc_EnvironmentError, IOError,
Richard Jones2d555b32006-05-27 16:15:11 +0000734 EnvironmentError, "I/O operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000735
736
737/*
738 * OSError extends EnvironmentError
739 */
740MiddlingExtendsException(PyExc_EnvironmentError, OSError,
Richard Jones2d555b32006-05-27 16:15:11 +0000741 EnvironmentError, "OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000742
743
744/*
745 * WindowsError extends OSError
746 */
747#ifdef MS_WINDOWS
748#include "errmap.h"
749
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000750static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000751WindowsError_clear(PyWindowsErrorObject *self)
752{
753 Py_CLEAR(self->myerrno);
754 Py_CLEAR(self->strerror);
755 Py_CLEAR(self->filename);
756 Py_CLEAR(self->winerror);
757 return BaseException_clear((PyBaseExceptionObject *)self);
758}
759
760static void
761WindowsError_dealloc(PyWindowsErrorObject *self)
762{
763 WindowsError_clear(self);
764 self->ob_type->tp_free((PyObject *)self);
765}
766
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000767static int
Richard Jones7b9558d2006-05-27 12:29:24 +0000768WindowsError_traverse(PyWindowsErrorObject *self, visitproc visit, void *arg)
769{
770 Py_VISIT(self->myerrno);
771 Py_VISIT(self->strerror);
772 Py_VISIT(self->filename);
773 Py_VISIT(self->winerror);
774 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
775}
776
Richard Jones7b9558d2006-05-27 12:29:24 +0000777static int
778WindowsError_init(PyWindowsErrorObject *self, PyObject *args, PyObject *kwds)
779{
780 PyObject *o_errcode = NULL;
781 long errcode;
782 long posix_errno;
783
784 if (EnvironmentError_init((PyEnvironmentErrorObject *)self, args, kwds)
785 == -1)
786 return -1;
787
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000788 if (self->myerrno == NULL)
Richard Jones7b9558d2006-05-27 12:29:24 +0000789 return 0;
Richard Jones7b9558d2006-05-27 12:29:24 +0000790
791 /* Set errno to the POSIX errno, and winerror to the Win32
792 error code. */
793 errcode = PyInt_AsLong(self->myerrno);
794 if (errcode == -1 && PyErr_Occurred())
795 return -1;
796 posix_errno = winerror_to_errno(errcode);
797
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000798 Py_CLEAR(self->winerror);
Richard Jones7b9558d2006-05-27 12:29:24 +0000799 self->winerror = self->myerrno;
800
801 o_errcode = PyInt_FromLong(posix_errno);
802 if (!o_errcode)
803 return -1;
804
805 self->myerrno = o_errcode;
806
807 return 0;
808}
809
810
811static PyObject *
812WindowsError_str(PyWindowsErrorObject *self)
813{
Richard Jones7b9558d2006-05-27 12:29:24 +0000814 PyObject *rtnval = NULL;
815
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000816 if (self->filename) {
817 PyObject *fmt;
818 PyObject *repr;
819 PyObject *tuple;
Richard Jones7b9558d2006-05-27 12:29:24 +0000820
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000821 fmt = PyString_FromString("[Error %s] %s: %s");
822 if (!fmt)
823 return NULL;
824
825 repr = PyObject_Repr(self->filename);
826 if (!repr) {
827 Py_DECREF(fmt);
828 return NULL;
829 }
830 tuple = PyTuple_New(3);
831 if (!tuple) {
832 Py_DECREF(repr);
833 Py_DECREF(fmt);
834 return NULL;
835 }
836
837 if (self->myerrno) {
838 Py_INCREF(self->myerrno);
839 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
840 }
841 else {
842 Py_INCREF(Py_None);
843 PyTuple_SET_ITEM(tuple, 0, Py_None);
844 }
845 if (self->strerror) {
846 Py_INCREF(self->strerror);
847 PyTuple_SET_ITEM(tuple, 1, self->strerror);
848 }
849 else {
850 Py_INCREF(Py_None);
851 PyTuple_SET_ITEM(tuple, 1, Py_None);
852 }
853
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000854 PyTuple_SET_ITEM(tuple, 2, repr);
Richard Jones7b9558d2006-05-27 12:29:24 +0000855
856 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000857
858 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000859 Py_DECREF(tuple);
860 }
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000861 else if (self->myerrno && self->strerror) {
862 PyObject *fmt;
863 PyObject *tuple;
864
Richard Jones7b9558d2006-05-27 12:29:24 +0000865 fmt = PyString_FromString("[Error %s] %s");
866 if (!fmt)
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000867 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +0000868
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000869 tuple = PyTuple_New(2);
870 if (!tuple) {
871 Py_DECREF(fmt);
872 return NULL;
873 }
874
875 if (self->myerrno) {
876 Py_INCREF(self->myerrno);
877 PyTuple_SET_ITEM(tuple, 0, self->myerrno);
878 }
879 else {
880 Py_INCREF(Py_None);
881 PyTuple_SET_ITEM(tuple, 0, Py_None);
882 }
883 if (self->strerror) {
884 Py_INCREF(self->strerror);
885 PyTuple_SET_ITEM(tuple, 1, self->strerror);
886 }
887 else {
888 Py_INCREF(Py_None);
889 PyTuple_SET_ITEM(tuple, 1, Py_None);
890 }
Richard Jones7b9558d2006-05-27 12:29:24 +0000891
892 rtnval = PyString_Format(fmt, tuple);
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000893
894 Py_DECREF(fmt);
Richard Jones7b9558d2006-05-27 12:29:24 +0000895 Py_DECREF(tuple);
896 }
897 else
Michael W. Hudson96495ee2006-05-28 17:40:29 +0000898 rtnval = EnvironmentError_str((PyEnvironmentErrorObject *)self);
Richard Jones7b9558d2006-05-27 12:29:24 +0000899
Richard Jones7b9558d2006-05-27 12:29:24 +0000900 return rtnval;
901}
902
903static PyMemberDef WindowsError_members[] = {
904 {"message", T_OBJECT, offsetof(PyWindowsErrorObject, message), 0,
905 PyDoc_STR("exception message")},
906 {"errno", T_OBJECT, offsetof(PyWindowsErrorObject, myerrno), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000907 PyDoc_STR("POSIX exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000908 {"strerror", T_OBJECT, offsetof(PyWindowsErrorObject, strerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000909 PyDoc_STR("exception strerror")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000910 {"filename", T_OBJECT, offsetof(PyWindowsErrorObject, filename), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000911 PyDoc_STR("exception filename")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000912 {"winerror", T_OBJECT, offsetof(PyWindowsErrorObject, winerror), 0,
Richard Jonesc5b2a2e2006-05-27 16:07:28 +0000913 PyDoc_STR("Win32 exception code")},
Richard Jones7b9558d2006-05-27 12:29:24 +0000914 {NULL} /* Sentinel */
915};
916
Richard Jones2d555b32006-05-27 16:15:11 +0000917ComplexExtendsException(PyExc_OSError, WindowsError, WindowsError,
918 WindowsError_dealloc, 0, WindowsError_members,
919 WindowsError_str, "MS-Windows OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000920
921#endif /* MS_WINDOWS */
922
923
924/*
925 * VMSError extends OSError (I think)
926 */
927#ifdef __VMS
928MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,
Richard Jones2d555b32006-05-27 16:15:11 +0000929 "OpenVMS OS system call failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000930#endif
931
932
933/*
934 * EOFError extends StandardError
935 */
936SimpleExtendsException(PyExc_StandardError, EOFError,
Richard Jones2d555b32006-05-27 16:15:11 +0000937 "Read beyond end of file.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000938
939
940/*
941 * RuntimeError extends StandardError
942 */
943SimpleExtendsException(PyExc_StandardError, RuntimeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000944 "Unspecified run-time error.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000945
946
947/*
948 * NotImplementedError extends RuntimeError
949 */
950SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,
Richard Jones2d555b32006-05-27 16:15:11 +0000951 "Method or function hasn't been implemented yet.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000952
953/*
954 * NameError extends StandardError
955 */
956SimpleExtendsException(PyExc_StandardError, NameError,
Richard Jones2d555b32006-05-27 16:15:11 +0000957 "Name not found globally.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000958
959/*
960 * UnboundLocalError extends NameError
961 */
962SimpleExtendsException(PyExc_NameError, UnboundLocalError,
Richard Jones2d555b32006-05-27 16:15:11 +0000963 "Local name referenced but not bound to a value.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000964
965/*
966 * AttributeError extends StandardError
967 */
968SimpleExtendsException(PyExc_StandardError, AttributeError,
Richard Jones2d555b32006-05-27 16:15:11 +0000969 "Attribute not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +0000970
971
972/*
973 * SyntaxError extends StandardError
974 */
Richard Jones7b9558d2006-05-27 12:29:24 +0000975
976static int
977SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds)
978{
979 PyObject *info = NULL;
980 Py_ssize_t lenargs = PyTuple_GET_SIZE(args);
981
982 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
983 return -1;
984
985 if (lenargs >= 1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000986 Py_CLEAR(self->msg);
Richard Jones7b9558d2006-05-27 12:29:24 +0000987 self->msg = PyTuple_GET_ITEM(args, 0);
988 Py_INCREF(self->msg);
989 }
990 if (lenargs == 2) {
991 info = PyTuple_GET_ITEM(args, 1);
992 info = PySequence_Tuple(info);
993 if (!info) return -1;
994
Michael W. Hudson22a80e72006-05-28 15:51:40 +0000995 if (PyTuple_GET_SIZE(info) != 4) {
996 /* not a very good error message, but it's what Python 2.4 gives */
997 PyErr_SetString(PyExc_IndexError, "tuple index out of range");
998 Py_DECREF(info);
999 return -1;
1000 }
1001
1002 Py_CLEAR(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +00001003 self->filename = PyTuple_GET_ITEM(info, 0);
1004 Py_INCREF(self->filename);
1005
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001006 Py_CLEAR(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +00001007 self->lineno = PyTuple_GET_ITEM(info, 1);
1008 Py_INCREF(self->lineno);
1009
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001010 Py_CLEAR(self->offset);
Richard Jones7b9558d2006-05-27 12:29:24 +00001011 self->offset = PyTuple_GET_ITEM(info, 2);
1012 Py_INCREF(self->offset);
1013
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001014 Py_CLEAR(self->text);
Richard Jones7b9558d2006-05-27 12:29:24 +00001015 self->text = PyTuple_GET_ITEM(info, 3);
1016 Py_INCREF(self->text);
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001017
1018 Py_DECREF(info);
Richard Jones7b9558d2006-05-27 12:29:24 +00001019 }
1020 return 0;
1021}
1022
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001023static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001024SyntaxError_clear(PySyntaxErrorObject *self)
1025{
1026 Py_CLEAR(self->msg);
1027 Py_CLEAR(self->filename);
1028 Py_CLEAR(self->lineno);
1029 Py_CLEAR(self->offset);
1030 Py_CLEAR(self->text);
1031 Py_CLEAR(self->print_file_and_line);
1032 return BaseException_clear((PyBaseExceptionObject *)self);
1033}
1034
1035static void
1036SyntaxError_dealloc(PySyntaxErrorObject *self)
1037{
1038 SyntaxError_clear(self);
1039 self->ob_type->tp_free((PyObject *)self);
1040}
1041
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001042static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001043SyntaxError_traverse(PySyntaxErrorObject *self, visitproc visit, void *arg)
1044{
1045 Py_VISIT(self->msg);
1046 Py_VISIT(self->filename);
1047 Py_VISIT(self->lineno);
1048 Py_VISIT(self->offset);
1049 Py_VISIT(self->text);
1050 Py_VISIT(self->print_file_and_line);
1051 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1052}
1053
1054/* This is called "my_basename" instead of just "basename" to avoid name
1055 conflicts with glibc; basename is already prototyped if _GNU_SOURCE is
1056 defined, and Python does define that. */
1057static char *
1058my_basename(char *name)
1059{
1060 char *cp = name;
1061 char *result = name;
1062
1063 if (name == NULL)
1064 return "???";
1065 while (*cp != '\0') {
1066 if (*cp == SEP)
1067 result = cp + 1;
1068 ++cp;
1069 }
1070 return result;
1071}
1072
1073
1074static PyObject *
1075SyntaxError_str(PySyntaxErrorObject *self)
1076{
1077 PyObject *str;
1078 PyObject *result;
Georg Brandl43ab1002006-05-28 20:57:09 +00001079 int have_filename = 0;
1080 int have_lineno = 0;
1081 char *buffer = NULL;
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001082 Py_ssize_t bufsize;
Richard Jones7b9558d2006-05-27 12:29:24 +00001083
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001084 if (self->msg)
1085 str = PyObject_Str(self->msg);
1086 else
1087 str = PyObject_Str(Py_None);
Georg Brandl43ab1002006-05-28 20:57:09 +00001088 if (!str) return NULL;
1089 /* Don't fiddle with non-string return (shouldn't happen anyway) */
1090 if (!PyString_Check(str)) return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001091
1092 /* XXX -- do all the additional formatting with filename and
1093 lineno here */
1094
Georg Brandl43ab1002006-05-28 20:57:09 +00001095 have_filename = (self->filename != NULL) &&
1096 PyString_Check(self->filename);
1097 have_lineno = (self->lineno != NULL) && PyInt_Check(self->lineno);
Richard Jones7b9558d2006-05-27 12:29:24 +00001098
Georg Brandl43ab1002006-05-28 20:57:09 +00001099 if (!have_filename && !have_lineno)
1100 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001101
Thomas Woutersc1282ee2006-05-28 21:32:12 +00001102 bufsize = PyString_GET_SIZE(str) + 64;
Georg Brandl43ab1002006-05-28 20:57:09 +00001103 if (have_filename)
1104 bufsize += PyString_GET_SIZE(self->filename);
Richard Jones7b9558d2006-05-27 12:29:24 +00001105
Georg Brandl43ab1002006-05-28 20:57:09 +00001106 buffer = PyMem_MALLOC(bufsize);
1107 if (buffer == NULL)
1108 return str;
Richard Jones7b9558d2006-05-27 12:29:24 +00001109
Georg Brandl43ab1002006-05-28 20:57:09 +00001110 if (have_filename && have_lineno)
1111 PyOS_snprintf(buffer, bufsize, "%s (%s, line %ld)",
1112 PyString_AS_STRING(str),
1113 my_basename(PyString_AS_STRING(self->filename)),
1114 PyInt_AsLong(self->lineno));
1115 else if (have_filename)
1116 PyOS_snprintf(buffer, bufsize, "%s (%s)",
1117 PyString_AS_STRING(str),
1118 my_basename(PyString_AS_STRING(self->filename)));
1119 else /* only have_lineno */
1120 PyOS_snprintf(buffer, bufsize, "%s (line %ld)",
1121 PyString_AS_STRING(str),
1122 PyInt_AsLong(self->lineno));
Richard Jones7b9558d2006-05-27 12:29:24 +00001123
Georg Brandl43ab1002006-05-28 20:57:09 +00001124 result = PyString_FromString(buffer);
1125 PyMem_FREE(buffer);
1126
1127 if (result == NULL)
1128 result = str;
1129 else
1130 Py_DECREF(str);
Richard Jones7b9558d2006-05-27 12:29:24 +00001131 return result;
1132}
1133
1134static PyMemberDef SyntaxError_members[] = {
1135 {"message", T_OBJECT, offsetof(PySyntaxErrorObject, message), 0,
1136 PyDoc_STR("exception message")},
1137 {"msg", T_OBJECT, offsetof(PySyntaxErrorObject, msg), 0,
1138 PyDoc_STR("exception msg")},
1139 {"filename", T_OBJECT, offsetof(PySyntaxErrorObject, filename), 0,
1140 PyDoc_STR("exception filename")},
1141 {"lineno", T_OBJECT, offsetof(PySyntaxErrorObject, lineno), 0,
1142 PyDoc_STR("exception lineno")},
1143 {"offset", T_OBJECT, offsetof(PySyntaxErrorObject, offset), 0,
1144 PyDoc_STR("exception offset")},
1145 {"text", T_OBJECT, offsetof(PySyntaxErrorObject, text), 0,
1146 PyDoc_STR("exception text")},
1147 {"print_file_and_line", T_OBJECT,
1148 offsetof(PySyntaxErrorObject, print_file_and_line), 0,
1149 PyDoc_STR("exception print_file_and_line")},
1150 {NULL} /* Sentinel */
1151};
1152
1153ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError,
1154 SyntaxError_dealloc, 0, SyntaxError_members,
Richard Jones2d555b32006-05-27 16:15:11 +00001155 SyntaxError_str, "Invalid syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001156
1157
1158/*
1159 * IndentationError extends SyntaxError
1160 */
1161MiddlingExtendsException(PyExc_SyntaxError, IndentationError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001162 "Improper indentation.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001163
1164
1165/*
1166 * TabError extends IndentationError
1167 */
1168MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,
Richard Jones2d555b32006-05-27 16:15:11 +00001169 "Improper mixture of spaces and tabs.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001170
1171
1172/*
1173 * LookupError extends StandardError
1174 */
1175SimpleExtendsException(PyExc_StandardError, LookupError,
Richard Jones2d555b32006-05-27 16:15:11 +00001176 "Base class for lookup errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001177
1178
1179/*
1180 * IndexError extends LookupError
1181 */
1182SimpleExtendsException(PyExc_LookupError, IndexError,
Richard Jones2d555b32006-05-27 16:15:11 +00001183 "Sequence index out of range.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001184
1185
1186/*
1187 * KeyError extends LookupError
1188 */
1189static PyObject *
1190KeyError_str(PyBaseExceptionObject *self)
1191{
1192 /* If args is a tuple of exactly one item, apply repr to args[0].
1193 This is done so that e.g. the exception raised by {}[''] prints
1194 KeyError: ''
1195 rather than the confusing
1196 KeyError
1197 alone. The downside is that if KeyError is raised with an explanatory
1198 string, that string will be displayed in quotes. Too bad.
1199 If args is anything else, use the default BaseException__str__().
1200 */
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001201 if (PyTuple_GET_SIZE(self->args) == 1) {
1202 return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
Richard Jones7b9558d2006-05-27 12:29:24 +00001203 }
1204 return BaseException_str(self);
1205}
1206
1207ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,
Richard Jones2d555b32006-05-27 16:15:11 +00001208 0, 0, 0, KeyError_str, "Mapping key not found.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001209
1210
1211/*
1212 * ValueError extends StandardError
1213 */
1214SimpleExtendsException(PyExc_StandardError, ValueError,
Richard Jones2d555b32006-05-27 16:15:11 +00001215 "Inappropriate argument value (of correct type).");
Richard Jones7b9558d2006-05-27 12:29:24 +00001216
1217/*
1218 * UnicodeError extends ValueError
1219 */
1220
1221SimpleExtendsException(PyExc_ValueError, UnicodeError,
Richard Jones2d555b32006-05-27 16:15:11 +00001222 "Unicode related error.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001223
1224#ifdef Py_USING_UNICODE
1225static int
1226get_int(PyObject *attr, Py_ssize_t *value, const char *name)
1227{
1228 if (!attr) {
1229 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1230 return -1;
1231 }
1232
1233 if (PyInt_Check(attr)) {
1234 *value = PyInt_AS_LONG(attr);
1235 } else if (PyLong_Check(attr)) {
1236 *value = _PyLong_AsSsize_t(attr);
1237 if (*value == -1 && PyErr_Occurred())
1238 return -1;
1239 } else {
1240 PyErr_Format(PyExc_TypeError, "%.200s attribute must be int", name);
1241 return -1;
1242 }
1243 return 0;
1244}
1245
1246static int
1247set_ssize_t(PyObject **attr, Py_ssize_t value)
1248{
1249 PyObject *obj = PyInt_FromSsize_t(value);
1250 if (!obj)
1251 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001252 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001253 *attr = obj;
1254 return 0;
1255}
1256
1257static PyObject *
1258get_string(PyObject *attr, const char *name)
1259{
1260 if (!attr) {
1261 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1262 return NULL;
1263 }
1264
1265 if (!PyString_Check(attr)) {
1266 PyErr_Format(PyExc_TypeError, "%.200s attribute must be str", name);
1267 return NULL;
1268 }
1269 Py_INCREF(attr);
1270 return attr;
1271}
1272
1273
1274static int
1275set_string(PyObject **attr, const char *value)
1276{
1277 PyObject *obj = PyString_FromString(value);
1278 if (!obj)
1279 return -1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001280 Py_CLEAR(*attr);
Richard Jones7b9558d2006-05-27 12:29:24 +00001281 *attr = obj;
1282 return 0;
1283}
1284
1285
1286static PyObject *
1287get_unicode(PyObject *attr, const char *name)
1288{
1289 if (!attr) {
1290 PyErr_Format(PyExc_TypeError, "%.200s attribute not set", name);
1291 return NULL;
1292 }
1293
1294 if (!PyUnicode_Check(attr)) {
1295 PyErr_Format(PyExc_TypeError,
1296 "%.200s attribute must be unicode", name);
1297 return NULL;
1298 }
1299 Py_INCREF(attr);
1300 return attr;
1301}
1302
1303PyObject *
1304PyUnicodeEncodeError_GetEncoding(PyObject *exc)
1305{
1306 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1307}
1308
1309PyObject *
1310PyUnicodeDecodeError_GetEncoding(PyObject *exc)
1311{
1312 return get_string(((PyUnicodeErrorObject *)exc)->encoding, "encoding");
1313}
1314
1315PyObject *
1316PyUnicodeEncodeError_GetObject(PyObject *exc)
1317{
1318 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1319}
1320
1321PyObject *
1322PyUnicodeDecodeError_GetObject(PyObject *exc)
1323{
1324 return get_string(((PyUnicodeErrorObject *)exc)->object, "object");
1325}
1326
1327PyObject *
1328PyUnicodeTranslateError_GetObject(PyObject *exc)
1329{
1330 return get_unicode(((PyUnicodeErrorObject *)exc)->object, "object");
1331}
1332
1333int
1334PyUnicodeEncodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1335{
1336 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1337 Py_ssize_t size;
1338 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1339 "object");
1340 if (!obj) return -1;
1341 size = PyUnicode_GET_SIZE(obj);
1342 if (*start<0)
1343 *start = 0; /*XXX check for values <0*/
1344 if (*start>=size)
1345 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001346 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001347 return 0;
1348 }
1349 return -1;
1350}
1351
1352
1353int
1354PyUnicodeDecodeError_GetStart(PyObject *exc, Py_ssize_t *start)
1355{
1356 if (!get_int(((PyUnicodeErrorObject *)exc)->start, start, "start")) {
1357 Py_ssize_t size;
1358 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1359 "object");
1360 if (!obj) return -1;
1361 size = PyString_GET_SIZE(obj);
1362 if (*start<0)
1363 *start = 0;
1364 if (*start>=size)
1365 *start = size-1;
Georg Brandl43ab1002006-05-28 20:57:09 +00001366 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001367 return 0;
1368 }
1369 return -1;
1370}
1371
1372
1373int
1374PyUnicodeTranslateError_GetStart(PyObject *exc, Py_ssize_t *start)
1375{
1376 return PyUnicodeEncodeError_GetStart(exc, start);
1377}
1378
1379
1380int
1381PyUnicodeEncodeError_SetStart(PyObject *exc, Py_ssize_t start)
1382{
1383 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1384}
1385
1386
1387int
1388PyUnicodeDecodeError_SetStart(PyObject *exc, Py_ssize_t start)
1389{
1390 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1391}
1392
1393
1394int
1395PyUnicodeTranslateError_SetStart(PyObject *exc, Py_ssize_t start)
1396{
1397 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->start, start);
1398}
1399
1400
1401int
1402PyUnicodeEncodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1403{
1404 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1405 Py_ssize_t size;
1406 PyObject *obj = get_unicode(((PyUnicodeErrorObject *)exc)->object,
1407 "object");
1408 if (!obj) return -1;
1409 size = PyUnicode_GET_SIZE(obj);
1410 if (*end<1)
1411 *end = 1;
1412 if (*end>size)
1413 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001414 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001415 return 0;
1416 }
1417 return -1;
1418}
1419
1420
1421int
1422PyUnicodeDecodeError_GetEnd(PyObject *exc, Py_ssize_t *end)
1423{
1424 if (!get_int(((PyUnicodeErrorObject *)exc)->end, end, "end")) {
1425 Py_ssize_t size;
1426 PyObject *obj = get_string(((PyUnicodeErrorObject *)exc)->object,
1427 "object");
1428 if (!obj) return -1;
1429 size = PyString_GET_SIZE(obj);
1430 if (*end<1)
1431 *end = 1;
1432 if (*end>size)
1433 *end = size;
Georg Brandl43ab1002006-05-28 20:57:09 +00001434 Py_DECREF(obj);
Richard Jones7b9558d2006-05-27 12:29:24 +00001435 return 0;
1436 }
1437 return -1;
1438}
1439
1440
1441int
1442PyUnicodeTranslateError_GetEnd(PyObject *exc, Py_ssize_t *start)
1443{
1444 return PyUnicodeEncodeError_GetEnd(exc, start);
1445}
1446
1447
1448int
1449PyUnicodeEncodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1450{
1451 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1452}
1453
1454
1455int
1456PyUnicodeDecodeError_SetEnd(PyObject *exc, Py_ssize_t end)
1457{
1458 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1459}
1460
1461
1462int
1463PyUnicodeTranslateError_SetEnd(PyObject *exc, Py_ssize_t end)
1464{
1465 return set_ssize_t(&((PyUnicodeErrorObject *)exc)->end, end);
1466}
1467
1468PyObject *
1469PyUnicodeEncodeError_GetReason(PyObject *exc)
1470{
1471 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1472}
1473
1474
1475PyObject *
1476PyUnicodeDecodeError_GetReason(PyObject *exc)
1477{
1478 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1479}
1480
1481
1482PyObject *
1483PyUnicodeTranslateError_GetReason(PyObject *exc)
1484{
1485 return get_string(((PyUnicodeErrorObject *)exc)->reason, "reason");
1486}
1487
1488
1489int
1490PyUnicodeEncodeError_SetReason(PyObject *exc, const char *reason)
1491{
1492 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1493}
1494
1495
1496int
1497PyUnicodeDecodeError_SetReason(PyObject *exc, const char *reason)
1498{
1499 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1500}
1501
1502
1503int
1504PyUnicodeTranslateError_SetReason(PyObject *exc, const char *reason)
1505{
1506 return set_string(&((PyUnicodeErrorObject *)exc)->reason, reason);
1507}
1508
1509
Richard Jones7b9558d2006-05-27 12:29:24 +00001510static int
1511UnicodeError_init(PyUnicodeErrorObject *self, PyObject *args, PyObject *kwds,
1512 PyTypeObject *objecttype)
1513{
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001514 Py_CLEAR(self->encoding);
1515 Py_CLEAR(self->object);
1516 Py_CLEAR(self->start);
1517 Py_CLEAR(self->end);
1518 Py_CLEAR(self->reason);
1519
Richard Jones7b9558d2006-05-27 12:29:24 +00001520 if (!PyArg_ParseTuple(args, "O!O!O!O!O!",
1521 &PyString_Type, &self->encoding,
1522 objecttype, &self->object,
1523 &PyInt_Type, &self->start,
1524 &PyInt_Type, &self->end,
1525 &PyString_Type, &self->reason)) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001526 self->encoding = self->object = self->start = self->end =
Richard Jones7b9558d2006-05-27 12:29:24 +00001527 self->reason = NULL;
1528 return -1;
1529 }
1530
1531 Py_INCREF(self->encoding);
1532 Py_INCREF(self->object);
1533 Py_INCREF(self->start);
1534 Py_INCREF(self->end);
1535 Py_INCREF(self->reason);
1536
1537 return 0;
1538}
1539
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001540static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001541UnicodeError_clear(PyUnicodeErrorObject *self)
1542{
1543 Py_CLEAR(self->encoding);
1544 Py_CLEAR(self->object);
1545 Py_CLEAR(self->start);
1546 Py_CLEAR(self->end);
1547 Py_CLEAR(self->reason);
1548 return BaseException_clear((PyBaseExceptionObject *)self);
1549}
1550
1551static void
1552UnicodeError_dealloc(PyUnicodeErrorObject *self)
1553{
1554 UnicodeError_clear(self);
1555 self->ob_type->tp_free((PyObject *)self);
1556}
1557
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001558static int
Richard Jones7b9558d2006-05-27 12:29:24 +00001559UnicodeError_traverse(PyUnicodeErrorObject *self, visitproc visit, void *arg)
1560{
1561 Py_VISIT(self->encoding);
1562 Py_VISIT(self->object);
1563 Py_VISIT(self->start);
1564 Py_VISIT(self->end);
1565 Py_VISIT(self->reason);
1566 return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
1567}
1568
1569static PyMemberDef UnicodeError_members[] = {
1570 {"message", T_OBJECT, offsetof(PyUnicodeErrorObject, message), 0,
1571 PyDoc_STR("exception message")},
1572 {"encoding", T_OBJECT, offsetof(PyUnicodeErrorObject, encoding), 0,
1573 PyDoc_STR("exception encoding")},
1574 {"object", T_OBJECT, offsetof(PyUnicodeErrorObject, object), 0,
1575 PyDoc_STR("exception object")},
1576 {"start", T_OBJECT, offsetof(PyUnicodeErrorObject, start), 0,
1577 PyDoc_STR("exception start")},
1578 {"end", T_OBJECT, offsetof(PyUnicodeErrorObject, end), 0,
1579 PyDoc_STR("exception end")},
1580 {"reason", T_OBJECT, offsetof(PyUnicodeErrorObject, reason), 0,
1581 PyDoc_STR("exception reason")},
1582 {NULL} /* Sentinel */
1583};
1584
1585
1586/*
1587 * UnicodeEncodeError extends UnicodeError
1588 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001589
1590static int
1591UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1592{
1593 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1594 return -1;
1595 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1596 kwds, &PyUnicode_Type);
1597}
1598
1599static PyObject *
1600UnicodeEncodeError_str(PyObject *self)
1601{
1602 Py_ssize_t start;
1603 Py_ssize_t end;
1604
1605 if (PyUnicodeEncodeError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001606 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001607
1608 if (PyUnicodeEncodeError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001609 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001610
1611 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001612 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1613 char badchar_str[20];
1614 if (badchar <= 0xff)
1615 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1616 else if (badchar <= 0xffff)
1617 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1618 else
1619 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1620 return PyString_FromFormat(
1621 "'%.400s' codec can't encode character u'\\%s' in position %zd: %.400s",
1622 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1623 badchar_str,
1624 start,
1625 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1626 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001627 }
1628 return PyString_FromFormat(
1629 "'%.400s' codec can't encode characters in position %zd-%zd: %.400s",
1630 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1631 start,
1632 (end-1),
1633 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1634 );
1635}
1636
1637static PyTypeObject _PyExc_UnicodeEncodeError = {
1638 PyObject_HEAD_INIT(NULL)
1639 0,
1640 "UnicodeEncodeError",
1641 sizeof(PyUnicodeErrorObject), 0,
1642 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1643 (reprfunc)UnicodeEncodeError_str, 0, 0, 0,
1644 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001645 PyDoc_STR("Unicode encoding error."), (traverseproc)UnicodeError_traverse,
1646 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001647 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001648 (initproc)UnicodeEncodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001649};
1650PyObject *PyExc_UnicodeEncodeError = (PyObject *)&_PyExc_UnicodeEncodeError;
1651
1652PyObject *
1653PyUnicodeEncodeError_Create(
1654 const char *encoding, const Py_UNICODE *object, Py_ssize_t length,
1655 Py_ssize_t start, Py_ssize_t end, const char *reason)
1656{
1657 return PyObject_CallFunction(PyExc_UnicodeEncodeError, "su#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001658 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001659}
1660
1661
1662/*
1663 * UnicodeDecodeError extends UnicodeError
1664 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001665
1666static int
1667UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds)
1668{
1669 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1670 return -1;
1671 return UnicodeError_init((PyUnicodeErrorObject *)self, args,
1672 kwds, &PyString_Type);
1673}
1674
1675static PyObject *
1676UnicodeDecodeError_str(PyObject *self)
1677{
Georg Brandl43ab1002006-05-28 20:57:09 +00001678 Py_ssize_t start = 0;
1679 Py_ssize_t end = 0;
Richard Jones7b9558d2006-05-27 12:29:24 +00001680
1681 if (PyUnicodeDecodeError_GetStart(self, &start))
1682 return NULL;
1683
1684 if (PyUnicodeDecodeError_GetEnd(self, &end))
1685 return NULL;
1686
1687 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001688 /* FromFormat does not support %02x, so format that separately */
1689 char byte[4];
1690 PyOS_snprintf(byte, sizeof(byte), "%02x",
1691 ((int)PyString_AS_STRING(((PyUnicodeErrorObject *)self)->object)[start])&0xff);
1692 return PyString_FromFormat(
1693 "'%.400s' codec can't decode byte 0x%s in position %zd: %.400s",
1694 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1695 byte,
1696 start,
1697 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1698 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001699 }
1700 return PyString_FromFormat(
1701 "'%.400s' codec can't decode bytes in position %zd-%zd: %.400s",
1702 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->encoding),
1703 start,
1704 (end-1),
1705 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1706 );
1707}
1708
1709static PyTypeObject _PyExc_UnicodeDecodeError = {
1710 PyObject_HEAD_INIT(NULL)
1711 0,
1712 EXC_MODULE_NAME "UnicodeDecodeError",
1713 sizeof(PyUnicodeErrorObject), 0,
1714 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1715 (reprfunc)UnicodeDecodeError_str, 0, 0, 0,
1716 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Michael W. Hudson27596272006-05-28 21:19:03 +00001717 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1718 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
Richard Jones7b9558d2006-05-27 12:29:24 +00001719 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001720 (initproc)UnicodeDecodeError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001721};
1722PyObject *PyExc_UnicodeDecodeError = (PyObject *)&_PyExc_UnicodeDecodeError;
1723
1724PyObject *
1725PyUnicodeDecodeError_Create(
1726 const char *encoding, const char *object, Py_ssize_t length,
1727 Py_ssize_t start, Py_ssize_t end, const char *reason)
1728{
1729 assert(length < INT_MAX);
1730 assert(start < INT_MAX);
1731 assert(end < INT_MAX);
1732 return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001733 encoding, object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001734}
1735
1736
1737/*
1738 * UnicodeTranslateError extends UnicodeError
1739 */
Richard Jones7b9558d2006-05-27 12:29:24 +00001740
1741static int
1742UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args,
1743 PyObject *kwds)
1744{
1745 if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1)
1746 return -1;
1747
1748 Py_CLEAR(self->object);
1749 Py_CLEAR(self->start);
1750 Py_CLEAR(self->end);
1751 Py_CLEAR(self->reason);
1752
1753 if (!PyArg_ParseTuple(args, "O!O!O!O!",
1754 &PyUnicode_Type, &self->object,
1755 &PyInt_Type, &self->start,
1756 &PyInt_Type, &self->end,
1757 &PyString_Type, &self->reason)) {
1758 self->object = self->start = self->end = self->reason = NULL;
1759 return -1;
1760 }
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001761
Richard Jones7b9558d2006-05-27 12:29:24 +00001762 Py_INCREF(self->object);
1763 Py_INCREF(self->start);
1764 Py_INCREF(self->end);
1765 Py_INCREF(self->reason);
1766
1767 return 0;
1768}
1769
1770
1771static PyObject *
1772UnicodeTranslateError_str(PyObject *self)
1773{
1774 Py_ssize_t start;
1775 Py_ssize_t end;
1776
1777 if (PyUnicodeTranslateError_GetStart(self, &start))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001778 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001779
1780 if (PyUnicodeTranslateError_GetEnd(self, &end))
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001781 return NULL;
Richard Jones7b9558d2006-05-27 12:29:24 +00001782
1783 if (end==start+1) {
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001784 int badchar = (int)PyUnicode_AS_UNICODE(((PyUnicodeErrorObject *)self)->object)[start];
1785 char badchar_str[20];
1786 if (badchar <= 0xff)
1787 PyOS_snprintf(badchar_str, sizeof(badchar_str), "x%02x", badchar);
1788 else if (badchar <= 0xffff)
1789 PyOS_snprintf(badchar_str, sizeof(badchar_str), "u%04x", badchar);
1790 else
1791 PyOS_snprintf(badchar_str, sizeof(badchar_str), "U%08x", badchar);
1792 return PyString_FromFormat(
Richard Jones7b9558d2006-05-27 12:29:24 +00001793 "can't translate character u'\\%s' in position %zd: %.400s",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001794 badchar_str,
1795 start,
1796 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1797 );
Richard Jones7b9558d2006-05-27 12:29:24 +00001798 }
1799 return PyString_FromFormat(
1800 "can't translate characters in position %zd-%zd: %.400s",
1801 start,
1802 (end-1),
1803 PyString_AS_STRING(((PyUnicodeErrorObject *)self)->reason)
1804 );
1805}
1806
1807static PyTypeObject _PyExc_UnicodeTranslateError = {
1808 PyObject_HEAD_INIT(NULL)
1809 0,
1810 EXC_MODULE_NAME "UnicodeTranslateError",
1811 sizeof(PyUnicodeErrorObject), 0,
1812 (destructor)UnicodeError_dealloc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1813 (reprfunc)UnicodeTranslateError_str, 0, 0, 0,
1814 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1815 PyDoc_STR("Unicode decoding error."), (traverseproc)UnicodeError_traverse,
1816 (inquiry)UnicodeError_clear, 0, 0, 0, 0, 0, UnicodeError_members,
1817 0, &_PyExc_UnicodeError, 0, 0, 0, offsetof(PyUnicodeErrorObject, dict),
Michael W. Hudson96495ee2006-05-28 17:40:29 +00001818 (initproc)UnicodeTranslateError_init, 0, BaseException_new,
Richard Jones7b9558d2006-05-27 12:29:24 +00001819};
1820PyObject *PyExc_UnicodeTranslateError = (PyObject *)&_PyExc_UnicodeTranslateError;
1821
1822PyObject *
1823PyUnicodeTranslateError_Create(
1824 const Py_UNICODE *object, Py_ssize_t length,
1825 Py_ssize_t start, Py_ssize_t end, const char *reason)
1826{
1827 return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001828 object, length, start, end, reason);
Richard Jones7b9558d2006-05-27 12:29:24 +00001829}
1830#endif
1831
1832
1833/*
1834 * AssertionError extends StandardError
1835 */
1836SimpleExtendsException(PyExc_StandardError, AssertionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001837 "Assertion failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001838
1839
1840/*
1841 * ArithmeticError extends StandardError
1842 */
1843SimpleExtendsException(PyExc_StandardError, ArithmeticError,
Richard Jones2d555b32006-05-27 16:15:11 +00001844 "Base class for arithmetic errors.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001845
1846
1847/*
1848 * FloatingPointError extends ArithmeticError
1849 */
1850SimpleExtendsException(PyExc_ArithmeticError, FloatingPointError,
Richard Jones2d555b32006-05-27 16:15:11 +00001851 "Floating point operation failed.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001852
1853
1854/*
1855 * OverflowError extends ArithmeticError
1856 */
1857SimpleExtendsException(PyExc_ArithmeticError, OverflowError,
Richard Jones2d555b32006-05-27 16:15:11 +00001858 "Result too large to be represented.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001859
1860
1861/*
1862 * ZeroDivisionError extends ArithmeticError
1863 */
1864SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,
Richard Jones2d555b32006-05-27 16:15:11 +00001865 "Second argument to a division or modulo operation was zero.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001866
1867
1868/*
1869 * SystemError extends StandardError
1870 */
1871SimpleExtendsException(PyExc_StandardError, SystemError,
1872 "Internal error in the Python interpreter.\n"
1873 "\n"
1874 "Please report this to the Python maintainer, along with the traceback,\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001875 "the Python version, and the hardware/OS platform and version.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001876
1877
1878/*
1879 * ReferenceError extends StandardError
1880 */
1881SimpleExtendsException(PyExc_StandardError, ReferenceError,
Richard Jones2d555b32006-05-27 16:15:11 +00001882 "Weak ref proxy used after referent went away.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001883
1884
1885/*
1886 * MemoryError extends StandardError
1887 */
Richard Jones2d555b32006-05-27 16:15:11 +00001888SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001889
1890
1891/* Warning category docstrings */
1892
1893/*
1894 * Warning extends Exception
1895 */
1896SimpleExtendsException(PyExc_Exception, Warning,
Richard Jones2d555b32006-05-27 16:15:11 +00001897 "Base class for warning categories.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001898
1899
1900/*
1901 * UserWarning extends Warning
1902 */
1903SimpleExtendsException(PyExc_Warning, UserWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001904 "Base class for warnings generated by user code.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001905
1906
1907/*
1908 * DeprecationWarning extends Warning
1909 */
1910SimpleExtendsException(PyExc_Warning, DeprecationWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001911 "Base class for warnings about deprecated features.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001912
1913
1914/*
1915 * PendingDeprecationWarning extends Warning
1916 */
1917SimpleExtendsException(PyExc_Warning, PendingDeprecationWarning,
1918 "Base class for warnings about features which will be deprecated\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001919 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001920
1921
1922/*
1923 * SyntaxWarning extends Warning
1924 */
1925SimpleExtendsException(PyExc_Warning, SyntaxWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001926 "Base class for warnings about dubious syntax.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001927
1928
1929/*
1930 * RuntimeWarning extends Warning
1931 */
1932SimpleExtendsException(PyExc_Warning, RuntimeWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001933 "Base class for warnings about dubious runtime behavior.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001934
1935
1936/*
1937 * FutureWarning extends Warning
1938 */
1939SimpleExtendsException(PyExc_Warning, FutureWarning,
1940 "Base class for warnings about constructs that will change semantically\n"
Richard Jones2d555b32006-05-27 16:15:11 +00001941 "in the future.");
Richard Jones7b9558d2006-05-27 12:29:24 +00001942
1943
1944/*
1945 * ImportWarning extends Warning
1946 */
1947SimpleExtendsException(PyExc_Warning, ImportWarning,
Richard Jones2d555b32006-05-27 16:15:11 +00001948 "Base class for warnings about probable mistakes in module imports");
Richard Jones7b9558d2006-05-27 12:29:24 +00001949
1950
1951/* Pre-computed MemoryError instance. Best to create this as early as
1952 * possible and not wait until a MemoryError is actually raised!
1953 */
1954PyObject *PyExc_MemoryErrorInst=NULL;
1955
1956/* module global functions */
1957static PyMethodDef functions[] = {
1958 /* Sentinel */
1959 {NULL, NULL}
1960};
1961
1962#define PRE_INIT(TYPE) if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \
1963 Py_FatalError("exceptions bootstrapping error.");
1964
1965#define POST_INIT(TYPE) Py_INCREF(PyExc_ ## TYPE); \
1966 PyModule_AddObject(m, # TYPE, PyExc_ ## TYPE); \
1967 if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
1968 Py_FatalError("Module dictionary insertion problem.");
1969
Kristján Valur Jónsson74c3ea02006-07-03 14:59:05 +00001970#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
Kristján Valur Jónssonf6083172006-06-12 15:45:12 +00001971/* crt variable checking in VisualStudio .NET 2005 */
1972#include <crtdbg.h>
1973
1974static int prevCrtReportMode;
1975static _invalid_parameter_handler prevCrtHandler;
1976
1977/* Invalid parameter handler. Sets a ValueError exception */
1978static void
1979InvalidParameterHandler(
1980 const wchar_t * expression,
1981 const wchar_t * function,
1982 const wchar_t * file,
1983 unsigned int line,
1984 uintptr_t pReserved)
1985{
1986 /* Do nothing, allow execution to continue. Usually this
1987 * means that the CRT will set errno to EINVAL
1988 */
1989}
1990#endif
1991
1992
Richard Jones7b9558d2006-05-27 12:29:24 +00001993PyMODINIT_FUNC
Michael W. Hudson22a80e72006-05-28 15:51:40 +00001994_PyExc_Init(void)
Richard Jones7b9558d2006-05-27 12:29:24 +00001995{
1996 PyObject *m, *bltinmod, *bdict;
1997
1998 PRE_INIT(BaseException)
1999 PRE_INIT(Exception)
2000 PRE_INIT(StandardError)
2001 PRE_INIT(TypeError)
2002 PRE_INIT(StopIteration)
2003 PRE_INIT(GeneratorExit)
2004 PRE_INIT(SystemExit)
2005 PRE_INIT(KeyboardInterrupt)
2006 PRE_INIT(ImportError)
2007 PRE_INIT(EnvironmentError)
2008 PRE_INIT(IOError)
2009 PRE_INIT(OSError)
2010#ifdef MS_WINDOWS
2011 PRE_INIT(WindowsError)
2012#endif
2013#ifdef __VMS
2014 PRE_INIT(VMSError)
2015#endif
2016 PRE_INIT(EOFError)
2017 PRE_INIT(RuntimeError)
2018 PRE_INIT(NotImplementedError)
2019 PRE_INIT(NameError)
2020 PRE_INIT(UnboundLocalError)
2021 PRE_INIT(AttributeError)
2022 PRE_INIT(SyntaxError)
2023 PRE_INIT(IndentationError)
2024 PRE_INIT(TabError)
2025 PRE_INIT(LookupError)
2026 PRE_INIT(IndexError)
2027 PRE_INIT(KeyError)
2028 PRE_INIT(ValueError)
2029 PRE_INIT(UnicodeError)
2030#ifdef Py_USING_UNICODE
2031 PRE_INIT(UnicodeEncodeError)
2032 PRE_INIT(UnicodeDecodeError)
2033 PRE_INIT(UnicodeTranslateError)
2034#endif
2035 PRE_INIT(AssertionError)
2036 PRE_INIT(ArithmeticError)
2037 PRE_INIT(FloatingPointError)
2038 PRE_INIT(OverflowError)
2039 PRE_INIT(ZeroDivisionError)
2040 PRE_INIT(SystemError)
2041 PRE_INIT(ReferenceError)
2042 PRE_INIT(MemoryError)
2043 PRE_INIT(Warning)
2044 PRE_INIT(UserWarning)
2045 PRE_INIT(DeprecationWarning)
2046 PRE_INIT(PendingDeprecationWarning)
2047 PRE_INIT(SyntaxWarning)
2048 PRE_INIT(RuntimeWarning)
2049 PRE_INIT(FutureWarning)
2050 PRE_INIT(ImportWarning)
2051
Richard Jonesc5b2a2e2006-05-27 16:07:28 +00002052 m = Py_InitModule4("exceptions", functions, exceptions_doc,
2053 (PyObject *)NULL, PYTHON_API_VERSION);
Richard Jones7b9558d2006-05-27 12:29:24 +00002054 if (m == NULL) return;
2055
2056 bltinmod = PyImport_ImportModule("__builtin__");
2057 if (bltinmod == NULL)
2058 Py_FatalError("exceptions bootstrapping error.");
2059 bdict = PyModule_GetDict(bltinmod);
2060 if (bdict == NULL)
2061 Py_FatalError("exceptions bootstrapping error.");
2062
2063 POST_INIT(BaseException)
2064 POST_INIT(Exception)
2065 POST_INIT(StandardError)
2066 POST_INIT(TypeError)
2067 POST_INIT(StopIteration)
2068 POST_INIT(GeneratorExit)
2069 POST_INIT(SystemExit)
2070 POST_INIT(KeyboardInterrupt)
2071 POST_INIT(ImportError)
2072 POST_INIT(EnvironmentError)
2073 POST_INIT(IOError)
2074 POST_INIT(OSError)
2075#ifdef MS_WINDOWS
2076 POST_INIT(WindowsError)
2077#endif
2078#ifdef __VMS
2079 POST_INIT(VMSError)
2080#endif
2081 POST_INIT(EOFError)
2082 POST_INIT(RuntimeError)
2083 POST_INIT(NotImplementedError)
2084 POST_INIT(NameError)
2085 POST_INIT(UnboundLocalError)
2086 POST_INIT(AttributeError)
2087 POST_INIT(SyntaxError)
2088 POST_INIT(IndentationError)
2089 POST_INIT(TabError)
2090 POST_INIT(LookupError)
2091 POST_INIT(IndexError)
2092 POST_INIT(KeyError)
2093 POST_INIT(ValueError)
2094 POST_INIT(UnicodeError)
2095#ifdef Py_USING_UNICODE
2096 POST_INIT(UnicodeEncodeError)
2097 POST_INIT(UnicodeDecodeError)
2098 POST_INIT(UnicodeTranslateError)
2099#endif
2100 POST_INIT(AssertionError)
2101 POST_INIT(ArithmeticError)
2102 POST_INIT(FloatingPointError)
2103 POST_INIT(OverflowError)
2104 POST_INIT(ZeroDivisionError)
2105 POST_INIT(SystemError)
2106 POST_INIT(ReferenceError)
2107 POST_INIT(MemoryError)
2108 POST_INIT(Warning)
2109 POST_INIT(UserWarning)
2110 POST_INIT(DeprecationWarning)
2111 POST_INIT(PendingDeprecationWarning)
2112 POST_INIT(SyntaxWarning)
2113 POST_INIT(RuntimeWarning)
2114 POST_INIT(FutureWarning)
2115 POST_INIT(ImportWarning)
2116
2117 PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL);
2118 if (!PyExc_MemoryErrorInst)
2119 Py_FatalError("Cannot pre-allocate MemoryError instance\n");
2120
2121 Py_DECREF(bltinmod);
Kristján Valur Jónssonf6083172006-06-12 15:45:12 +00002122
Kristján Valur Jónsson74c3ea02006-07-03 14:59:05 +00002123#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
Kristján Valur Jónssonf6083172006-06-12 15:45:12 +00002124 /* Set CRT argument error handler */
2125 prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
2126 /* turn off assertions in debug mode */
2127 prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
2128#endif
Richard Jones7b9558d2006-05-27 12:29:24 +00002129}
2130
2131void
2132_PyExc_Fini(void)
2133{
2134 Py_XDECREF(PyExc_MemoryErrorInst);
2135 PyExc_MemoryErrorInst = NULL;
Kristján Valur Jónsson74c3ea02006-07-03 14:59:05 +00002136#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
Kristján Valur Jónssonf6083172006-06-12 15:45:12 +00002137 /* reset CRT error handling */
2138 _set_invalid_parameter_handler(prevCrtHandler);
2139 _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
2140#endif
Richard Jones7b9558d2006-05-27 12:29:24 +00002141}