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
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 Py_XINCREF(exception);
56 Py_XINCREF(value);
57 PyErr_Restore(exception, value, (PyObject *)NULL);
58}
59
60void
61PyErr_SetNone(PyObject *exception)
62{
63 PyErr_SetObject(exception, (PyObject *)NULL);
64}
65
66void
67PyErr_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
75PyObject *
76PyErr_Occurred(void)
77{
78 PyThreadState *tstate = PyThreadState_GET();
79
80 return tstate->curexc_type;
81}
82
83
84int
85PyErr_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
118int
119PyErr_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*/
128void
129PyErr_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;
194finally:
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
214void
215PyErr_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
228void
229PyErr_Clear(void)
230{
231 PyErr_Restore(NULL, NULL, NULL);
232}
233
234/* Convenience functions to set a type error exception and return 0 */
235
236int
237PyErr_BadArgument(void)
238{
239 PyErr_SetString(PyExc_TypeError,
240 "bad argument type for built-in operation");
241 return 0;
242}
243
244PyObject *
245PyErr_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
263PyObject *
264PyErr_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
343PyObject *
344PyErr_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
353PyObject *
354PyErr_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
365PyObject *
366PyErr_SetFromErrno(PyObject *exc)
367{
368 return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);
369}
370
371#ifdef MS_WINDOWS
372/* Windows specific error code handling */
373PyObject *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
420PyObject *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
434PyObject *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
450PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
451{
452 return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
453}
454
455PyObject *PyErr_SetFromWindowsErr(int ierr)
456{
457 return PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,
458 ierr, NULL);
459}
460PyObject *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
473PyObject *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
489void
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
500void
501PyErr_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
510PyObject *
511PyErr_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
531PyObject *
532PyErr_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. */
583void
584PyErr_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
636extern PyObject *PyModule_GetWarningsModule(void);
637
638/* Function to issue a warning message; may raise an exception. */
639int
640PyErr_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
673PyAPI_FUNC(int)
674PyErr_Warn(PyObject *category, char *message)
675{
676 return PyErr_WarnEx(category, message, 1);
677}
678
679/* Warning with explicit origin */
680int
681PyErr_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
718void
719PyErr_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
784PyObject *
785PyErr_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