private var file: nullable NativeFile = null
# The status of a file. see POSIX stat(2).
- fun file_stat: NativeFileStat do return _file.file_stat
+ #
+ # var f = new FileReader.open("/etc/issue")
+ # assert f.file_stat.is_file
+ #
+ # Return null in case of error
+ fun file_stat: nullable FileStat
+ do
+ var stat = _file.file_stat
+ if stat.address_is_null then return null
+ return new FileStat(stat)
+ end
# File descriptor of this file
fun fd: Int do return _file.fileno
+ redef fun close
+ do
+ if _file == null then return
+ if _file.address_is_null then
+ if last_error != null then return
+ last_error = new IOError("Cannot close unopened file")
+ return
+ end
+ var i = _file.io_close
+ if i != 0 then
+ last_error = new IOError("Close failed due to error {sys.errno.strerror}")
+ end
+ _file = null
+ end
+
# Sets the buffering mode for the current FileStream
#
# If the buf_size is <= 0, its value will be 512 by default
# Open the same file again.
# The original path is reused, therefore the reopened file can be a different file.
+ #
+ # var f = new FileReader.open("/etc/issue")
+ # var l = f.read_line
+ # f.reopen
+ # assert l == f.read_line
fun reopen
do
if not eof and not _file.address_is_null then close
redef fun close
do
- if _file == null or _file.address_is_null then return
- var i = _file.io_close
+ super
_buffer.clear
end_reached = true
- _file = null
end
redef fun fill_buffer
redef var end_reached: Bool = false
# Open the file at `path` for reading.
+ #
+ # var f = new FileReader.open("/etc/issue")
+ # assert not f.end_reached
+ # f.close
+ #
+ # In case of error, `last_error` is set
+ #
+ # f = new FileReader.open("/fail/does not/exist")
+ # assert f.end_reached
+ # assert f.last_error != null
init open(path: String)
do
self.path = path
end
end
+ # Creates a new File stream from a file descriptor
+ #
+ # This is a low-level method.
init from_fd(fd: Int) do
self.path = ""
prepare_buffer(1)
else
for i in s.substrings do write_native(i.to_cstring, i.length)
end
- _file.flush
end
redef fun close
do
- if _file == null then return
- if _file.address_is_null then
- if last_error != null then return
- last_error = new IOError("Cannot close unopened write stream")
- _is_writable = false
- return
- end
- var i = _file.io_close
- if i != 0 then
- last_error = new IOError("Close failed due to error {sys.errno.strerror}")
- end
+ super
_is_writable = false
- _file = null
end
redef var is_writable = false
###############################################################################
# Standard input stream.
+#
+# The class of the default value of `sys.stdin`.
class Stdin
super FileReader
end
# Standard output stream.
+#
+# The class of the default value of `sys.stdout`.
class Stdout
super FileWriter
init do
end
# Standard error stream.
+#
+# The class of the default value of `sys.stderr`.
class Stderr
super FileWriter
init do
#
# Returns `null` if there is no file at `self`.
#
+ # assert "/etc/".to_path.stat.is_dir
+ # assert "/etc/issue".to_path.stat.is_file
+ # assert "/fail/does not/exist".to_path.stat == null
+ #
# ~~~
# var p = "/tmp/".to_path
# var stat = p.stat
end
# Delete a file from the file system, return `true` on success
- #
- # Require: `exists`
fun delete: Bool do return path.to_cstring.file_delete
# Copy content of file at `path` to `dest`
return stat.atime
end
+ # Returns the last access time
+ #
+ # alias for `last_access_time`
+ fun atime: Int do return last_access_time
+
# Returns the last modification time in seconds since Epoch
fun last_modification_time: Int
do
return stat.mtime
end
+ # Returns the last modification time
+ #
+ # alias for `last_modification_time`
+ fun mtime: Int do return last_modification_time
+
+
# Size of the file at `path`
fun size: Int
do
return stat.size
end
- # Is this a regular file and not a device file, pipe, socket, etc.?
+ # Is self a regular file and not a device file, pipe, socket, etc.?
fun is_file: Bool
do
assert not finalized
return stat.is_reg
end
+ # Alias for `is_file`
+ fun is_reg: Bool do return is_file
+
# Is this a directory?
fun is_dir: Bool
do
return stat.ctime
end
+ # Returns the last status change time
+ #
+ # alias for `last_status_change_time`
+ fun ctime: Int do return last_status_change_time
+
# Returns the permission bits of file
fun mode: Int
do
fun file_exists: Bool do return to_cstring.file_exists
# The status of a file. see POSIX stat(2).
- fun file_stat: NativeFileStat do return to_cstring.file_stat
+ fun file_stat: nullable FileStat
+ do
+ var stat = to_cstring.file_stat
+ if stat.address_is_null then return null
+ return new FileStat(stat)
+ end
# The status of a file or of a symlink. see POSIX lstat(2).
- fun file_lstat: NativeFileStat do return to_cstring.file_lstat
+ fun file_lstat: nullable FileStat
+ do
+ var stat = to_cstring.file_lstat
+ if stat.address_is_null then return null
+ return new FileStat(stat)
+ end
# Remove a file, return true if success
fun file_delete: Bool do return to_cstring.file_delete
end
# Simplify a file path by remove useless ".", removing "//", and resolving ".."
- # ".." are not resolved if they start the path
- # starting "/" is not removed
- # trainling "/" is removed
#
- # Note that the method only wonrk on the string:
+ # * ".." are not resolved if they start the path
+ # * starting "/" is not removed
+ # * trailing "/" is removed
+ #
+ # Note that the method only work on the string:
#
# * no I/O access is performed
# * the validity of the path is not checked
# Using a standard "{self}/{path}" does not work in the following cases:
#
# * `self` is empty.
- # * `path` ends with `'/'`.
# * `path` starts with `'/'`.
#
# This method ensures that the join is valid.
end
end
- # returns files contained within the directory represented by self
+ # Returns entries contained within the directory represented by self.
+ #
+ # var files = "/etc".files
+ # assert files.has("issue")
+ #
+ # Returns an empty array in case of error
+ #
+ # files = "/etc/issue".files
+ # assert files.is_empty
+ #
+ # TODO find a better way to handle errors and to give them back to the user.
fun files: Array[String] is extern import Array[String], Array[String].add, NativeString.to_s, String.to_cstring `{
char *dir_path;
DIR *dir;
dir_path = String_to_cstring( recv );
if ((dir = opendir(dir_path)) == NULL)
{
- perror( dir_path );
- exit( 1 );
+ //perror( dir_path );
+ //exit( 1 );
+ Array_of_String results;
+ results = new_Array_of_String();
+ return results;
}
else
{
end
# This class is system dependent ... must reify the vfs
-extern class NativeFileStat `{ struct stat * `}
+private extern class NativeFileStat `{ struct stat * `}
# Returns the permission bits of file
fun mode: Int is extern "file_FileStat_FileStat_mode_0"
# Returns the last access time
redef class Sys
# Standard input
- var stdin: PollableReader = new Stdin is protected writable
+ var stdin: PollableReader = new Stdin is protected writable, lazy
# Standard output
- var stdout: Writer = new Stdout is protected writable
+ var stdout: Writer = new Stdout is protected writable, lazy
# Standard output for errors
- var stderr: Writer = new Stderr is protected writable
+ var stderr: Writer = new Stderr is protected writable, lazy
# Enumeration for buffer mode full (flushes when buffer is full)
fun buffer_mode_full: Int is extern "file_Sys_Sys_buffer_mode_full_0"
end
# Print `objects` on the standard output (`stdout`).
-protected fun printn(objects: Object...)
+fun printn(objects: Object...)
do
sys.stdout.write(objects.to_s)
end
# Print an `object` on the standard output (`stdout`) and add a newline.
-protected fun print(object: Object)
+fun print(object: Object)
do
sys.stdout.write(object.to_s)
sys.stdout.write("\n")
end
# Read a character from the standard input (`stdin`).
-protected fun getc: Char
+fun getc: Char
do
return sys.stdin.read_char.ascii
end
# Read a line from the standard input (`stdin`).
-protected fun gets: String
+fun gets: String
do
return sys.stdin.read_line
end
# Return the working (current) directory
-protected fun getcwd: String do return file_getcwd.to_s
+fun getcwd: String do return file_getcwd.to_s
private fun file_getcwd: NativeString is extern "string_NativeString_NativeString_file_getcwd_0"