1.1 --- a/lib/__builtins__/file.py Sat Jan 07 16:23:25 2017 +0100
1.2 +++ b/lib/__builtins__/file.py Sun Jan 08 00:27:02 2017 +0100
1.3 @@ -20,7 +20,7 @@
1.4 """
1.5
1.6 from __builtins__.types import check_int, check_string
1.7 -from native import isinstance as _isinstance, fclose, fopen, fread, fwrite
1.8 +from native import isinstance as _isinstance, fclose, fflush, fopen, fread, fwrite
1.9
1.10 class filestream:
1.11
1.12 @@ -46,6 +46,12 @@
1.13 else:
1.14 return bytes
1.15
1.16 + def flush(self):
1.17 +
1.18 + "Flush the stream."
1.19 +
1.20 + fflush(self.__data__)
1.21 +
1.22 def read(self, n=0):
1.23
1.24 "Read 'n' bytes from the stream."
1.25 @@ -66,7 +72,7 @@
1.26
1.27 try:
1.28 while True:
1.29 - l.append(fread(self.__data__, self.bufsize))
1.30 + self._read_data(l)
1.31
1.32 # Handle end-of-file reads.
1.33
1.34 @@ -97,18 +103,10 @@
1.35 l = []
1.36
1.37 # Read until end-of-line or end-of-file.
1.38 - # NOTE: Only POSIX newlines are supported currently.
1.39
1.40 try:
1.41 - while True:
1.42 - s = fread(self.__data__, 1)
1.43 - l.append(s)
1.44 -
1.45 - # Where a newline has been read, provide the preceding data
1.46 - # plus the newline indicator.
1.47 -
1.48 - if s == "\n":
1.49 - break
1.50 + while not self._read_until_newline(l):
1.51 + pass
1.52
1.53 # Handle end-of-file reads.
1.54
1.55 @@ -119,6 +117,22 @@
1.56
1.57 return self._convert(s)
1.58
1.59 + def _read_data(self, l):
1.60 +
1.61 + "Read data into 'l'."
1.62 +
1.63 + l.append(fread(self.__data__, self.bufsize))
1.64 +
1.65 + def _read_until_newline(self, l):
1.66 +
1.67 + "Read data into 'l', returning whether a newline has been read."
1.68 +
1.69 + # NOTE: Only POSIX newlines are supported currently.
1.70 +
1.71 + s = fread(self.__data__, 1)
1.72 + l.append(s)
1.73 + return s == "\n"
1.74 +
1.75 def readlines(self, n=None): pass
1.76
1.77 def write(self, s):
1.78 @@ -154,5 +168,43 @@
1.79
1.80 get_using(filestream.__init__, self)(encoding, bufsize)
1.81 self.__data__ = fopen(filename, mode)
1.82 + self.buffered = ""
1.83 +
1.84 + def _get_data(self):
1.85 +
1.86 + "Get data from the file."
1.87 +
1.88 + if self.buffered:
1.89 + s = self.buffered
1.90 + self.buffered = ""
1.91 + else:
1.92 + s = fread(self.__data__, self.bufsize)
1.93 +
1.94 + return s
1.95 +
1.96 + def _read_data(self, l):
1.97 +
1.98 + "Read data into 'l'."
1.99 +
1.100 + s = self._get_data()
1.101 + l.append(s)
1.102 +
1.103 + def _read_until_newline(self, l):
1.104 +
1.105 + "Read data into 'l', returning whether a newline has been read."
1.106 +
1.107 + s = self._get_data()
1.108 +
1.109 + # NOTE: Only POSIX newlines are supported currently.
1.110 +
1.111 + i = s.find("\n")
1.112 +
1.113 + if i != -1:
1.114 + l.append(s[:i+1])
1.115 + self.buffered = s[i+1:]
1.116 + return True
1.117 +
1.118 + l.append(s)
1.119 + return False
1.120
1.121 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/lib/__builtins__/io.py Sat Jan 07 16:23:25 2017 +0100
2.2 +++ b/lib/__builtins__/io.py Sun Jan 08 00:27:02 2017 +0100
2.3 @@ -32,6 +32,7 @@
2.4
2.5 if prompt:
2.6 stdout.write(prompt)
2.7 + stdout.flush()
2.8
2.9 return lstdin.readline()
2.10
3.1 --- a/lib/native/__init__.py Sat Jan 07 16:23:25 2017 +0100
3.2 +++ b/lib/native/__init__.py Sun Jan 08 00:27:02 2017 +0100
3.3 @@ -31,7 +31,7 @@
3.4
3.5 from native.iconv import iconv, iconv_close, iconv_open, iconv_reset
3.6
3.7 -from native.io import fclose, fopen, fdopen, close, read, write, fread, fwrite
3.8 +from native.io import fclose, fflush, fopen, fdopen, close, read, write, fread, fwrite
3.9
3.10 from native.limits import get_maxint, get_minint
3.11
4.1 --- a/lib/native/io.py Sat Jan 07 16:23:25 2017 +0100
4.2 +++ b/lib/native/io.py Sun Jan 08 00:27:02 2017 +0100
4.3 @@ -25,6 +25,7 @@
4.4 """
4.5
4.6 def fclose(fp): IOError
4.7 +def fflush(fp): IOError
4.8 def fopen(filename, mode): IOError
4.9 def fdopen(fd, mode): IOError
4.10 def close(fd): IOError
5.1 --- a/templates/native/io.c Sat Jan 07 16:23:25 2017 +0100
5.2 +++ b/templates/native/io.c Sun Jan 08 00:27:02 2017 +0100
5.3 @@ -44,6 +44,19 @@
5.4 return __builtins___none_None;
5.5 }
5.6
5.7 +__attr __fn_native_io_fflush(__attr __args[])
5.8 +{
5.9 + __attr * const fp = &__args[1];
5.10 + /* fp interpreted as FILE reference */
5.11 + FILE *f = (FILE *) fp->datavalue;
5.12 +
5.13 + errno = 0;
5.14 + if (fflush(f))
5.15 + __raise_io_error(__new_int(errno));
5.16 +
5.17 + return __builtins___none_None;
5.18 +}
5.19 +
5.20 __attr __fn_native_io_fopen(__attr __args[])
5.21 {
5.22 __attr * const filename = &__args[1];
6.1 --- a/templates/native/io.h Sat Jan 07 16:23:25 2017 +0100
6.2 +++ b/templates/native/io.h Sun Jan 08 00:27:02 2017 +0100
6.3 @@ -24,6 +24,7 @@
6.4 /* Input/output. */
6.5
6.6 __attr __fn_native_io_fclose(__attr __args[]);
6.7 +__attr __fn_native_io_fflush(__attr __args[]);
6.8 __attr __fn_native_io_fopen(__attr __args[]);
6.9 __attr __fn_native_io_fdopen(__attr __args[]);
6.10 __attr __fn_native_io_fread(__attr __args[]);
7.1 --- a/tests/read_file.py Sat Jan 07 16:23:25 2017 +0100
7.2 +++ b/tests/read_file.py Sun Jan 08 00:27:02 2017 +0100
7.3 @@ -9,6 +9,8 @@
7.4 print s # try:
7.5 s = f.read(49)
7.6 print s # f = open("tests/read_file.py") # this file!
7.7 + s = f.readline()
7.8 + print s # except IOError, exc:
7.9 s = f.read()
7.10 print s
7.11 finally: