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