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