mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* re.c (rb_reg_s_union, Init_Regexp): new method `Regexp.union'.
* lib/pathname.rb (realpath): examine Dir.pwd because it may have symlinks. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4856 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
8bf300f149
commit
a5c350aaba
3 changed files with 122 additions and 34 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Wed Oct 29 17:27:05 2003 Tanaka Akira <akr@m17n.org>
|
||||||
|
|
||||||
|
* re.c (rb_reg_s_union, Init_Regexp): new method `Regexp.union'.
|
||||||
|
|
||||||
|
* lib/pathname.rb (realpath): examine Dir.pwd because it may have
|
||||||
|
symlinks.
|
||||||
|
|
||||||
Wed Oct 29 17:16:31 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Wed Oct 29 17:16:31 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* eval.c (rb_longjmp): must not disturb original jump.
|
* eval.c (rb_longjmp): must not disturb original jump.
|
||||||
|
|
|
@ -105,27 +105,29 @@ class Pathname
|
||||||
Pathname.new(path)
|
Pathname.new(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
# realpath returns real pathname of self in actual filesystem.
|
# realpath returns a real pathname of self in actual filesystem.
|
||||||
|
# The real pathname doesn't contain a symlink and useless dots.
|
||||||
#
|
#
|
||||||
# If false is given for the optional argument force_absolute,
|
# If false is given for the optional argument force_absolute,
|
||||||
# it may return relative pathname.
|
# it may return relative pathname.
|
||||||
# Otherwise it returns absolute pathname.
|
# Otherwise it returns absolute pathname.
|
||||||
def realpath(force_absolute=true)
|
def realpath(force_absolute=true)
|
||||||
# Check file existence at first by File.stat.
|
if %r{\A/} =~ @path
|
||||||
# This test detects ELOOP.
|
top = '/'
|
||||||
#
|
unresolved = @path.scan(%r{[^/]+})
|
||||||
# /tmp/a -> a
|
elsif force_absolute
|
||||||
# /tmp/b -> b/b
|
# Although POSIX getcwd returns a pathname which contains no symlink,
|
||||||
# /tmp/c -> ./c
|
# 4.4BSD-Lite2 derived getcwd may return the environment variable $PWD
|
||||||
# /tmp/d -> ../tmp/d
|
# which may contain a symlink.
|
||||||
|
# So the return value of Dir.pwd should be examined.
|
||||||
File.stat(@path)
|
top = '/'
|
||||||
|
unresolved = Dir.pwd.scan(%r{[^/]+}) + @path.scan(%r{[^/]+})
|
||||||
top = %r{\A/} =~ @path ? '/' : ''
|
else
|
||||||
unresolved = @path.scan(%r{[^/]+})
|
top = ''
|
||||||
|
unresolved = @path.scan(%r{[^/]+})
|
||||||
|
end
|
||||||
resolved = []
|
resolved = []
|
||||||
checked_path = {}
|
|
||||||
|
|
||||||
until unresolved.empty?
|
until unresolved.empty?
|
||||||
case unresolved.last
|
case unresolved.last
|
||||||
when '.'
|
when '.'
|
||||||
|
@ -133,34 +135,36 @@ class Pathname
|
||||||
when '..'
|
when '..'
|
||||||
resolved.unshift unresolved.pop
|
resolved.unshift unresolved.pop
|
||||||
else
|
else
|
||||||
path = top + unresolved.join('/')
|
loop_check = {}
|
||||||
raise Errno::ELOOP.new(path) if checked_path[path]
|
while (stat = File.lstat(path = top + unresolved.join('/'))).symlink?
|
||||||
checked_path[path] = true
|
symlink_id = "#{stat.dev}:#{stat.ino}"
|
||||||
if File.lstat(path).symlink?
|
raise Errno::ELOOP.new(path) if loop_check[symlink_id]
|
||||||
link = File.readlink(path)
|
loop_check[symlink_id] = true
|
||||||
if %r{\A/} =~ link
|
if %r{\A/} =~ (link = File.readlink(path))
|
||||||
top = '/'
|
top = '/'
|
||||||
unresolved = link.scan(%r{[^/]+})
|
unresolved = link.scan(%r{[^/]+})
|
||||||
else
|
else
|
||||||
unresolved.pop
|
unresolved[-1,1] = link.scan(%r{[^/]+})
|
||||||
unresolved.concat link.scan(%r{[^/]+})
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
next if (filename = unresolved.pop) == '.'
|
||||||
|
if filename != '..' && resolved.first == '..'
|
||||||
|
resolved.shift
|
||||||
else
|
else
|
||||||
resolved.unshift unresolved.pop
|
resolved.unshift filename
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if resolved.empty?
|
if top == '/'
|
||||||
path = top.empty? ? '.' : top
|
resolved.shift while resolved[0] == '..'
|
||||||
else
|
|
||||||
path = top + resolved.join('/')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Note that Dir.pwd has no symlinks.
|
if resolved.empty?
|
||||||
path = File.join(Dir.pwd, path) if %r{\A/} !~ path && force_absolute
|
Pathname.new(top.empty? ? '.' : '/')
|
||||||
|
else
|
||||||
Pathname.new(path).cleanpath
|
Pathname.new(top + resolved.join('/'))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# parent method returns parent directory, i.e. ".." is joined at last.
|
# parent method returns parent directory, i.e. ".." is joined at last.
|
||||||
|
@ -297,7 +301,7 @@ end
|
||||||
# IO
|
# IO
|
||||||
class Pathname
|
class Pathname
|
||||||
# Pathname#each_line iterates over lines of the file.
|
# Pathname#each_line iterates over lines of the file.
|
||||||
# It's yields String objects for each line.
|
# It's yields a String object for each line.
|
||||||
#
|
#
|
||||||
# This method is exist since 1.8.1.
|
# This method is exist since 1.8.1.
|
||||||
def each_line(*args, &block) IO.foreach(@path, *args, &block) end
|
def each_line(*args, &block) IO.foreach(@path, *args, &block) end
|
||||||
|
|
77
re.c
77
re.c
|
@ -1484,6 +1484,82 @@ rb_reg_options(re)
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_reg_s_union(argc, argv)
|
||||||
|
int argc;
|
||||||
|
VALUE *argv;
|
||||||
|
{
|
||||||
|
if (argc == 0) {
|
||||||
|
VALUE args[1];
|
||||||
|
args[0] = rb_str_new2("(?!)");
|
||||||
|
return rb_class_new_instance(1, args, rb_cRegexp);
|
||||||
|
}
|
||||||
|
else if (argc == 1) {
|
||||||
|
VALUE v;
|
||||||
|
v = rb_check_convert_type(argv[0], T_REGEXP, "Regexp", "to_regexp");
|
||||||
|
if (!NIL_P(v))
|
||||||
|
return v;
|
||||||
|
else {
|
||||||
|
VALUE args[1];
|
||||||
|
args[0] = rb_reg_s_quote(argc, argv);
|
||||||
|
return rb_class_new_instance(1, args, rb_cRegexp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i, kcode = -1;
|
||||||
|
VALUE kcode_re = Qnil;
|
||||||
|
VALUE source = rb_str_buf_new(0);
|
||||||
|
VALUE args[3];
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
volatile VALUE v;
|
||||||
|
if (0 < i)
|
||||||
|
rb_str_buf_cat2(source, "|");
|
||||||
|
v = rb_check_convert_type(argv[i], T_REGEXP, "Regexp", "to_regexp");
|
||||||
|
if (!NIL_P(v)) {
|
||||||
|
if (FL_TEST(v, KCODE_FIXED)) {
|
||||||
|
if (kcode == -1) {
|
||||||
|
kcode_re = v;
|
||||||
|
kcode = RBASIC(v)->flags & KCODE_MASK;
|
||||||
|
}
|
||||||
|
else if ((RBASIC(v)->flags & KCODE_MASK) != kcode) {
|
||||||
|
volatile VALUE str1, str2;
|
||||||
|
str1 = rb_inspect(kcode_re);
|
||||||
|
str2 = rb_inspect(v);
|
||||||
|
rb_raise(rb_eArgError, "mixed kcode: %s and %s",
|
||||||
|
RSTRING(str1)->ptr, RSTRING(str2)->ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v = rb_reg_to_s(v);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
args[0] = argv[i];
|
||||||
|
v = rb_reg_s_quote(1, args);
|
||||||
|
}
|
||||||
|
rb_str_buf_append(source, v);
|
||||||
|
}
|
||||||
|
args[0] = source;
|
||||||
|
args[1] = Qnil;
|
||||||
|
switch (kcode) {
|
||||||
|
case -1:
|
||||||
|
args[2] = Qnil;
|
||||||
|
break;
|
||||||
|
case KCODE_NONE:
|
||||||
|
args[2] = rb_str_new2("n");
|
||||||
|
break;
|
||||||
|
case KCODE_EUC:
|
||||||
|
args[2] = rb_str_new2("e");
|
||||||
|
break;
|
||||||
|
case KCODE_SJIS:
|
||||||
|
args[2] = rb_str_new2("s");
|
||||||
|
break;
|
||||||
|
case KCODE_UTF8:
|
||||||
|
args[2] = rb_str_new2("u");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return rb_class_new_instance(3, args, rb_cRegexp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_reg_init_copy(copy, re)
|
rb_reg_init_copy(copy, re)
|
||||||
VALUE copy, re;
|
VALUE copy, re;
|
||||||
|
@ -1732,6 +1808,7 @@ Init_Regexp()
|
||||||
rb_define_singleton_method(rb_cRegexp, "compile", rb_class_new_instance, -1);
|
rb_define_singleton_method(rb_cRegexp, "compile", rb_class_new_instance, -1);
|
||||||
rb_define_singleton_method(rb_cRegexp, "quote", rb_reg_s_quote, -1);
|
rb_define_singleton_method(rb_cRegexp, "quote", rb_reg_s_quote, -1);
|
||||||
rb_define_singleton_method(rb_cRegexp, "escape", rb_reg_s_quote, -1);
|
rb_define_singleton_method(rb_cRegexp, "escape", rb_reg_s_quote, -1);
|
||||||
|
rb_define_singleton_method(rb_cRegexp, "union", rb_reg_s_union, -1);
|
||||||
rb_define_singleton_method(rb_cRegexp, "last_match", rb_reg_s_last_match, -1);
|
rb_define_singleton_method(rb_cRegexp, "last_match", rb_reg_s_last_match, -1);
|
||||||
|
|
||||||
rb_define_method(rb_cRegexp, "initialize", rb_reg_initialize_m, -1);
|
rb_define_method(rb_cRegexp, "initialize", rb_reg_initialize_m, -1);
|
||||||
|
|
Loading…
Reference in a new issue