Commit 7d45c8b0 authored by Marius Wachtler's avatar Marius Wachtler

Add buffering argument support to open()

parent 79ad8be8
......@@ -94,6 +94,7 @@
#define HAVE_POLL_H 1
#define HAVE_PTHREAD_H 1
#define HAVE_PTY_H 1
#define HAVE_SETVBUF 1
#define HAVE_SHADOW_H 1
#define HAVE_SIGNAL_H 1
#define HAVE_SPAWN_H 1
......
......@@ -235,10 +235,11 @@ extern "C" Box* id(Box* arg) {
}
Box* open(Box* arg1, Box* arg2) {
Box* open(Box* arg1, Box* arg2, Box* arg3) {
assert(arg2);
assert(arg3);
// This could be optimized quite a bit if it ends up being important:
return runtimeCall(file_cls, ArgPassSpec(2), arg1, arg2, NULL, NULL, NULL);
return runtimeCall(file_cls, ArgPassSpec(3), arg1, arg2, arg3, NULL, NULL);
}
extern "C" Box* chr(Box* arg) {
......@@ -1108,9 +1109,9 @@ void setupBuiltins() {
setupXrange();
builtins_module->giveAttr("xrange", xrange_cls);
open_obj = new BoxedBuiltinFunctionOrMethod(
boxRTFunction((void*)open, typeFromClass(file_cls), 2, 1, false, false, ParamNames({ "name", "mode" }, "", "")),
"open", { boxStrConstant("r") });
open_obj = new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)open, typeFromClass(file_cls), 3, 2, false, false,
ParamNames({ "name", "mode", "buffering" }, "", "")),
"open", { boxStrConstant("r"), boxInt(-1) });
builtins_module->giveAttr("open", open_obj);
builtins_module->giveAttr("globals", new BoxedBuiltinFunctionOrMethod(
......
......@@ -805,7 +805,9 @@ Box* fileExit(BoxedFile* self, Box* exc_type, Box* exc_val, Box** args) {
}
// This differs very significantly from CPython:
Box* fileNew(BoxedClass* cls, Box* s, Box* m) {
Box* fileNew(BoxedClass* cls, Box* s, Box* m, Box** args) {
BoxedInt* buffering = (BoxedInt*)args[0];
assert(cls == file_cls);
if (s->cls == unicode_cls)
......@@ -823,6 +825,9 @@ Box* fileNew(BoxedClass* cls, Box* s, Box* m) {
raiseExcHelper(TypeError, "");
}
if (!PyInt_Check(buffering))
raiseExcHelper(TypeError, "an integer is required");
auto fn = static_cast<BoxedString*>(s);
auto mode = static_cast<BoxedString*>(m);
......@@ -840,7 +845,9 @@ Box* fileNew(BoxedClass* cls, Box* s, Box* m) {
abort(); // unreachable;
}
return new BoxedFile(f, fn->s, PyString_AsString(m));
auto file = new BoxedFile(f, fn->s, PyString_AsString(m));
PyFile_SetBufSize(file, buffering->n);
return file;
}
static PyObject* file_readlines(BoxedFile* f, PyObject* args) noexcept {
......@@ -1111,12 +1118,38 @@ extern "C" int PyFile_WriteString(const char* s, PyObject* f) noexcept {
extern "C" void PyFile_SetBufSize(PyObject* f, int bufsize) noexcept {
assert(f->cls == file_cls);
BoxedFile* file = (BoxedFile*)f;
if (bufsize >= 0) {
if (bufsize == 0) {
setvbuf(static_cast<BoxedFile*>(f)->f_fp, NULL, _IONBF, 0);
int type;
switch (bufsize) {
case 0:
type = _IONBF;
break;
#ifdef HAVE_SETVBUF
case 1:
type = _IOLBF;
bufsize = BUFSIZ;
break;
#endif
default:
type = _IOFBF;
#ifndef HAVE_SETVBUF
bufsize = BUFSIZ;
#endif
break;
}
fflush(file->f_fp);
if (type == _IONBF) {
PyMem_Free(file->f_setbuf);
file->f_setbuf = NULL;
} else {
Py_FatalError("unimplemented");
file->f_setbuf = (char*)PyMem_Realloc(file->f_setbuf, bufsize);
}
#ifdef HAVE_SETVBUF
setvbuf(file->f_fp, file->f_setbuf, type, bufsize);
#else /* !HAVE_SETVBUF */
setbuf(file->f_fp, file->f_setbuf);
#endif /* !HAVE_SETVBUF */
}
}
......@@ -1426,6 +1459,7 @@ void BoxedFile::gcHandler(GCVisitor* v, Box* b) {
v->visit(f->f_mode);
v->visit(f->f_encoding);
v->visit(f->f_errors);
v->visit(f->f_setbuf);
}
void setupFile() {
......@@ -1455,8 +1489,8 @@ void setupFile() {
file_cls->giveAttr("softspace",
new BoxedMemberDescriptor(BoxedMemberDescriptor::INT, offsetof(BoxedFile, f_softspace), false));
file_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)fileNew, UNKNOWN, 3, 1, false, false),
{ boxStrConstant("r") }));
file_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)fileNew, UNKNOWN, 4, 2, false, false),
{ boxStrConstant("r"), boxInt(-1) }));
for (auto& md : file_methods) {
file_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, file_cls));
......
......@@ -65,7 +65,6 @@ extern "C" BoxedString* strOrNull(Box* obj); // similar to str, but returns NUL
extern "C" bool exceptionMatches(Box* obj, Box* cls);
extern "C" BoxedInt* hash(Box* obj);
extern "C" Box* abs_(Box* obj);
Box* open(Box* arg1, Box* arg2);
// extern "C" Box* chr(Box* arg);
extern "C" Box* compare(Box*, Box*, int);
extern "C" BoxedInt* len(Box* obj);
......
......@@ -75,6 +75,8 @@ with open(fn) as f:
with open(fn, "rU") as f:
print len(f.readlines())
with open(fn, "r", 1) as f:
print len(f.readlines())
fd, fn = tempfile.mkstemp()
try:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment