SBFile::GetFile: convert SBFile back into python native files.
Summary: This makes SBFile::GetFile public and adds a SWIG typemap to convert the result back into a python native file. If the underlying File itself came from a python file, it is returned identically. Otherwise a new python file object is created using the file descriptor. Reviewers: JDevlieghere, jasonmolenda, labath Reviewed By: labath Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D68737 llvm-svn: 374911
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "lldb/Utility/Stream.h"
|
||||
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/ConvertUTF.h"
|
||||
#include "llvm/Support/Errno.h"
|
||||
|
||||
@@ -1012,8 +1013,6 @@ operator()(std::initializer_list<PythonObject> args) {
|
||||
|
||||
PythonFile::PythonFile() : PythonObject() {}
|
||||
|
||||
PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); }
|
||||
|
||||
PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); }
|
||||
|
||||
PythonFile::~PythonFile() {}
|
||||
@@ -1063,25 +1062,6 @@ void PythonFile::Reset(PyRefType type, PyObject *py_obj) {
|
||||
PythonObject::Reset(PyRefType::Borrowed, result.get());
|
||||
}
|
||||
|
||||
void PythonFile::Reset(File &file, const char *mode) {
|
||||
if (!file.IsValid()) {
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
char *cmode = const_cast<char *>(mode);
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
Reset(PyRefType::Owned, PyFile_FromFd(file.GetDescriptor(), nullptr, cmode,
|
||||
-1, nullptr, "ignore", nullptr, 0));
|
||||
#else
|
||||
// Read through the Python source, doesn't seem to modify these strings
|
||||
Reset(PyRefType::Owned,
|
||||
PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode,
|
||||
nullptr));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
FileUP PythonFile::GetUnderlyingFile() const {
|
||||
if (!IsValid())
|
||||
return nullptr;
|
||||
@@ -1238,6 +1218,13 @@ public:
|
||||
return base_error;
|
||||
};
|
||||
|
||||
PyObject *GetPythonObject() const {
|
||||
assert(m_py_obj.IsValid());
|
||||
return m_py_obj.get();
|
||||
}
|
||||
|
||||
static bool classof(const File *file) = delete;
|
||||
|
||||
protected:
|
||||
PythonFile m_py_obj;
|
||||
bool m_borrowed;
|
||||
@@ -1252,7 +1239,14 @@ public:
|
||||
SimplePythonFile(const PythonFile &file, bool borrowed, int fd,
|
||||
File::OpenOptions options)
|
||||
: OwnedPythonFile(file, borrowed, fd, options, false) {}
|
||||
|
||||
static char ID;
|
||||
bool isA(const void *classID) const override {
|
||||
return classID == &ID || NativeFile::isA(classID);
|
||||
}
|
||||
static bool classof(const File *file) { return file->isA(&ID); }
|
||||
};
|
||||
char SimplePythonFile::ID = 0;
|
||||
} // namespace
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
@@ -1321,7 +1315,18 @@ public:
|
||||
return Status();
|
||||
}
|
||||
|
||||
Expected<File::OpenOptions> GetOptions() const override {
|
||||
GIL takeGIL;
|
||||
return GetOptionsForPyObject(m_py_obj);
|
||||
}
|
||||
|
||||
static char ID;
|
||||
bool isA(const void *classID) const override {
|
||||
return classID == &ID || File::isA(classID);
|
||||
}
|
||||
static bool classof(const File *file) { return file->isA(&ID); }
|
||||
};
|
||||
char PythonIOFile::ID = 0;
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
@@ -1542,4 +1547,42 @@ PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed) {
|
||||
#endif
|
||||
}
|
||||
|
||||
Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) {
|
||||
if (!file.IsValid())
|
||||
return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
||||
"invalid file");
|
||||
|
||||
if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
|
||||
return Retain<PythonFile>(simple->GetPythonObject());
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
|
||||
return Retain<PythonFile>(pythonio->GetPythonObject());
|
||||
#endif
|
||||
|
||||
if (!mode) {
|
||||
auto m = file.GetOpenMode();
|
||||
if (!m)
|
||||
return m.takeError();
|
||||
mode = m.get();
|
||||
}
|
||||
|
||||
PyObject *file_obj;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr,
|
||||
"ignore", nullptr, 0);
|
||||
#else
|
||||
// Read through the Python source, doesn't seem to modify these strings
|
||||
char *cmode = const_cast<char *>(mode);
|
||||
// We pass ::flush instead of ::fclose here so we borrow the FILE* --
|
||||
// the lldb_private::File still owns it.
|
||||
file_obj =
|
||||
PyFile_FromFile(file.GetStream(), const_cast<char *>(""), cmode, ::fflush);
|
||||
#endif
|
||||
|
||||
if (!file_obj)
|
||||
return exception();
|
||||
|
||||
return Take<PythonFile>(file_obj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user