Commit 89d0615c authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #203 from jvkersch/file-iter-168

Small improvements for file objects.
parents 26de61ba cfe83db0
......@@ -211,9 +211,9 @@ Box* open(Box* arg1, Box* arg2) {
FILE* f = fopen(fn.c_str(), mode.c_str());
if (!f)
raiseExcHelper(IOError, "%s: '%s' '%s'", strerror(errno), fn.c_str());
raiseExcHelper(IOError, "[Error %d] %s: '%s'", errno, strerror(errno), fn.c_str());
return new BoxedFile(f);
return new BoxedFile(f, fn, mode);
}
extern "C" Box* chr(Box* arg) {
......
......@@ -112,9 +112,9 @@ void setupSys() {
sys_module->giveAttr("argv", new BoxedList());
sys_module->giveAttr("stdout", new BoxedFile(stdout));
sys_module->giveAttr("stdin", new BoxedFile(stdin));
sys_module->giveAttr("stderr", new BoxedFile(stderr));
sys_module->giveAttr("stdout", new BoxedFile(stdout, "<stdout>", "w"));
sys_module->giveAttr("stdin", new BoxedFile(stdin, "<stdin>", "r"));
sys_module->giveAttr("stderr", new BoxedFile(stderr, "<stderr>", "w"));
sys_module->giveAttr("warnoptions", new BoxedList());
sys_module->giveAttr("py3kwarning", False);
......
......@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cstdio>
#include <cstring>
#include <sstream>
......@@ -26,7 +27,14 @@ namespace pyston {
Box* fileRepr(BoxedFile* self) {
assert(self->cls == file_cls);
RELEASE_ASSERT(0, "");
void* addr = static_cast<void*>(self->f);
std::ostringstream repr;
repr << "<" << (self->closed ? "closed" : "open") << " file '" << self->fname << "', ";
repr << "mode '" << self->fmode << "' at " << addr << ">";
return boxString(repr.str());
}
Box* fileRead(BoxedFile* self, Box* _size) {
......@@ -154,6 +162,22 @@ Box* fileNew(BoxedClass* cls, Box* s, Box* m) {
return open(s, m);
}
Box* fileIterNext(BoxedFile* s) {
return fileReadline1(s);
}
bool fileEof(BoxedFile* self) {
char ch = fgetc(self->f);
ungetc(ch, self->f);
return feof(self->f);
}
Box* fileIterHasNext(Box* s) {
assert(s->cls == file_cls);
BoxedFile* self = static_cast<BoxedFile*>(s);
return boxBool(!fileEof(self));
}
void setupFile() {
file_cls->giveAttr("__name__", boxStrConstant("file"));
......@@ -172,6 +196,10 @@ void setupFile() {
file_cls->giveAttr("__enter__", new BoxedFunction(boxRTFunction((void*)fileEnter, typeFromClass(file_cls), 1)));
file_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)fileExit, UNKNOWN, 4)));
file_cls->giveAttr("__iter__", file_cls->getattr("__enter__"));
file_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)fileIterHasNext, BOXED_BOOL, 1)));
file_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)fileIterNext, STR, 1)));
file_cls->giveAttr("softspace",
new BoxedMemberDescriptor(BoxedMemberDescriptor::BYTE, offsetof(BoxedFile, softspace)));
......
......@@ -290,9 +290,12 @@ extern "C" BoxedTuple* EmptyTuple;
class BoxedFile : public Box {
public:
FILE* f;
std::string fname;
std::string fmode;
bool closed;
bool softspace;
BoxedFile(FILE* f) __attribute__((visibility("default"))) : Box(file_cls), f(f), closed(false), softspace(false) {}
BoxedFile(FILE* f, std::string fname, std::string fmode) __attribute__((visibility("default")))
: Box(file_cls), f(f), fname(fname), fmode(fmode), closed(false), softspace(false) {}
};
struct PyHasher {
......
import sys
f = open("/dev/null")
print repr(f.read())
......@@ -6,3 +8,39 @@ print repr(f2.read())
with open("/dev/null") as f3:
print repr(f3.read())
# String representation of file objects.
def chop(s):
"""Chop off the last bit of a file object repr, which is the address
of the raw file pointer.
"""
return ' '.join(s.split()[:-1])
for desc in [sys.stderr, sys.stdout, sys.stdin]:
print chop(str(desc))
f = open("/dev/null", 'w')
print chop(str(f))
f.close()
print chop(str(f))
f = open("/dev/null", 'r')
print chop(str(f))
f.close()
print chop(str(f))
# Support for iteration protocol.
f = open('/dev/null')
print iter(f) is f
f.close()
with open('../README.md') as f:
lines = list(f)
print lines[:5]
print lines[-5:]
# Check that opening a non-existent file results in an IOError.
try:
f = open('this-should-definitely-not-exist.txt')
except IOError as e:
print str(e)
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