History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Python/errors.c (1 of 3706 files). Show all

Unified · Split

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