# HG changeset patch # User Paul Boddie # Date 1483831622 -3600 # Node ID 28e2996df412498f7cb5256a5d10221e51b48649 # Parent 06c4fdc8da56050ebfaeef1d0ad3a746ca77b8e6 Added stream flushing to make raw_input work properly. Introduced separate readline approaches for streams and files, where streams are read one byte at a time, whereas files are read in chunks according to the specified buffer size. diff -r 06c4fdc8da56 -r 28e2996df412 lib/__builtins__/file.py --- a/lib/__builtins__/file.py Sat Jan 07 16:23:25 2017 +0100 +++ b/lib/__builtins__/file.py Sun Jan 08 00:27:02 2017 +0100 @@ -20,7 +20,7 @@ """ from __builtins__.types import check_int, check_string -from native import isinstance as _isinstance, fclose, fopen, fread, fwrite +from native import isinstance as _isinstance, fclose, fflush, fopen, fread, fwrite class filestream: @@ -46,6 +46,12 @@ else: return bytes + def flush(self): + + "Flush the stream." + + fflush(self.__data__) + def read(self, n=0): "Read 'n' bytes from the stream." @@ -66,7 +72,7 @@ try: while True: - l.append(fread(self.__data__, self.bufsize)) + self._read_data(l) # Handle end-of-file reads. @@ -97,18 +103,10 @@ l = [] # Read until end-of-line or end-of-file. - # NOTE: Only POSIX newlines are supported currently. try: - while True: - s = fread(self.__data__, 1) - l.append(s) - - # Where a newline has been read, provide the preceding data - # plus the newline indicator. - - if s == "\n": - break + while not self._read_until_newline(l): + pass # Handle end-of-file reads. @@ -119,6 +117,22 @@ return self._convert(s) + def _read_data(self, l): + + "Read data into 'l'." + + l.append(fread(self.__data__, self.bufsize)) + + def _read_until_newline(self, l): + + "Read data into 'l', returning whether a newline has been read." + + # NOTE: Only POSIX newlines are supported currently. + + s = fread(self.__data__, 1) + l.append(s) + return s == "\n" + def readlines(self, n=None): pass def write(self, s): @@ -154,5 +168,43 @@ get_using(filestream.__init__, self)(encoding, bufsize) self.__data__ = fopen(filename, mode) + self.buffered = "" + + def _get_data(self): + + "Get data from the file." + + if self.buffered: + s = self.buffered + self.buffered = "" + else: + s = fread(self.__data__, self.bufsize) + + return s + + def _read_data(self, l): + + "Read data into 'l'." + + s = self._get_data() + l.append(s) + + def _read_until_newline(self, l): + + "Read data into 'l', returning whether a newline has been read." + + s = self._get_data() + + # NOTE: Only POSIX newlines are supported currently. + + i = s.find("\n") + + if i != -1: + l.append(s[:i+1]) + self.buffered = s[i+1:] + return True + + l.append(s) + return False # vim: tabstop=4 expandtab shiftwidth=4 diff -r 06c4fdc8da56 -r 28e2996df412 lib/__builtins__/io.py --- a/lib/__builtins__/io.py Sat Jan 07 16:23:25 2017 +0100 +++ b/lib/__builtins__/io.py Sun Jan 08 00:27:02 2017 +0100 @@ -32,6 +32,7 @@ if prompt: stdout.write(prompt) + stdout.flush() return lstdin.readline() diff -r 06c4fdc8da56 -r 28e2996df412 lib/native/__init__.py --- a/lib/native/__init__.py Sat Jan 07 16:23:25 2017 +0100 +++ b/lib/native/__init__.py Sun Jan 08 00:27:02 2017 +0100 @@ -31,7 +31,7 @@ from native.iconv import iconv, iconv_close, iconv_open, iconv_reset -from native.io import fclose, fopen, fdopen, close, read, write, fread, fwrite +from native.io import fclose, fflush, fopen, fdopen, close, read, write, fread, fwrite from native.limits import get_maxint, get_minint diff -r 06c4fdc8da56 -r 28e2996df412 lib/native/io.py --- a/lib/native/io.py Sat Jan 07 16:23:25 2017 +0100 +++ b/lib/native/io.py Sun Jan 08 00:27:02 2017 +0100 @@ -25,6 +25,7 @@ """ def fclose(fp): IOError +def fflush(fp): IOError def fopen(filename, mode): IOError def fdopen(fd, mode): IOError def close(fd): IOError diff -r 06c4fdc8da56 -r 28e2996df412 templates/native/io.c --- a/templates/native/io.c Sat Jan 07 16:23:25 2017 +0100 +++ b/templates/native/io.c Sun Jan 08 00:27:02 2017 +0100 @@ -44,6 +44,19 @@ return __builtins___none_None; } +__attr __fn_native_io_fflush(__attr __args[]) +{ + __attr * const fp = &__args[1]; + /* fp interpreted as FILE reference */ + FILE *f = (FILE *) fp->datavalue; + + errno = 0; + if (fflush(f)) + __raise_io_error(__new_int(errno)); + + return __builtins___none_None; +} + __attr __fn_native_io_fopen(__attr __args[]) { __attr * const filename = &__args[1]; diff -r 06c4fdc8da56 -r 28e2996df412 templates/native/io.h --- a/templates/native/io.h Sat Jan 07 16:23:25 2017 +0100 +++ b/templates/native/io.h Sun Jan 08 00:27:02 2017 +0100 @@ -24,6 +24,7 @@ /* Input/output. */ __attr __fn_native_io_fclose(__attr __args[]); +__attr __fn_native_io_fflush(__attr __args[]); __attr __fn_native_io_fopen(__attr __args[]); __attr __fn_native_io_fdopen(__attr __args[]); __attr __fn_native_io_fread(__attr __args[]); diff -r 06c4fdc8da56 -r 28e2996df412 tests/read_file.py --- a/tests/read_file.py Sat Jan 07 16:23:25 2017 +0100 +++ b/tests/read_file.py Sun Jan 08 00:27:02 2017 +0100 @@ -9,6 +9,8 @@ print s # try: s = f.read(49) print s # f = open("tests/read_file.py") # this file! + s = f.readline() + print s # except IOError, exc: s = f.read() print s finally: