summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-io/mrblib/file.rb
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-io/mrblib/file.rb')
-rw-r--r--mrbgems/mruby-io/mrblib/file.rb208
1 files changed, 208 insertions, 0 deletions
diff --git a/mrbgems/mruby-io/mrblib/file.rb b/mrbgems/mruby-io/mrblib/file.rb
new file mode 100644
index 000000000..514efc1c6
--- /dev/null
+++ b/mrbgems/mruby-io/mrblib/file.rb
@@ -0,0 +1,208 @@
+class File < IO
+ class FileError < Exception; end
+ class NoFileError < FileError; end
+ class UnableToStat < FileError; end
+ class PermissionError < FileError; end
+
+ attr_accessor :path
+
+ def initialize(fd_or_path, mode = "r", perm = 0666)
+ if fd_or_path.kind_of? Fixnum
+ super(fd_or_path, mode)
+ else
+ @path = fd_or_path
+ fd = IO.sysopen(@path, mode, perm)
+ super(fd, mode)
+ end
+ 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.expand_path(path, default_dir = '.')
+ def 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
+
+ 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)
+ return '' if fname[0] == '.' || fname.index('.').nil?
+ ext = fname.split('.').last
+ ext.empty? ? '' : ".#{ext}"
+ end
+
+ def self.path(filename)
+ if filename.kind_of?(String)
+ filename
+ elsif filename.respond_to?(:to_path)
+ filename.to_path
+ else
+ raise TypeError, "no implicit conversion of #{filename.class} into String"
+ end
+ end
+end