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