# another product.
# File manipulations (create, read, write, etc.)
-package file
+module file
intrude import stream
intrude import string
do
return stdin.read_line
end
+
+ # Return the working (current) directory
+ protected fun getcwd: String do return file_getcwd.to_s
+ private fun file_getcwd: NativeString is extern "string_NativeString_NativeString_file_getcwd_0"
end
# File Abstract Stream
end
# Extract the dirname of a path
+ #
+ # assert "/path/to/a_file.ext".dirname == "/path/to"
+ # assert "path/to/a_file.ext".dirname == "path/to"
+ # assert "path/to".dirname == "path"
+ # assert "path/to/".dirname == "path"
+ # assert "path".dirname == "."
+ # assert "/path".dirname == "/"
+ # assert "/".dirname == "/"
+ # assert "".dirname == "."
fun dirname: String
do
- var pos = last_index_of_from('/', _length - 1)
- if pos >= 0 then
+ var l = _length - 1 # Index of the last char
+ if l > 0 and self[l] == '/' then l -= 1 # remove trailing `/`
+ var pos = last_index_of_from('/', l)
+ if pos > 0 then
return substring(0, pos)
+ else if pos == 0 then
+ return "/"
else
return "."
end
end
+ # Return the canonicalized absolute pathname (see POSIX function `realpath`)
+ fun realpath: String do
+ var cs = to_cstring.file_realpath
+ var res = cs.to_s_with_copy
+ # cs.free_malloc # FIXME memory leak
+ return res
+ end
+
# Simplify a file path by remove useless ".", removing "//", and resolving ".."
# ".." are not resolved if they start the path
# starting "/" is not removed
# * the validity of the path is not checked
#
# assert "some/./complex/../../path/from/../to/a////file//".simplify_path == "path/to/a/file"
- # assert "../dir/file".simplify_path == "../dir/file"
- # assert "dir/../../".simplify_path == ".."
- # assert "//absolute//path/".simplify_path == "/absolute/path"
+ # assert "../dir/file".simplify_path == "../dir/file"
+ # assert "dir/../../".simplify_path == ".."
+ # assert "dir/..".simplify_path == "."
+ # assert "//absolute//path/".simplify_path == "/absolute/path"
fun simplify_path: String
do
var a = self.split_with("/")
end
a2.push(x)
end
+ if a2.is_empty then return "."
return a2.join("/")
end
end
end
+ # Change the current working directory
+ #
+ # "/etc".chdir
+ # assert getcwd == "/etc"
+ # "..".chdir
+ # assert getcwd == "/"
+ #
+ # TODO: errno
+ fun chdir do to_cstring.file_chdir
+
# Return right-most extension (without the dot)
fun file_extension : nullable String
do
`}
private fun file_mkdir: Bool is extern "string_NativeString_NativeString_file_mkdir_0"
private fun file_delete: Bool is extern "string_NativeString_NativeString_file_delete_0"
+ private fun file_chdir is extern "string_NativeString_NativeString_file_chdir_0"
+ private fun file_realpath: NativeString is extern "file_NativeString_realpath"
end
extern FileStat `{ struct stat * `}