annotate cos/python/Python/errors.c @ 39:600f48b74799

Move ide
author windel
date Fri, 03 Feb 2012 18:40:43 +0100
parents 7f74363f4c82
children
rev   line source
27
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2 /* Error handling */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4 #include "Python.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
5
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
6 #ifndef __STDC__
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
7 #ifndef MS_WINDOWS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
8 extern char *strerror(int);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
9 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
10 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
11
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
12 #ifdef MS_WINDOWS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
13 #include <windows.h>
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
14 #include <winbase.h>
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
15 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
16
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
17 #include <ctype.h>
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
18
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
19 #ifdef __cplusplus
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
20 extern "C" {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
21 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
22
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
23
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
24 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
25 PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
26 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
27 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
28 PyObject *oldtype, *oldvalue, *oldtraceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
29
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
30 if (traceback != NULL && !PyTraceBack_Check(traceback)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
31 /* XXX Should never happen -- fatal error instead? */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
32 /* Well, it could be None. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
33 Py_DECREF(traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
34 traceback = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
35 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
36
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
37 /* Save these in locals to safeguard against recursive
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
38 invocation through Py_XDECREF */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
39 oldtype = tstate->curexc_type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
40 oldvalue = tstate->curexc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
41 oldtraceback = tstate->curexc_traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
42
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
43 tstate->curexc_type = type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
44 tstate->curexc_value = value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
45 tstate->curexc_traceback = traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
46
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
47 Py_XDECREF(oldtype);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
48 Py_XDECREF(oldvalue);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
49 Py_XDECREF(oldtraceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
50 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
51
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
52 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
53 PyErr_SetObject(PyObject *exception, PyObject *value)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
54 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
55 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
56 PyObject *exc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
57 PyObject *tb = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
58
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
59 if (exception != NULL &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
60 !PyExceptionClass_Check(exception)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
61 PyErr_Format(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
62 "exception %R not a BaseException subclass",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
63 exception);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
64 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
65 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
66 Py_XINCREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
67 exc_value = tstate->exc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
68 if (exc_value != NULL && exc_value != Py_None) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
69 /* Implicit exception chaining */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
70 Py_INCREF(exc_value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
71 if (value == NULL || !PyExceptionInstance_Check(value)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
72 /* We must normalize the value right now */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
73 PyObject *args, *fixed_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
74 if (value == NULL || value == Py_None)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
75 args = PyTuple_New(0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
76 else if (PyTuple_Check(value)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
77 Py_INCREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
78 args = value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
79 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
80 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
81 args = PyTuple_Pack(1, value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
82 fixed_value = args ?
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
83 PyEval_CallObject(exception, args) : NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
84 Py_XDECREF(args);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
85 Py_XDECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
86 if (fixed_value == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
87 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
88 value = fixed_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
89 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
90 /* Avoid reference cycles through the context chain.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
91 This is O(chain length) but context chains are
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
92 usually very short. Sensitive readers may try
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
93 to inline the call to PyException_GetContext. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
94 if (exc_value != value) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
95 PyObject *o = exc_value, *context;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
96 while ((context = PyException_GetContext(o))) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
97 Py_DECREF(context);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
98 if (context == value) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
99 PyException_SetContext(o, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
100 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
101 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
102 o = context;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
103 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
104 PyException_SetContext(value, exc_value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
105 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
106 Py_DECREF(exc_value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
107 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
108 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
109 if (value != NULL && PyExceptionInstance_Check(value))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
110 tb = PyException_GetTraceback(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
111 Py_XINCREF(exception);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
112 PyErr_Restore(exception, value, tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
113 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
114
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
115 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
116 PyErr_SetNone(PyObject *exception)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
117 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
118 PyErr_SetObject(exception, (PyObject *)NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
119 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
120
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
121 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
122 PyErr_SetString(PyObject *exception, const char *string)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
123 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
124 PyObject *value = PyUnicode_FromString(string);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
125 PyErr_SetObject(exception, value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
126 Py_XDECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
127 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
128
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
129
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
130 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
131 PyErr_Occurred(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
132 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
133 /* If there is no thread state, PyThreadState_GET calls
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
134 Py_FatalError, which calls PyErr_Occurred. To avoid the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
135 resulting infinite loop, we inline PyThreadState_GET here and
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
136 treat no thread as no error. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
137 PyThreadState *tstate =
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
138 ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
139
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
140 return tstate == NULL ? NULL : tstate->curexc_type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
141 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
142
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
143
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
144 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
145 PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
146 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
147 if (err == NULL || exc == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
148 /* maybe caused by "import exceptions" that failed early on */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
149 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
150 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
151 if (PyTuple_Check(exc)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
152 Py_ssize_t i, n;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
153 n = PyTuple_Size(exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
154 for (i = 0; i < n; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
155 /* Test recursively */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
156 if (PyErr_GivenExceptionMatches(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
157 err, PyTuple_GET_ITEM(exc, i)))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
158 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
159 return 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
160 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
161 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
162 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
163 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
164 /* err might be an instance, so check its class. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
165 if (PyExceptionInstance_Check(err))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
166 err = PyExceptionInstance_Class(err);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
167
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
168 if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
169 int res = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
170 PyObject *exception, *value, *tb;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
171 PyErr_Fetch(&exception, &value, &tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
172 /* PyObject_IsSubclass() can recurse and therefore is
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
173 not safe (see test_bad_getattr in test.pickletester). */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
174 res = PyType_IsSubtype((PyTypeObject *)err, (PyTypeObject *)exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
175 /* This function must not fail, so print the error here */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
176 if (res == -1) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
177 PyErr_WriteUnraisable(err);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
178 res = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
179 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
180 PyErr_Restore(exception, value, tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
181 return res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
182 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
183
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
184 return err == exc;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
185 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
186
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
187
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
188 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
189 PyErr_ExceptionMatches(PyObject *exc)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
190 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
191 return PyErr_GivenExceptionMatches(PyErr_Occurred(), exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
192 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
193
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
194
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
195 /* Used in many places to normalize a raised exception, including in
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
196 eval_code2(), do_raise(), and PyErr_Print()
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
197
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
198 XXX: should PyErr_NormalizeException() also call
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
199 PyException_SetTraceback() with the resulting value and tb?
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
200 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
201 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
202 PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
203 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
204 PyObject *type = *exc;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
205 PyObject *value = *val;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
206 PyObject *inclass = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
207 PyObject *initial_tb = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
208 PyThreadState *tstate = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
209
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
210 if (type == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
211 /* There was no exception, so nothing to do. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
212 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
213 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
214
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
215 /* If PyErr_SetNone() was used, the value will have been actually
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
216 set to NULL.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
217 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
218 if (!value) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
219 value = Py_None;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
220 Py_INCREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
221 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
222
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
223 if (PyExceptionInstance_Check(value))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
224 inclass = PyExceptionInstance_Class(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
225
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
226 /* Normalize the exception so that if the type is a class, the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
227 value will be an instance.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
228 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
229 if (PyExceptionClass_Check(type)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
230 /* if the value was not an instance, or is not an instance
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
231 whose class is (or is derived from) type, then use the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
232 value as an argument to instantiation of the type
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
233 class.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
234 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
235 if (!inclass || !PyObject_IsSubclass(inclass, type)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
236 PyObject *args, *res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
237
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
238 if (value == Py_None)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
239 args = PyTuple_New(0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
240 else if (PyTuple_Check(value)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
241 Py_INCREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
242 args = value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
243 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
244 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
245 args = PyTuple_Pack(1, value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
246
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
247 if (args == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
248 goto finally;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
249 res = PyEval_CallObject(type, args);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
250 Py_DECREF(args);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
251 if (res == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
252 goto finally;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
253 Py_DECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
254 value = res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
255 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
256 /* if the class of the instance doesn't exactly match the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
257 class of the type, believe the instance
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
258 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
259 else if (inclass != type) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
260 Py_DECREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
261 type = inclass;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
262 Py_INCREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
263 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
264 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
265 *exc = type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
266 *val = value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
267 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
268 finally:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
269 Py_DECREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
270 Py_DECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
271 /* If the new exception doesn't set a traceback and the old
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
272 exception had a traceback, use the old traceback for the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
273 new exception. It's better than nothing.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
274 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
275 initial_tb = *tb;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
276 PyErr_Fetch(exc, val, tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
277 if (initial_tb != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
278 if (*tb == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
279 *tb = initial_tb;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
280 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
281 Py_DECREF(initial_tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
282 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
283 /* normalize recursively */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
284 tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
285 if (++tstate->recursion_depth > Py_GetRecursionLimit()) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
286 --tstate->recursion_depth;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
287 /* throw away the old exception... */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
288 Py_DECREF(*exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
289 Py_DECREF(*val);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
290 /* ... and use the recursion error instead */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
291 *exc = PyExc_RuntimeError;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
292 *val = PyExc_RecursionErrorInst;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
293 Py_INCREF(*exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
294 Py_INCREF(*val);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
295 /* just keeping the old traceback */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
296 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
297 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
298 PyErr_NormalizeException(exc, val, tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
299 --tstate->recursion_depth;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
300 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
301
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
302
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
303 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
304 PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
305 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
306 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
307
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
308 *p_type = tstate->curexc_type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
309 *p_value = tstate->curexc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
310 *p_traceback = tstate->curexc_traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
311
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
312 tstate->curexc_type = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
313 tstate->curexc_value = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
314 tstate->curexc_traceback = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
315 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
316
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
317 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
318 PyErr_Clear(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
319 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
320 PyErr_Restore(NULL, NULL, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
321 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
322
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
323 /* Convenience functions to set a type error exception and return 0 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
324
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
325 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
326 PyErr_BadArgument(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
327 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
328 PyErr_SetString(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
329 "bad argument type for built-in operation");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
330 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
331 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
332
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
333 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
334 PyErr_NoMemory(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
335 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
336 PyErr_SetNone(PyExc_MemoryError);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
337 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
338 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
339
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
340 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
341 PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
342 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
343 PyObject *message;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
344 PyObject *v, *args;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
345 int i = errno;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
346 #ifdef MS_WINDOWS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
347 WCHAR *s_buf = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
348 #endif /* Unix/Windows */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
349
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
350 #ifdef EINTR
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
351 if (i == EINTR && PyErr_CheckSignals())
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
352 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
353 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
354
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
355 #ifndef MS_WINDOWS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
356 if (i != 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
357 char *s = strerror(i);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
358 message = PyUnicode_DecodeLocale(s, "surrogateescape");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
359 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
360 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
361 /* Sometimes errno didn't get set */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
362 message = PyUnicode_FromString("Error");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
363 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
364 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
365 if (i == 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
366 message = PyUnicode_FromString("Error"); /* Sometimes errno didn't get set */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
367 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
368 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
369 /* Note that the Win32 errors do not lineup with the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
370 errno error. So if the error is in the MSVC error
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
371 table, we use it, otherwise we assume it really _is_
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
372 a Win32 error code
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
373 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
374 if (i > 0 && i < _sys_nerr) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
375 message = PyUnicode_FromString(_sys_errlist[i]);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
376 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
377 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
378 int len = FormatMessageW(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
379 FORMAT_MESSAGE_ALLOCATE_BUFFER |
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
380 FORMAT_MESSAGE_FROM_SYSTEM |
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
381 FORMAT_MESSAGE_IGNORE_INSERTS,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
382 NULL, /* no message source */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
383 i,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
384 MAKELANGID(LANG_NEUTRAL,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
385 SUBLANG_DEFAULT),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
386 /* Default language */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
387 (LPWSTR) &s_buf,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
388 0, /* size not used */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
389 NULL); /* no args */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
390 if (len==0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
391 /* Only ever seen this in out-of-mem
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
392 situations */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
393 s_buf = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
394 message = PyUnicode_FromFormat("Windows Error 0x%X", i);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
395 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
396 /* remove trailing cr/lf and dots */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
397 while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
398 s_buf[--len] = L'\0';
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
399 message = PyUnicode_FromWideChar(s_buf, len);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
400 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
401 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
402 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
403 #endif /* Unix/Windows */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
404
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
405 if (message == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
406 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
407 #ifdef MS_WINDOWS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
408 LocalFree(s_buf);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
409 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
410 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
411 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
412
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
413 if (filenameObject != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
414 args = Py_BuildValue("(iOO)", i, message, filenameObject);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
415 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
416 args = Py_BuildValue("(iO)", i, message);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
417 Py_DECREF(message);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
418
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
419 if (args != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
420 v = PyObject_Call(exc, args, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
421 Py_DECREF(args);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
422 if (v != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
423 PyErr_SetObject((PyObject *) Py_TYPE(v), v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
424 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
425 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
426 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
427 #ifdef MS_WINDOWS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
428 LocalFree(s_buf);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
429 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
430 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
431 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
432
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
433
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
434 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
435 PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
436 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
437 PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
438 PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
439 Py_XDECREF(name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
440 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
441 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
442
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
443 #ifdef MS_WINDOWS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
444 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
445 PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
446 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
447 PyObject *name = filename ?
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
448 PyUnicode_FromUnicode(filename, wcslen(filename)) :
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
449 NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
450 PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
451 Py_XDECREF(name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
452 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
453 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
454 #endif /* MS_WINDOWS */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
455
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
456 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
457 PyErr_SetFromErrno(PyObject *exc)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
458 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
459 return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
460 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
461
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
462 #ifdef MS_WINDOWS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
463 /* Windows specific error code handling */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
464 PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
465 PyObject *exc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
466 int ierr,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
467 PyObject *filenameObject)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
468 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
469 int len;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
470 WCHAR *s_buf = NULL; /* Free via LocalFree */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
471 PyObject *message;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
472 PyObject *args, *v;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
473 DWORD err = (DWORD)ierr;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
474 if (err==0) err = GetLastError();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
475 len = FormatMessageW(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
476 /* Error API error */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
477 FORMAT_MESSAGE_ALLOCATE_BUFFER |
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
478 FORMAT_MESSAGE_FROM_SYSTEM |
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
479 FORMAT_MESSAGE_IGNORE_INSERTS,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
480 NULL, /* no message source */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
481 err,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
482 MAKELANGID(LANG_NEUTRAL,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
483 SUBLANG_DEFAULT), /* Default language */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
484 (LPWSTR) &s_buf,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
485 0, /* size not used */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
486 NULL); /* no args */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
487 if (len==0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
488 /* Only seen this in out of mem situations */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
489 message = PyUnicode_FromFormat("Windows Error 0x%X", err);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
490 s_buf = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
491 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
492 /* remove trailing cr/lf and dots */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
493 while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
494 s_buf[--len] = L'\0';
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
495 message = PyUnicode_FromWideChar(s_buf, len);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
496 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
497
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
498 if (message == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
499 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
500 LocalFree(s_buf);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
501 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
502 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
503
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
504 if (filenameObject == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
505 filenameObject = Py_None;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
506 /* This is the constructor signature for passing a Windows error code.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
507 The POSIX translation will be figured out by the constructor. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
508 args = Py_BuildValue("(iOOi)", 0, message, filenameObject, err);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
509 Py_DECREF(message);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
510
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
511 if (args != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
512 v = PyObject_Call(exc, args, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
513 Py_DECREF(args);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
514 if (v != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
515 PyErr_SetObject((PyObject *) Py_TYPE(v), v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
516 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
517 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
518 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
519 LocalFree(s_buf);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
520 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
521 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
522
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
523 PyObject *PyErr_SetExcFromWindowsErrWithFilename(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
524 PyObject *exc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
525 int ierr,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
526 const char *filename)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
527 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
528 PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
529 PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
530 ierr,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
531 name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
532 Py_XDECREF(name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
533 return ret;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
534 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
535
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
536 PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
537 PyObject *exc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
538 int ierr,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
539 const Py_UNICODE *filename)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
540 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
541 PyObject *name = filename ?
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
542 PyUnicode_FromUnicode(filename, wcslen(filename)) :
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
543 NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
544 PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
545 ierr,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
546 name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
547 Py_XDECREF(name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
548 return ret;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
549 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
550
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
551 PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
552 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
553 return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
554 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
555
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
556 PyObject *PyErr_SetFromWindowsErr(int ierr)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
557 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
558 return PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
559 ierr, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
560 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
561 PyObject *PyErr_SetFromWindowsErrWithFilename(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
562 int ierr,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
563 const char *filename)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
564 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
565 PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
566 PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
567 PyExc_WindowsError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
568 ierr, name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
569 Py_XDECREF(name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
570 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
571 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
572
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
573 PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
574 int ierr,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
575 const Py_UNICODE *filename)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
576 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
577 PyObject *name = filename ?
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
578 PyUnicode_FromUnicode(filename, wcslen(filename)) :
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
579 NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
580 PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
581 PyExc_WindowsError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
582 ierr, name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
583 Py_XDECREF(name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
584 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
585 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
586 #endif /* MS_WINDOWS */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
587
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
588 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
589 _PyErr_BadInternalCall(const char *filename, int lineno)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
590 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
591 PyErr_Format(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
592 "%s:%d: bad argument to internal function",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
593 filename, lineno);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
594 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
595
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
596 /* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
597 export the entry point for existing object code: */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
598 #undef PyErr_BadInternalCall
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
599 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
600 PyErr_BadInternalCall(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
601 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
602 PyErr_Format(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
603 "bad argument to internal function");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
604 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
605 #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
606
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
607
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
608
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
609 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
610 PyErr_Format(PyObject *exception, const char *format, ...)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
611 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
612 va_list vargs;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
613 PyObject* string;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
614
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
615 #ifdef HAVE_STDARG_PROTOTYPES
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
616 va_start(vargs, format);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
617 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
618 va_start(vargs);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
619 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
620
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
621 string = PyUnicode_FromFormatV(format, vargs);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
622 PyErr_SetObject(exception, string);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
623 Py_XDECREF(string);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
624 va_end(vargs);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
625 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
626 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
627
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
628
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
629
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
630 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
631 PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
632 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
633 const char *dot;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
634 PyObject *modulename = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
635 PyObject *classname = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
636 PyObject *mydict = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
637 PyObject *bases = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
638 PyObject *result = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
639 dot = strrchr(name, '.');
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
640 if (dot == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
641 PyErr_SetString(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
642 "PyErr_NewException: name must be module.class");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
643 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
644 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
645 if (base == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
646 base = PyExc_Exception;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
647 if (dict == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
648 dict = mydict = PyDict_New();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
649 if (dict == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
650 goto failure;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
651 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
652 if (PyDict_GetItemString(dict, "__module__") == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
653 modulename = PyUnicode_FromStringAndSize(name,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
654 (Py_ssize_t)(dot-name));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
655 if (modulename == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
656 goto failure;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
657 if (PyDict_SetItemString(dict, "__module__", modulename) != 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
658 goto failure;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
659 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
660 if (PyTuple_Check(base)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
661 bases = base;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
662 /* INCREF as we create a new ref in the else branch */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
663 Py_INCREF(bases);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
664 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
665 bases = PyTuple_Pack(1, base);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
666 if (bases == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
667 goto failure;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
668 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
669 /* Create a real class. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
670 result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
671 dot+1, bases, dict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
672 failure:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
673 Py_XDECREF(bases);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
674 Py_XDECREF(mydict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
675 Py_XDECREF(classname);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
676 Py_XDECREF(modulename);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
677 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
678 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
679
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
680
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
681 /* Create an exception with docstring */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
682 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
683 PyErr_NewExceptionWithDoc(const char *name, const char *doc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
684 PyObject *base, PyObject *dict)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
685 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
686 int result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
687 PyObject *ret = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
688 PyObject *mydict = NULL; /* points to the dict only if we create it */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
689 PyObject *docobj;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
690
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
691 if (dict == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
692 dict = mydict = PyDict_New();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
693 if (dict == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
694 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
695 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
696 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
697
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
698 if (doc != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
699 docobj = PyUnicode_FromString(doc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
700 if (docobj == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
701 goto failure;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
702 result = PyDict_SetItemString(dict, "__doc__", docobj);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
703 Py_DECREF(docobj);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
704 if (result < 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
705 goto failure;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
706 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
707
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
708 ret = PyErr_NewException(name, base, dict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
709 failure:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
710 Py_XDECREF(mydict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
711 return ret;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
712 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
713
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
714
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
715 /* Call when an exception has occurred but there is no way for Python
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
716 to handle it. Examples: exception in __del__ or during GC. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
717 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
718 PyErr_WriteUnraisable(PyObject *obj)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
719 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
720 _Py_IDENTIFIER(__module__);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
721 PyObject *f, *t, *v, *tb;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
722 PyErr_Fetch(&t, &v, &tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
723 f = PySys_GetObject("stderr");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
724 if (f != NULL && f != Py_None) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
725 PyFile_WriteString("Exception ", f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
726 if (t) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
727 PyObject* moduleName;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
728 char* className;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
729 assert(PyExceptionClass_Check(t));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
730 className = PyExceptionClass_Name(t);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
731 if (className != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
732 char *dot = strrchr(className, '.');
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
733 if (dot != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
734 className = dot+1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
735 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
736
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
737 moduleName = _PyObject_GetAttrId(t, &PyId___module__);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
738 if (moduleName == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
739 PyFile_WriteString("<unknown>", f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
740 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
741 char* modstr = _PyUnicode_AsString(moduleName);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
742 if (modstr &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
743 strcmp(modstr, "builtins") != 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
744 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
745 PyFile_WriteString(modstr, f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
746 PyFile_WriteString(".", f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
747 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
748 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
749 if (className == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
750 PyFile_WriteString("<unknown>", f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
751 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
752 PyFile_WriteString(className, f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
753 if (v && v != Py_None) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
754 PyFile_WriteString(": ", f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
755 PyFile_WriteObject(v, f, 0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
756 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
757 Py_XDECREF(moduleName);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
758 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
759 if (obj) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
760 PyFile_WriteString(" in ", f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
761 PyFile_WriteObject(obj, f, 0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
762 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
763 PyFile_WriteString(" ignored\n", f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
764 PyErr_Clear(); /* Just in case */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
765 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
766 Py_XDECREF(t);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
767 Py_XDECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
768 Py_XDECREF(tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
769 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
770
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
771 extern PyObject *PyModule_GetWarningsModule(void);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
772
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
773
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
774 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
775 PyErr_SyntaxLocation(const char *filename, int lineno) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
776 PyErr_SyntaxLocationEx(filename, lineno, -1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
777 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
778
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
779
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
780 /* Set file and line information for the current exception.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
781 If the exception is not a SyntaxError, also sets additional attributes
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
782 to make printing of exceptions believe it is a syntax error. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
783
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
784 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
785 PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
786 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
787 PyObject *exc, *v, *tb, *tmp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
788 _Py_IDENTIFIER(filename);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
789 _Py_IDENTIFIER(lineno);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
790 _Py_IDENTIFIER(msg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
791 _Py_IDENTIFIER(offset);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
792 _Py_IDENTIFIER(print_file_and_line);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
793 _Py_IDENTIFIER(text);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
794
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
795 /* add attributes for the line number and filename for the error */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
796 PyErr_Fetch(&exc, &v, &tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
797 PyErr_NormalizeException(&exc, &v, &tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
798 /* XXX check that it is, indeed, a syntax error. It might not
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
799 * be, though. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
800 tmp = PyLong_FromLong(lineno);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
801 if (tmp == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
802 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
803 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
804 if (_PyObject_SetAttrId(v, &PyId_lineno, tmp))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
805 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
806 Py_DECREF(tmp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
807 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
808 if (col_offset >= 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
809 tmp = PyLong_FromLong(col_offset);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
810 if (tmp == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
811 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
812 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
813 if (_PyObject_SetAttrId(v, &PyId_offset, tmp))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
814 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
815 Py_DECREF(tmp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
816 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
817 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
818 if (filename != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
819 tmp = PyUnicode_DecodeFSDefault(filename);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
820 if (tmp == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
821 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
822 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
823 if (_PyObject_SetAttrId(v, &PyId_filename, tmp))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
824 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
825 Py_DECREF(tmp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
826 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
827
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
828 tmp = PyErr_ProgramText(filename, lineno);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
829 if (tmp) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
830 if (_PyObject_SetAttrId(v, &PyId_text, tmp))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
831 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
832 Py_DECREF(tmp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
833 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
834 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
835 if (_PyObject_SetAttrId(v, &PyId_offset, Py_None)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
836 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
837 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
838 if (exc != PyExc_SyntaxError) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
839 if (!_PyObject_HasAttrId(v, &PyId_msg)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
840 tmp = PyObject_Str(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
841 if (tmp) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
842 if (_PyObject_SetAttrId(v, &PyId_msg, tmp))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
843 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
844 Py_DECREF(tmp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
845 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
846 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
847 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
848 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
849 if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
850 if (_PyObject_SetAttrId(v, &PyId_print_file_and_line,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
851 Py_None))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
852 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
853 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
854 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
855 PyErr_Restore(exc, v, tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
856 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
857
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
858 /* Attempt to load the line of text that the exception refers to. If it
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
859 fails, it will return NULL but will not set an exception.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
860
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
861 XXX The functionality of this function is quite similar to the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
862 functionality in tb_displayline() in traceback.c. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
863
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
864 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
865 PyErr_ProgramText(const char *filename, int lineno)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
866 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
867 FILE *fp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
868 int i;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
869 char linebuf[1000];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
870
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
871 if (filename == NULL || *filename == '\0' || lineno <= 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
872 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
873 fp = fopen(filename, "r" PY_STDIOTEXTMODE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
874 if (fp == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
875 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
876 for (i = 0; i < lineno; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
877 char *pLastChar = &linebuf[sizeof(linebuf) - 2];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
878 do {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
879 *pLastChar = '\0';
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
880 if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
881 fp, NULL) == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
882 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
883 /* fgets read *something*; if it didn't get as
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
884 far as pLastChar, it must have found a newline
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
885 or hit the end of the file; if pLastChar is \n,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
886 it obviously found a newline; else we haven't
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
887 yet seen a newline, so must continue */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
888 } while (*pLastChar != '\0' && *pLastChar != '\n');
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
889 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
890 fclose(fp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
891 if (i == lineno) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
892 char *p = linebuf;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
893 PyObject *res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
894 while (*p == ' ' || *p == '\t' || *p == '\014')
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
895 p++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
896 res = PyUnicode_FromString(p);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
897 if (res == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
898 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
899 return res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
900 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
901 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
902 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
903
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
904 #ifdef __cplusplus
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
905 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
906 #endif