span>len] = L'\0';
message = PyUnicode_FromWideChar(s_buf, len);
}
if (message == NULL)
{
LocalFree(s_buf);
return NULL;
}
if (filenameObject == NULL) {
assert(filenameObject2 == NULL);
filenameObject = filenameObject2 = Py_None;
}
else if (filenameObject2 == NULL)
filenameObject2 = Py_None;
/* This is the constructor signature for OSError.
The POSIX translation will be figured out by the constructor. */
args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2);
Py_DECREF(message);
if (args != NULL) {
v = PyObject_Call(exc, args, NULL);
Py_DECREF(args);
if (v != NULL) {
_PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v);
Py_DECREF(v);
}
}
LocalFree(s_buf);
return NULL;
}
PyObject *PyErr_SetExcFromWindowsErrWithFilename(
PyObject *exc,
int ierr,
const char *filename)
{
PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
ierr,
name,
NULL);
Py_XDECREF(name);
return ret;
}
PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
{
return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
}
PyObject *PyErr_SetFromWindowsErr(int ierr)
{
return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError,
ierr, NULL);
}
PyObject *PyErr_SetFromWindowsErrWithFilename(
int ierr,
const char *filename)
{
PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
PyExc_OSError,
ierr, name, NULL);
Py_XDECREF(name);
return result;
}
#endif /* MS_WINDOWS */
static PyObject *
_PyErr_SetImportErrorSubclassWithNameFrom(
PyObject *exception, PyObject *msg,
PyObject *name, PyObject *path, PyObject* from_name)
{
PyThreadState *tstate = _PyThreadState_GET();
int issubclass;
PyObject *kwargs, *error;
issubclass = PyObject_IsSubclass(exception, PyExc_ImportError);
if (issubclass < 0) {
return NULL;
}
else if (!issubclass) {
_PyErr_SetString(tstate, PyExc_TypeError,
"expected a subclass of ImportError");
return NULL;
}
if (msg == NULL) {
_PyErr_SetString(tstate, PyExc_TypeError,
"expected a message argument");
return NULL;
}
if (name == NULL) {
name = Py_None;
}
if (path == NULL) {
path = Py_None;
}
if (from_name == NULL) {
from_name = Py_None;
}
kwargs = PyDict_New();
if (kwargs == NULL) {
return NULL;
}
if (PyDict_SetItemString(kwargs, "name", name) < 0) {
goto done;
}
if (PyDict_SetItemString(kwargs, "path", path) < 0) {
goto done;
}
if (PyDict_SetItemString(kwargs, "name_from", from_name) < 0) {
goto done;
}
error = PyObject_VectorcallDict(exception, &msg, 1, kwargs);
if (error != NULL) {
_PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error);
Py_DECREF(error);
}
done:
Py_DECREF(kwargs);
return NULL;
}
PyObject *
PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg,
PyObject *name, PyObject *path)
{
return _PyErr_SetImportErrorSubclassWithNameFrom(exception, msg, name, path, NULL);
}
PyObject *
_PyErr_SetImportErrorWithNameFrom(PyObject *msg, PyObject *name, PyObject *path, PyObject* from_name)
{
return _PyErr_SetImportErrorSubclassWithNameFrom(PyExc_ImportError, msg, name, path, from_name);
}
PyObject *
PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
{
return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, path);
}
void
_PyErr_BadInternalCall(const char *filename, int lineno)
{
PyThreadState *tstate = _PyThreadState_GET();
_PyErr_Format(tstate, PyExc_SystemError,
"%s:%d: bad argument to internal function",
filename, lineno);
}
/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
export the entry point for existing object code: */
#undef PyErr_BadInternalCall
void
PyErr_BadInternalCall(void)
{
assert(0 && "bad argument to internal function");
PyThreadState *tstate = _PyThreadState_GET();
_PyErr_SetString(tstate, PyExc_SystemError,
"bad argument to internal function");
}
#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
static PyObject *
_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
const char *format, va_list vargs)
{
PyObject* string;
/* Issue #23571: PyUnicode_FromFormatV() must not be called with an
exception set, it calls arbitrary Python code like PyObject_Repr() */
_PyErr_Clear(tstate);
string = PyUnicode_FromFormatV(format, vargs);
_PyErr_SetObject(tstate, exception, string);
Py_XDECREF(string);
return NULL;
}
PyObject *
PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
{
PyThreadState *tstate = _PyThreadState_GET();
return _PyErr_FormatV(tstate, exception, format, vargs);
}
PyObject *
_PyErr_Format(PyThreadState *tstate, PyObject *exception,
const char *format, ...)
{
va_list vargs;
va_start(vargs, format);
_PyErr_FormatV(tstate, exception, format, vargs);
va_end(vargs);
return NULL;
}
PyObject *
PyErr_Format(PyObject *exception, const char *format, ...)
{
PyThreadState *tstate = _PyThreadState_GET();
va_list vargs;
va_start(vargs, format);
_PyErr_FormatV(tstate, exception, format, vargs);
va_end(vargs);
return NULL;
}
/* Adds a note to the current exception (if any) */
void
_PyErr_FormatNote(const char *format, ...)
{
PyObject *exc = PyErr_GetRaisedException();
if (exc == NULL) {
return;
}
va_list vargs;
va_start(vargs, format);
PyObject *note = PyUnicode_FromFormatV(format, vargs);
va_end(vargs);
if (note == NULL) {
goto error;
}
int res = _PyException_AddNote(exc, note);
Py_DECREF(note);
if (res < 0) {
goto error;
}
PyErr_SetRaisedException(exc);
return;
error:
_PyErr_ChainExceptions1(exc);
}
PyObject *
PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *modulename = NULL;
PyObject *mydict = NULL;
PyObject *bases = NULL;
PyObject *result = NULL;
const char *dot = strrchr(name, '.');
if (dot == NULL) {
_PyErr_SetString(tstate, PyExc_SystemError,
"PyErr_NewException: name must be module.class");
return NULL;
}
if (base == NULL) {
base = PyExc_Exception;
}
if (dict == NULL) {
dict = mydict = PyDict_New();
if (dict == NULL)
goto failure;
}
int r = PyDict_Contains(dict, &_Py_ID(__module__));
if (r < 0) {
goto failure;
}
if (r == 0) {
modulename = PyUnicode_FromStringAndSize(name,
(Py_ssize_t)(dot-name));
if (modulename == NULL)
goto failure;
if (PyDict_SetItem(dict, &_Py_ID(__module__), modulename) != 0)
goto failure;
}
if (PyTuple_Check(base)) {
bases = Py_NewRef(base);
} else {
bases = PyTuple_Pack(1, base);
if (bases == NULL)
goto failure;
}
/* Create a real class. */
result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
dot+1, bases, dict);
failure:
Py_XDECREF(bases);
Py_XDECREF(mydict);
Py_XDECREF(modulename);
return result;
}
/* Create an exception with docstring */
PyObject *
PyErr_NewExceptionWithDoc(const char *name, const char *doc,
PyObject *base, PyObject *dict)
{
int result;
PyObject *ret = NULL;
PyObject *mydict = NULL; /* points to the dict only if we create it */
PyObject *docobj;
if (dict == NULL) {
dict = mydict = PyDict_New();
if (dict == NULL) {
return NULL;
}
}
if (doc != NULL) {
docobj = PyUnicode_FromString(doc);
if (docobj == NULL)
goto failure;
result = PyDict_SetItemString(dict, "__doc__", docobj);
Py_DECREF(docobj);
if (result < 0)
goto failure;
}
ret = PyErr_NewException(name, base, dict);
failure:
Py_XDECREF(mydict);
return ret;
}
PyDoc_STRVAR(UnraisableHookArgs__doc__,
"UnraisableHookArgs\n\
\n\
Type used to pass arguments to sys.unraisablehook.");
static PyTypeObject UnraisableHookArgsType;
static PyStructSequence_Field UnraisableHookArgs_fields[] = {
{"exc_type", "Exception type"},
{"exc_value", "Exception value"},
{"exc_traceback", "Exception traceback"},
{"err_msg", "Error message"},
{"object", "Object causing the exception"},
{0}
};
static PyStructSequence_Desc UnraisableHookArgs_desc = {
.name = "UnraisableHookArgs",
.doc = UnraisableHookArgs__doc__,
.fields = UnraisableHookArgs_fields,
.n_in_sequence = 5
};
PyStatus
_PyErr_InitTypes(PyInterpreterState *interp)
{
if (_PyStructSequence_InitBuiltin(interp, &UnraisableHookArgsType,
&UnraisableHookArgs_desc) < 0)
{
return _PyStatus_ERR("failed to initialize UnraisableHookArgs type");
}
return _PyStatus_OK();
}
void
_PyErr_FiniTypes(PyInterpreterState *interp)
{
_PyStructSequence_FiniBuiltin(interp, &UnraisableHookArgsType);
}
static PyObject *
make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type,
PyObject *exc_value, PyObject *exc_tb,
PyObject *err_msg, PyObject *obj)
{
PyObject *args = PyStructSequence_New(&UnraisableHookArgsType);
if (args == NULL) {
return NULL;
}
Py_ssize_t pos = 0;
#define ADD_ITEM(exc_type) \
do { \
if (exc_type == NULL) { \
exc_type = Py_None; \
} \
PyStructSequence_SET_ITEM(args, pos++, Py_NewRef(exc_type)); \
} while (0)
ADD_ITEM(exc_type);
ADD_ITEM(exc_value);
ADD_ITEM(exc_tb);
ADD_ITEM(err_msg);
ADD_ITEM(obj);
#undef ADD_ITEM
if (_PyErr_Occurred(tstate)) {
Py_DECREF(args);
return NULL;
}
return args;
}
/* Default implementation of sys.unraisablehook.
It can be called to log the exception of a custom sys.unraisablehook.
Do nothing if sys.stderr attribute doesn't exist or is set to None. */
static int
write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type,
PyObject *exc_value, PyObject *exc_tb,
PyObject *err_msg, PyObject *obj, PyObject *file)
{
if (obj != NULL && obj != Py_None) {
if (err_msg != NULL && err_msg != Py_None) {
if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) {
return -1;
}
if (PyFile_WriteString(": ", file) < 0) {
return -1;
}
}
else {
if (PyFile_WriteString("Exception ignored in: ", file) < 0) {
return -1;
}
}
if (PyFile_WriteObject(obj, file, 0) < 0) {
_PyErr_Clear(tstate);
if (PyFile_WriteString("<object repr() failed>", file) < 0) {
return -1;
}
}
if (PyFile_WriteString("\n", file) < 0) {
return -1;
}
}
else if (err_msg != NULL && err_msg != Py_None) {
if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) {
return -1;
}
if (PyFile_WriteString(":\n", file) < 0) {
return -1;
}
}
if (exc_tb != NULL && exc_tb != Py_None) {
if (PyTraceBack_Print(exc_tb, file) < 0) {
/* continue even if writing the traceback failed */
_PyErr_Clear(tstate);
}
}
if (exc_type == NULL || exc_type == Py_None) {
return -1;
}
assert(PyExceptionClass_Check(exc_type));
PyObject *modulename = PyObject_GetAttr(exc_type, &_Py_ID(__module__));
if (modulename == NULL || !PyUnicode_Check(modulename)) {
Py_XDECREF(modulename);
_PyErr_Clear(tstate);
if (PyFile_WriteString("<unknown>", file) < 0) {
return -1;
}
}
else {
if (!_PyUnicode_Equal(modulename, &_Py_ID(builtins)) &&
!_PyUnicode_Equal(modulename, &_Py_ID(__main__))) {
if (PyFile_WriteObject(modulename, file, Py_PRINT_RAW) < 0) {
Py_DECREF(modulename);
return -1;
}
Py_DECREF(modulename);
if (PyFile_WriteString(".", file) < 0) {
return -1;
}
}
else {
Py_DECREF(modulename);
}
}
PyObject *qualname = PyType_GetQualName((PyTypeObject *)exc_type);
if (qualname == NULL || !PyUnicode_Check(qualname)) {
Py_XDECREF(qualname);
_PyErr_Clear(tstate);
if (PyFile_WriteString("<unknown>", file) < 0) {
return -1;
}
}
else {
if (PyFile_WriteObject(qualname, file, Py_PRINT_RAW) < 0) {
Py_DECREF(qualname);
return -1;
}
Py_DECREF(qualname);
}
if (exc_value && exc_value != Py_None) {
if (PyFile_WriteString(": ", file) < 0) {
return -1;
}
if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) {
_PyErr_Clear(tstate);
if (PyFile_WriteString("<exception str() failed>", file) < 0) {
return -1;
}
}
}
if (PyFile_WriteString("\n", file) < 0) {
return -1;
}
/* Explicitly call file.flush() */
PyObject *res = _PyObject_CallMethodNoArgs(file, &_Py_ID(flush));
if (!res) {
return -1;
}
Py_DECREF(res);
return 0;
}
static int
write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type,
PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg,
PyObject *obj)
{
PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr));
if (file == NULL || file == Py_None) {
return 0;
}
/* Hold a strong reference to ensure that sys.stderr doesn't go away
while we use it */
Py_INCREF(file);
int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb,
err_msg, obj, file);
Py_DECREF(file);
return res;
}
PyObject*
_PyErr_WriteUnraisableDefaultHook(PyObject *args)
{
PyThreadState *tstate = _PyThreadState_GET();
if (!Py_IS_TYPE(args, &UnraisableHookArgsType)) {
_PyErr_SetString(tstate, PyExc_TypeError,
"sys.unraisablehook argument type "
"must be UnraisableHookArgs");
return NULL;
}
/* Borrowed references */
PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3);
PyObject *obj = PyStructSequence_GET_ITEM(args, 4);
if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) {
return NULL;
}
Py_RETURN_NONE;
}
/* Call sys.unraisablehook().
This function can be used when an exception has occurred but there is no way
for Python to handle it. For example, when a destructor raises an exception
or during garbage collection (gc.collect()).
If err_msg_str is non-NULL, the error message is formatted as:
"Exception ignored %s" % err_msg_str. Otherwise, use "Exception ignored in"
error message.
An exception must be set when calling this function. */
void
_PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj)
{
PyThreadState *tstate = _PyThreadState_GET();
_Py_EnsureTstateNotNULL(tstate);
PyObject *err_msg = NULL;
PyObject *exc_type, *exc_value, *exc_tb;
_PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
assert(exc_type != NULL);
if (exc_type == NULL) {
/* sys.unraisablehook requires that at least exc_type is set */
goto default_hook;
}
if (exc_tb == NULL) {
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
if (frame != NULL) {
exc_tb = _PyTraceBack_FromFrame(NULL, frame);
if (exc_tb == NULL) {
_PyErr_Clear(tstate);
}
Py_DECREF(frame);
}
}
_PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb);
if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) {
if (PyException_SetTraceback(exc_value, exc_tb) < 0) {
_PyErr_Clear(tstate);
}
}
if (err_msg_str != NULL) {
err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str);
if (err_msg == NULL) {
PyErr_Clear();
}
}
PyObject *hook_args = make_unraisable_hook_args(
tstate, exc_type, exc_value, exc_tb, err_msg, obj);
if (hook_args == NULL) {
err_msg_str = ("Exception ignored on building "
"sys.unraisablehook arguments");
goto error;
}
PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(unraisablehook));
if (hook == NULL) {
Py_DECREF(hook_args);
goto default_hook;
}
if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) {
Py_DECREF(hook_args);
err_msg_str = "Exception ignored in audit hook";
obj = NULL;
goto error;
}
if (hook == Py_None) {
Py_DECREF(hook_args);
goto default_hook;
}
PyObject *res = PyObject_CallOneArg(hook, hook_args);
Py_DECREF(hook_args);
if (res != NULL) {
Py_DECREF(res);
goto done;
}
/* sys.unraisablehook failed: log its error using default hook */
obj = hook;
err_msg_str = NULL;
error:
/* err_msg_str and obj have been updated and we have a new exception */
Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ?
err_msg_str : "Exception ignored in sys.unraisablehook"));
Py_XDECREF(exc_type);
Py_XDECREF(exc_value);
Py_XDECREF(exc_tb);
_PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
default_hook:
/* Call the default unraisable hook (ignore failure) */
(void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb,
err_msg, obj);
done:
Py_XDECREF(exc_type);
Py_XDECREF(exc_value);
Py_XDECREF(exc_tb);
Py_XDECREF(err_msg);
_PyErr_Clear(tstate); /* Just in case */
}
void
PyErr_WriteUnraisable(PyObject *obj)
{
_PyErr_WriteUnraisableMsg(NULL, obj);
}
void
PyErr_SyntaxLocation(const char *filename, int lineno)
{
PyErr_SyntaxLocationEx(filename, lineno, -1);
}
/* Set file and line information for the current exception.
If the exception is not a SyntaxError, also sets additional attributes
to make printing of exceptions believe it is a syntax error. */
static void
PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset,
int end_lineno, int end_col_offset)
{
PyThreadState *tstate = _PyThreadState_GET();
/* add attributes for the line number and filename for the error */
PyObject *exc = _PyErr_GetRaisedException(tstate);
/* XXX check that it is, indeed, a syntax error. It might not
* be, though. */
PyObject *tmp = PyLong_FromLong(lineno);
if (tmp == NULL) {
_PyErr_Clear(tstate);
}
else {
if (PyObject_SetAttr(exc, &_Py_ID(lineno), tmp)) {
_PyErr_Clear(tstate);
}
Py_DECREF(tmp);
}
tmp = NULL;
if (col_offset >= 0) {
tmp = PyLong_FromLong(col_offset);
if (tmp == NULL) {
_PyErr_Clear(tstate);
}
}
if (PyObject_SetAttr(exc, &_Py_ID(offset), tmp ? tmp : Py_None)) {
_PyErr_Clear(tstate);
}
Py_XDECREF(tmp);
tmp = NULL;
if (end_lineno >= 0) {
tmp = PyLong_FromLong(end_lineno);
if (tmp == NULL) {
_PyErr_Clear(tstate);
}
}
if (PyObject_SetAttr(exc, &_Py_ID(end_lineno), tmp ? tmp : Py_None)) {
_PyErr_Clear(tstate);
}
Py_XDECREF(tmp);
tmp = NULL;
if (end_col_offset >= 0) {
tmp = PyLong_FromLong(end_col_offset);
if (tmp == NULL) {
_PyErr_Clear(tstate);
}
}
if (PyObject_SetAttr(exc, &_Py_ID(end_offset), tmp ? tmp : Py_None)) {
_PyErr_Clear(tstate);
}
Py_XDECREF(tmp);
tmp = NULL;
if (filename != NULL) {
if (PyObject_SetAttr(exc, &_Py_ID(filename), filename)) {
_PyErr_Clear(tstate);
}
tmp = PyErr_ProgramTextObject(filename, lineno);
if (tmp) {
if (PyObject_SetAttr(exc, &_Py_ID(text), tmp)) {
_PyErr_Clear(tstate);
}
Py_DECREF(tmp);
}
else {
_PyErr_Clear(tstate);
}
}
if ((PyObject *)Py_TYPE(exc) != PyExc_SyntaxError) {
if (_PyObject_LookupAttr(exc, &_Py_ID(msg), &tmp) < 0) {
_PyErr_Clear(tstate);
}
else if (tmp) {
Py_DECREF(tmp);
}
else {
tmp = PyObject_Str(exc);
if (tmp) {
if (PyObject_SetAttr(exc, &_Py_ID(msg), tmp)) {
_PyErr_Clear(tstate);
}
Py_DECREF(tmp);
}
else {
_PyErr_Clear(tstate);
}
}
if (_PyObject_LookupAttr(exc, &_Py_ID(print_file_and_line), &tmp) < 0) {
_PyErr_Clear(tstate);
}
else if (tmp) {
Py_DECREF(tmp);
}
else {
if (PyObject_SetAttr(exc, &_Py_ID(print_file_and_line), Py_None)) {
_PyErr_Clear(tstate);
}
}
}
_PyErr_SetRaisedException(tstate, exc);
}
void
PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) {
PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, lineno, -1);
}
void
PyErr_RangedSyntaxLocationObject(PyObject *filename, int lineno, int col_offset,
int end_lineno, int end_col_offset) {
PyErr_SyntaxLocationObjectEx(filename, lineno, col_offset, end_lineno, end_col_offset);
}
void
PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
{
PyThreadState *tstate = _PyThreadState_GET();
PyObject *fileobj;
if (filename != NULL) {
fileobj = PyUnicode_DecodeFSDefault(filename);
if (fileobj == NULL) {
_PyErr_Clear(tstate);
}
}
else {
fileobj = NULL;
}
PyErr_SyntaxLocationObject(fileobj, lineno, col_offset);
Py_XDECREF(fileobj);
}
/* Attempt to load the line of text that the exception refers to. If it
fails, it will return NULL but will not set an exception.
XXX The functionality of this function is quite similar to the
functionality in tb_displayline() in traceback.c. */
static PyObject *
err_programtext(PyThreadState *tstate, FILE *fp, int lineno, const char* encoding)
{
int i;
char linebuf[1000];
if (fp == NULL) {
return NULL;
}
for (i = 0; i < lineno; i++) {
char *pLastChar = &linebuf[sizeof(linebuf) - 2];
do {
*pLastChar = '\0';
if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf,
fp, NULL) == NULL) {
goto after_loop;
}
/* fgets read *something*; if it didn't get as
far as pLastChar, it must have found a newline
or hit the end of the file; if pLastChar is \n,
it obviously found a newline; else we haven't
yet seen a newline, so must continue */
} while (*pLastChar != '\0' && *pLastChar != '\n');
}
after_loop:
fclose(fp);
if (i == lineno) {
PyObject *res;
if (encoding != NULL) {
res = PyUnicode_Decode(linebuf, strlen(linebuf), encoding, "replace");
} else {
res = PyUnicode_FromString(linebuf);
}
if (res == NULL)
_PyErr_Clear(tstate);
return res;
}
return NULL;
}
PyObject *
PyErr_ProgramText(const char *filename, int lineno)
{
if (filename == NULL) {
return NULL;
}
PyObject *filename_obj = PyUnicode_DecodeFSDefault(filename);
if (filename_obj == NULL) {
PyErr_Clear();
return NULL;
}
PyObject *res = PyErr_ProgramTextObject(filename_obj, lineno);
Py_DECREF(filename_obj);
return res;
}
PyObject *
_PyErr_ProgramDecodedTextObject(PyObject *filename, int lineno, const char* encoding)
{
if (filename == NULL || lineno <= 0) {
return NULL;
}
PyThreadState *tstate = _PyThreadState_GET();
FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE);
if (fp == NULL) {
_PyErr_Clear(tstate);
return NULL;
}
return err_programtext(tstate, fp, lineno, encoding);
}
PyObject *
PyErr_ProgramTextObject(PyObject *filename, int lineno)
{
return _PyErr_ProgramDecodedTextObject(filename, lineno, NULL);
}
#ifdef __cplusplus
}
#endif
|