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