mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
221 lines
4.7 KiB
Ruby
221 lines
4.7 KiB
Ruby
class File < IO
|
|
attr_accessor :path
|
|
|
|
def initialize(fd_or_path, mode = "r", perm = 0666)
|
|
if fd_or_path.kind_of? Integer
|
|
super(fd_or_path, mode)
|
|
else
|
|
@path = fd_or_path
|
|
fd = IO.sysopen(@path, mode, perm)
|
|
super(fd, mode)
|
|
end
|
|
end
|
|
|
|
def atime
|
|
t = self._atime
|
|
t && Time.at(t)
|
|
end
|
|
|
|
def ctime
|
|
t = self._ctime
|
|
t && Time.at(t)
|
|
end
|
|
|
|
def mtime
|
|
t = self._mtime
|
|
t && Time.at(t)
|
|
end
|
|
|
|
def inspect
|
|
"<#{self.class}:#{@path}>"
|
|
end
|
|
|
|
def self.join(*names)
|
|
return "" if names.empty?
|
|
|
|
names.map! do |name|
|
|
case name
|
|
when String
|
|
name
|
|
when Array
|
|
if names == name
|
|
raise ArgumentError, "recursive array"
|
|
end
|
|
join(*name)
|
|
else
|
|
raise TypeError, "no implicit conversion of #{name.class} into String"
|
|
end
|
|
end
|
|
|
|
return names[0] if names.size == 1
|
|
|
|
if names[0][-1] == File::SEPARATOR
|
|
s = names[0][0..-2]
|
|
else
|
|
s = names[0].dup
|
|
end
|
|
|
|
(1..names.size-2).each { |i|
|
|
t = names[i]
|
|
if t[0] == File::SEPARATOR and t[-1] == File::SEPARATOR
|
|
t = t[1..-2]
|
|
elsif t[0] == File::SEPARATOR
|
|
t = t[1..-1]
|
|
elsif t[-1] == File::SEPARATOR
|
|
t = t[0..-2]
|
|
end
|
|
s += File::SEPARATOR + t if t != ""
|
|
}
|
|
if names[-1][0] == File::SEPARATOR
|
|
s += File::SEPARATOR + names[-1][1..-1]
|
|
else
|
|
s += File::SEPARATOR + names[-1]
|
|
end
|
|
s
|
|
end
|
|
|
|
def self._concat_path(path, base_path)
|
|
if path[0] == "/" || path[1] == ':' # Windows root!
|
|
expanded_path = path
|
|
elsif path[0] == "~"
|
|
if (path[1] == "/" || path[1] == nil)
|
|
dir = path[1, path.size]
|
|
home_dir = _gethome
|
|
|
|
unless home_dir
|
|
raise ArgumentError, "couldn't find HOME environment -- expanding '~'"
|
|
end
|
|
|
|
expanded_path = home_dir
|
|
expanded_path += dir if dir
|
|
expanded_path += "/"
|
|
else
|
|
splitted_path = path.split("/")
|
|
user = splitted_path[0][1, splitted_path[0].size]
|
|
dir = "/" + splitted_path[1, splitted_path.size].join("/")
|
|
|
|
home_dir = _gethome(user)
|
|
|
|
unless home_dir
|
|
raise ArgumentError, "user #{user} doesn't exist"
|
|
end
|
|
|
|
expanded_path = home_dir
|
|
expanded_path += dir if dir
|
|
expanded_path += "/"
|
|
end
|
|
else
|
|
expanded_path = _concat_path(base_path, _getwd)
|
|
expanded_path += "/" + path
|
|
end
|
|
|
|
expanded_path
|
|
end
|
|
|
|
def self.expand_path(path, default_dir = '.')
|
|
expanded_path = _concat_path(path, default_dir)
|
|
drive_prefix = ""
|
|
if File::ALT_SEPARATOR && expanded_path.size > 2 &&
|
|
("A".."Z").include?(expanded_path[0].upcase) && expanded_path[1] == ":"
|
|
drive_prefix = expanded_path[0, 2]
|
|
expanded_path = expanded_path[2, expanded_path.size]
|
|
end
|
|
expand_path_array = []
|
|
if File::ALT_SEPARATOR && expanded_path.include?(File::ALT_SEPARATOR)
|
|
expanded_path.gsub!(File::ALT_SEPARATOR, '/')
|
|
end
|
|
while expanded_path.include?('//')
|
|
expanded_path = expanded_path.gsub('//', '/')
|
|
end
|
|
|
|
if expanded_path != "/"
|
|
expanded_path.split('/').each do |path_token|
|
|
if path_token == '..'
|
|
if expand_path_array.size > 1
|
|
expand_path_array.pop
|
|
end
|
|
elsif path_token == '.'
|
|
# nothing to do.
|
|
else
|
|
expand_path_array << path_token
|
|
end
|
|
end
|
|
|
|
expanded_path = expand_path_array.join("/")
|
|
if expanded_path.empty?
|
|
expanded_path = '/'
|
|
end
|
|
end
|
|
if drive_prefix.empty?
|
|
expanded_path
|
|
else
|
|
drive_prefix + expanded_path.gsub("/", File::ALT_SEPARATOR)
|
|
end
|
|
end
|
|
|
|
def self.foreach(file)
|
|
if block_given?
|
|
self.open(file) do |f|
|
|
f.each {|l| yield l}
|
|
end
|
|
else
|
|
return self.new(file)
|
|
end
|
|
end
|
|
|
|
def self.directory?(file)
|
|
FileTest.directory?(file)
|
|
end
|
|
|
|
def self.exist?(file)
|
|
FileTest.exist?(file)
|
|
end
|
|
|
|
def self.exists?(file)
|
|
FileTest.exists?(file)
|
|
end
|
|
|
|
def self.file?(file)
|
|
FileTest.file?(file)
|
|
end
|
|
|
|
def self.pipe?(file)
|
|
FileTest.pipe?(file)
|
|
end
|
|
|
|
def self.size(file)
|
|
FileTest.size(file)
|
|
end
|
|
|
|
def self.size?(file)
|
|
FileTest.size?(file)
|
|
end
|
|
|
|
def self.socket?(file)
|
|
FileTest.socket?(file)
|
|
end
|
|
|
|
def self.symlink?(file)
|
|
FileTest.symlink?(file)
|
|
end
|
|
|
|
def self.zero?(file)
|
|
FileTest.zero?(file)
|
|
end
|
|
|
|
def self.extname(filename)
|
|
fname = self.basename(filename)
|
|
epos = fname.rindex('.')
|
|
return '' if epos == 0 || epos.nil?
|
|
return fname[epos..-1]
|
|
end
|
|
|
|
def self.path(filename)
|
|
if filename.kind_of?(String)
|
|
filename
|
|
else
|
|
raise TypeError, "no implicit conversion of #{filename.class} into String"
|
|
end
|
|
end
|
|
end
|