• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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