source: python/vendor/current/Python/errors.c

Last change on this file was 388, checked in by dmik, 11 years ago

python: Update vendor to 2.7.6.

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