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

Add buffering argument support to open()

parent 79ad8be8
...@@ -94,6 +94,7 @@ ...@@ -94,6 +94,7 @@
#define HAVE_POLL_H 1 #define HAVE_POLL_H 1
#define HAVE_PTHREAD_H 1 #define HAVE_PTHREAD_H 1
#define HAVE_PTY_H 1 #define HAVE_PTY_H 1
#define HAVE_SETVBUF 1
#define HAVE_SHADOW_H 1 #define HAVE_SHADOW_H 1
#define HAVE_SIGNAL_H 1 #define HAVE_SIGNAL_H 1
#define HAVE_SPAWN_H 1 #define HAVE_SPAWN_H 1
......
...@@ -235,10 +235,11 @@ extern "C" Box* id(Box* arg) { ...@@ -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(arg2);
assert(arg3);
// This could be optimized quite a bit if it ends up being important: // 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) { extern "C" Box* chr(Box* arg) {
...@@ -1108,9 +1109,9 @@ void setupBuiltins() { ...@@ -1108,9 +1109,9 @@ void setupBuiltins() {
setupXrange(); setupXrange();
builtins_module->giveAttr("xrange", xrange_cls); builtins_module->giveAttr("xrange", xrange_cls);
open_obj = new BoxedBuiltinFunctionOrMethod( open_obj = new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)open, typeFromClass(file_cls), 3, 2, false, false,
boxRTFunction((void*)open, typeFromClass(file_cls), 2, 1, false, false, ParamNames({ "name", "mode" }, "", "")), ParamNames({ "name", "mode", "buffering" }, "", "")),
"open", { boxStrConstant("r") }); "open", { boxStrConstant("r"), boxInt(-1) });
builtins_module->giveAttr("open", open_obj); builtins_module->giveAttr("open", open_obj);
builtins_module->giveAttr("globals", new BoxedBuiltinFunctionOrMethod( builtins_module->giveAttr("globals", new BoxedBuiltinFunctionOrMethod(
......
...@@ -805,7 +805,9 @@ Box* fileExit(BoxedFile* self, Box* exc_type, Box* exc_val, Box** args) { ...@@ -805,7 +805,9 @@ Box* fileExit(BoxedFile* self, Box* exc_type, Box* exc_val, Box** args) {
} }
// This differs very significantly from CPython: // 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); assert(cls == file_cls);
if (s->cls == unicode_cls) if (s->cls == unicode_cls)
...@@ -823,6 +825,9 @@ Box* fileNew(BoxedClass* cls, Box* s, Box* m) { ...@@ -823,6 +825,9 @@ Box* fileNew(BoxedClass* cls, Box* s, Box* m) {
raiseExcHelper(TypeError, ""); raiseExcHelper(TypeError, "");
} }
if (!PyInt_Check(buffering))
raiseExcHelper(TypeError, "an integer is required");
auto fn = static_cast<BoxedString*>(s); auto fn = static_cast<BoxedString*>(s);
auto mode = static_cast<BoxedString*>(m); auto mode = static_cast<BoxedString*>(m);
...@@ -840,7 +845,9 @@ Box* fileNew(BoxedClass* cls, Box* s, Box* m) { ...@@ -840,7 +845,9 @@ Box* fileNew(BoxedClass* cls, Box* s, Box* m) {
abort(); // unreachable; 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 { static PyObject* file_readlines(BoxedFile* f, PyObject* args) noexcept {
...@@ -1111,12 +1118,38 @@ extern "C" int PyFile_WriteString(const char* s, PyObject* f) 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 { extern "C" void PyFile_SetBufSize(PyObject* f, int bufsize) noexcept {
assert(f->cls == file_cls); assert(f->cls == file_cls);
BoxedFile* file = (BoxedFile*)f;
if (bufsize >= 0) { if (bufsize >= 0) {
if (bufsize == 0) { int type;
setvbuf(static_cast<BoxedFile*>(f)->f_fp, NULL, _IONBF, 0); 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 { } 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) { ...@@ -1426,6 +1459,7 @@ void BoxedFile::gcHandler(GCVisitor* v, Box* b) {
v->visit(f->f_mode); v->visit(f->f_mode);
v->visit(f->f_encoding); v->visit(f->f_encoding);
v->visit(f->f_errors); v->visit(f->f_errors);
v->visit(f->f_setbuf);
} }
void setupFile() { void setupFile() {
...@@ -1455,8 +1489,8 @@ void setupFile() { ...@@ -1455,8 +1489,8 @@ void setupFile() {
file_cls->giveAttr("softspace", file_cls->giveAttr("softspace",
new BoxedMemberDescriptor(BoxedMemberDescriptor::INT, offsetof(BoxedFile, f_softspace), false)); new BoxedMemberDescriptor(BoxedMemberDescriptor::INT, offsetof(BoxedFile, f_softspace), false));
file_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)fileNew, UNKNOWN, 3, 1, false, false), file_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)fileNew, UNKNOWN, 4, 2, false, false),
{ boxStrConstant("r") })); { boxStrConstant("r"), boxInt(-1) }));
for (auto& md : file_methods) { for (auto& md : file_methods) {
file_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, file_cls)); 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 ...@@ -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" bool exceptionMatches(Box* obj, Box* cls);
extern "C" BoxedInt* hash(Box* obj); extern "C" BoxedInt* hash(Box* obj);
extern "C" Box* abs_(Box* obj); extern "C" Box* abs_(Box* obj);
Box* open(Box* arg1, Box* arg2);
// extern "C" Box* chr(Box* arg); // extern "C" Box* chr(Box* arg);
extern "C" Box* compare(Box*, Box*, int); extern "C" Box* compare(Box*, Box*, int);
extern "C" BoxedInt* len(Box* obj); extern "C" BoxedInt* len(Box* obj);
......
...@@ -75,6 +75,8 @@ with open(fn) as f: ...@@ -75,6 +75,8 @@ with open(fn) as f:
with open(fn, "rU") as f: with open(fn, "rU") as f:
print len(f.readlines()) print len(f.readlines())
with open(fn, "r", 1) as f:
print len(f.readlines())
fd, fn = tempfile.mkstemp() fd, fn = tempfile.mkstemp()
try: 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