# HG changeset patch # User Paul Boddie # Date 1486071667 -3600 # Node ID d6a50fe5b3adfde0469eb4499d3d15b77e788505 # Parent ca18c51ae153be86f80f97c5333709a74dc6cf15 Moved C library functionality into a separate package, adjusting built-in object dependencies and making the POSIX functionality more specific (and less likely to be included by many programs). diff -r ca18c51ae153 -r d6a50fe5b3ad lib/__builtins__/file.py --- a/lib/__builtins__/file.py Thu Feb 02 22:38:26 2017 +0100 +++ b/lib/__builtins__/file.py Thu Feb 02 22:41:07 2017 +0100 @@ -3,7 +3,7 @@ """ File objects. -Copyright (C) 2015, 2016 Paul Boddie +Copyright (C) 2015, 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -19,141 +19,8 @@ this program. If not, see . """ -from __builtins__.types import check_int, check_string -from native import isinstance as _isinstance, fclose, fflush, fopen, fread, fwrite - -class filestream: - - "Generic file-oriented stream functionality." - - def __init__(self, encoding=None, bufsize=1024): - - "Initialise the stream with the given 'encoding' and 'bufsize'." - - self.encoding = encoding - self.bufsize = bufsize - - # Internal stream details. - - self.__data__ = None - - def _convert(self, bytes): - - "Convert 'bytes' to text if necessary." - - if self.encoding: - return unicode(bytes, self.encoding) - else: - return bytes - - def flush(self): - - "Flush the stream." - - fflush(self.__data__) - - def read(self, n=0): - - "Read 'n' bytes from the stream." - - check_int(n) - - # Read any indicated number of bytes. - - if n > 0: - s = fread(self.__data__, n) - - # Read all remaining bytes. - - else: - l = [] - - # Read until end-of-file. - - try: - while True: - self._read_data(l) - - # Handle end-of-file reads. - - except EOFError: - pass - - s = "".join(l) - - return self._convert(s) - - def readline(self, n=0): - - """ - Read until an end-of-line indicator is encountered or at most 'n' bytes, - if indicated. - """ - - check_int(n) - - # Read any indicated number of bytes. - - if n > 0: - s = fread(self.__data__, n) - - # Read until an end-of-line indicator. - - else: - l = [] - - # Read until end-of-line or end-of-file. - - try: - while not self._read_until_newline(l): - pass - - # Handle end-of-file reads. - - except EOFError: - pass - - s = "".join(l) - - 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): - - "Write string 's' to the stream." - - check_string(s) - - # Encode text as bytes if necessary. When the encoding is not set, any - # original encoding of the text will be applied. - - if _isinstance(s, utf8string): - s = s.encode(self.encoding) - - fwrite(self.__data__, s) - - def close(self): - - "Close the stream." - - fclose(self.__data__) +from __builtins__.stream import filestream +from native import fopen, fread class file(filestream): diff -r ca18c51ae153 -r d6a50fe5b3ad lib/__builtins__/stream.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/__builtins__/stream.py Thu Feb 02 22:41:07 2017 +0100 @@ -0,0 +1,158 @@ +#!/usr/bin/env python + +""" +Stream objects. + +Copyright (C) 2015, 2016, 2017 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +from __builtins__.types import check_int, check_string +from native import isinstance as _isinstance, fclose, fflush, fread, fwrite + +class filestream: + + "Generic file-oriented stream functionality." + + def __init__(self, encoding=None, bufsize=1024): + + "Initialise the stream with the given 'encoding' and 'bufsize'." + + self.encoding = encoding + self.bufsize = bufsize + + # Internal stream details. + + self.__data__ = None + + def _convert(self, bytes): + + "Convert 'bytes' to text if necessary." + + if self.encoding: + return unicode(bytes, self.encoding) + else: + return bytes + + def flush(self): + + "Flush the stream." + + fflush(self.__data__) + + def read(self, n=0): + + "Read 'n' bytes from the stream." + + check_int(n) + + # Read any indicated number of bytes. + + if n > 0: + s = fread(self.__data__, n) + + # Read all remaining bytes. + + else: + l = [] + + # Read until end-of-file. + + try: + while True: + self._read_data(l) + + # Handle end-of-file reads. + + except EOFError: + pass + + s = "".join(l) + + return self._convert(s) + + def readline(self, n=0): + + """ + Read until an end-of-line indicator is encountered or at most 'n' bytes, + if indicated. + """ + + check_int(n) + + # Read any indicated number of bytes. + + if n > 0: + s = fread(self.__data__, n) + + # Read until an end-of-line indicator. + + else: + l = [] + + # Read until end-of-line or end-of-file. + + try: + while not self._read_until_newline(l): + pass + + # Handle end-of-file reads. + + except EOFError: + pass + + s = "".join(l) + + 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): + + "Write string 's' to the stream." + + check_string(s) + + # Encode text as bytes if necessary. When the encoding is not set, any + # original encoding of the text will be applied. + + if _isinstance(s, utf8string): + s = s.encode(self.encoding) + + fwrite(self.__data__, s) + + def close(self): + + "Close the stream." + + fclose(self.__data__) + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r ca18c51ae153 -r d6a50fe5b3ad lib/libc/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/libc/__init__.py Thu Feb 02 22:41:07 2017 +0100 @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +"C library support package." + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r ca18c51ae153 -r d6a50fe5b3ad lib/libc/io.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/libc/io.py Thu Feb 02 22:41:07 2017 +0100 @@ -0,0 +1,129 @@ +#!/usr/bin/env python + +""" +C library input/output. + +Copyright (C) 2016, 2017 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +from __builtins__.stream import filestream +from __builtins__.types import check_int, check_string + +import locale + +from native import ( + close as _close, + fdopen as _fdopen, + read as _read, + write as _write + ) + +# Abstractions for system-level files and streams. + +class sysfile: + + "A system-level file object." + + def __init__(self, fd): + + "Initialise the file with the given 'fd'." + + self.fd = fd + + def read(self, n): + + "Read 'n' bytes from the file, returning a string." + + return read(self.fd, n) + + def write(self, s): + + "Write string 's' to the file." + + return write(self.fd, s) + + def close(self): + + "Close the file." + + close(self.fd) + +class sysstream(filestream): + + "A system-level stream object." + + def __init__(self, fd, mode="r", encoding=None, bufsize=1024): + + """ + Initialise the stream with the given 'fd', 'mode', 'encoding' and + 'bufsize'. + """ + + check_int(fd) + check_string(mode) + + get_using(filestream.__init__, self)(encoding, bufsize) + self.__data__ = _fdopen(fd, mode) + +# Standard streams. + +stdin = sysstream(0) +stdout = sysstream(1, "w") +stderr = sysstream(2, "w") + +# Localised streams. +# Perform locale initialisation explicitly to ensure that the locale module +# and various function defaults have been initialised. + +locale.initlocale() +lstdin = sysstream(0, "r", locale.getpreferredencoding()) + +# Input/output functions. + +def close(fd): + + "Close the file descriptor 'fd'." + + _close(fd) + +def fdopen(fd, mode="r"): + + """ + Open a stream for the given file descriptor 'fd', operating in the given + 'mode'. + """ + + return sysstream(fd, mode) + +def read(fd, n): + + """ + Read using the low-level file descriptor 'fd' the given number of bytes 'n'. + """ + + check_int(fd) + check_int(n) + return _read(fd, n) + +def write(fd, s): + + "Write using the low-level file descriptor 'fd' the given string 's'." + + check_int(fd) + check_string(s) + return _write(fd, s) + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r ca18c51ae153 -r d6a50fe5b3ad lib/posix/io.py --- a/lib/posix/io.py Thu Feb 02 22:38:26 2017 +0100 +++ b/lib/posix/io.py Thu Feb 02 22:41:07 2017 +0100 @@ -19,85 +19,7 @@ this program. If not, see . """ -from __builtins__.file import filestream -from __builtins__.types import check_int, check_string - -from native import ( - close as _close, - fdopen as _fdopen, - read as _read, - write as _write - ) - -import locale - -# Abstractions for system-level files and streams. - -class sysfile: - - "A system-level file object." - - def __init__(self, fd): - - "Initialise the file with the given 'fd'." - - self.fd = fd - - def read(self, n): - - "Read 'n' bytes from the file, returning a string." - - return read(self.fd, n) - - def write(self, s): - - "Write string 's' to the file." - - return write(self.fd, s) - - def close(self): - - "Close the file." - - close(self.fd) - -class sysstream(filestream): - - "A system-level stream object." - - def __init__(self, fd, mode="r", encoding=None, bufsize=1024): - - """ - Initialise the stream with the given 'fd', 'mode', 'encoding' and - 'bufsize'. - """ - - check_int(fd) - check_string(mode) - - get_using(filestream.__init__, self)(encoding, bufsize) - self.__data__ = _fdopen(fd, mode) - -# Standard streams. - -stdin = sysstream(0) -stdout = sysstream(1, "w") -stderr = sysstream(2, "w") - -# Localised streams. -# Perform locale initialisation explicitly to ensure that the locale module -# and various function defaults have been initialised. - -locale.initlocale() -lstdin = sysstream(0, "r", locale.getpreferredencoding()) - -# Input/output functions. - -def close(fd): - - "Close the file descriptor 'fd'." - - _close(fd) +from libc.io import close, fdopen, read, write def closerange(fd_low, fd_high): pass def dup(fd): pass @@ -106,16 +28,6 @@ def fchmod(fd, mode): pass def fchown(fd, uid, gid): pass def fdatasync(fd): pass - -def fdopen(fd, mode="r"): - - """ - Open a stream for the given file descriptor 'fd', operating in the given - 'mode'. - """ - - return sysstream(fd, mode) - def fpathconf(fd, name): pass def fstat(fd): pass def fstatvfs(fd): pass @@ -132,31 +44,12 @@ def openpty(): pass def pipe(): pass def putenv(key, value): pass - -def read(fd, n): - - """ - Read using the low-level file descriptor 'fd' the given number of bytes 'n'. - """ - - check_int(fd) - check_int(n) - return _read(fd, n) - def times(): pass def ttyname(fd): pass def umask(new_mask): pass def uname(): pass def unsetenv(key): pass -def write(fd, s): - - "Write using the low-level file descriptor 'fd' the given string 's'." - - check_int(fd) - check_string(s) - return _write(fd, s) - # Constants. O_APPEND = 1024 diff -r ca18c51ae153 -r d6a50fe5b3ad lib/sys.py --- a/lib/sys.py Thu Feb 02 22:38:26 2017 +0100 +++ b/lib/sys.py Thu Feb 02 22:41:07 2017 +0100 @@ -3,7 +3,7 @@ """ System functions and objects. -Copyright (C) 2008, 2012, 2014, 2016 Paul Boddie +Copyright (C) 2008, 2012, 2014, 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -20,7 +20,7 @@ """ from __builtins__.int import maxint, minint -from posix.io import lstdin, stdin, stdout, stderr +from libc.io import lstdin, stdin, stdout, stderr from native import ( exit as _exit,