* lib: Convert tabs to spaces for ruby files per
http://redmine.ruby-lang.org/projects/ruby/wiki/DeveloperHowto#coding-style Patch by Steve Klabnik [Ruby 1.9 - Bug #4730] Patch by Jason Dew [Ruby 1.9 - Feature #4718] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31635 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
34276148c4
commit
7bbf2f3085
@ -1,3 +1,10 @@
|
|||||||
|
Thu May 19 06:16:41 2011 Eric Hodel <drbrain@segment7.net>
|
||||||
|
|
||||||
|
* lib: Convert tabs to spaces for ruby files per
|
||||||
|
http://redmine.ruby-lang.org/projects/ruby/wiki/DeveloperHowto#coding-style
|
||||||
|
Patch by Steve Klabnik [Ruby 1.9 - Bug #4730]
|
||||||
|
Patch by Jason Dew [Ruby 1.9 - Feature #4718]
|
||||||
|
|
||||||
Thu May 19 06:06:07 2011 Eric Hodel <drbrain@segment7.net>
|
Thu May 19 06:06:07 2011 Eric Hodel <drbrain@segment7.net>
|
||||||
|
|
||||||
* lib/cgi/util.rb: Improve documentation. Patch by Clinton Nixon.
|
* lib/cgi/util.rb: Improve documentation. Patch by Clinton Nixon.
|
||||||
|
@ -45,24 +45,24 @@ module Abbrev
|
|||||||
seen = Hash.new(0)
|
seen = Hash.new(0)
|
||||||
|
|
||||||
if pattern.is_a?(String)
|
if pattern.is_a?(String)
|
||||||
pattern = /^#{Regexp.quote(pattern)}/ # regard as a prefix
|
pattern = /^#{Regexp.quote(pattern)}/ # regard as a prefix
|
||||||
end
|
end
|
||||||
|
|
||||||
words.each do |word|
|
words.each do |word|
|
||||||
next if (abbrev = word).empty?
|
next if (abbrev = word).empty?
|
||||||
while (len = abbrev.rindex(/[\w\W]\z/)) > 0
|
while (len = abbrev.rindex(/[\w\W]\z/)) > 0
|
||||||
abbrev = word[0,len]
|
abbrev = word[0,len]
|
||||||
|
|
||||||
next if pattern && pattern !~ abbrev
|
next if pattern && pattern !~ abbrev
|
||||||
|
|
||||||
case seen[abbrev] += 1
|
case seen[abbrev] += 1
|
||||||
when 1
|
when 1
|
||||||
table[abbrev] = word
|
table[abbrev] = word
|
||||||
when 2
|
when 2
|
||||||
table.delete(abbrev)
|
table.delete(abbrev)
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -254,9 +254,9 @@ module Benchmark
|
|||||||
puts 'Rehearsal '.ljust(width+CAPTION.length,'-')
|
puts 'Rehearsal '.ljust(width+CAPTION.length,'-')
|
||||||
ets = job.list.inject(Tms.new) { |sum,(label,item)|
|
ets = job.list.inject(Tms.new) { |sum,(label,item)|
|
||||||
print label.ljust(width)
|
print label.ljust(width)
|
||||||
res = Benchmark.measure(&item)
|
res = Benchmark.measure(&item)
|
||||||
print res.format
|
print res.format
|
||||||
sum + res
|
sum + res
|
||||||
}.format("total: %tsec")
|
}.format("total: %tsec")
|
||||||
print " #{ets}\n\n".rjust(width+CAPTION.length+2,'-')
|
print " #{ets}\n\n".rjust(width+CAPTION.length+2,'-')
|
||||||
|
|
||||||
@ -520,14 +520,14 @@ module Benchmark
|
|||||||
cutime.__send__(op, x.cutime),
|
cutime.__send__(op, x.cutime),
|
||||||
cstime.__send__(op, x.cstime),
|
cstime.__send__(op, x.cstime),
|
||||||
real.__send__(op, x.real)
|
real.__send__(op, x.real)
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
Benchmark::Tms.new(utime.__send__(op, x),
|
Benchmark::Tms.new(utime.__send__(op, x),
|
||||||
stime.__send__(op, x),
|
stime.__send__(op, x),
|
||||||
cutime.__send__(op, x),
|
cutime.__send__(op, x),
|
||||||
cstime.__send__(op, x),
|
cstime.__send__(op, x),
|
||||||
real.__send__(op, x)
|
real.__send__(op, x)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -548,13 +548,13 @@ if __FILE__ == $0
|
|||||||
x.report("for:") {for _ in 1..n; _ = "1"; end} # Benchmark.measure
|
x.report("for:") {for _ in 1..n; _ = "1"; end} # Benchmark.measure
|
||||||
x.report("times:") {n.times do ; _ = "1"; end}
|
x.report("times:") {n.times do ; _ = "1"; end}
|
||||||
x.report("upto:") {1.upto(n) do ; _ = "1"; end}
|
x.report("upto:") {1.upto(n) do ; _ = "1"; end}
|
||||||
end
|
end
|
||||||
|
|
||||||
benchmark do
|
benchmark do
|
||||||
[
|
[
|
||||||
measure{for _ in 1..n; _ = "1"; end}, # Benchmark.measure
|
measure{for _ in 1..n; _ = "1"; end}, # Benchmark.measure
|
||||||
measure{n.times do ; _ = "1"; end},
|
measure{n.times do ; _ = "1"; end},
|
||||||
measure{1.upto(n) do ; _ = "1"; end}
|
measure{1.upto(n) do ; _ = "1"; end}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
26
lib/cmath.rb
26
lib/cmath.rb
@ -55,7 +55,7 @@ module CMath
|
|||||||
else
|
else
|
||||||
ere = exp!(z.real)
|
ere = exp!(z.real)
|
||||||
Complex(ere * cos!(z.imag),
|
Complex(ere * cos!(z.imag),
|
||||||
ere * sin!(z.imag))
|
ere * sin!(z.imag))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ module CMath
|
|||||||
else
|
else
|
||||||
a = Complex(log!(z.abs), z.arg)
|
a = Complex(log!(z.abs), z.arg)
|
||||||
if b
|
if b
|
||||||
a /= log(b)
|
a /= log(b)
|
||||||
end
|
end
|
||||||
a
|
a
|
||||||
end
|
end
|
||||||
@ -105,18 +105,18 @@ module CMath
|
|||||||
def sqrt(z)
|
def sqrt(z)
|
||||||
if z.real?
|
if z.real?
|
||||||
if z < 0
|
if z < 0
|
||||||
Complex(0, sqrt!(-z))
|
Complex(0, sqrt!(-z))
|
||||||
else
|
else
|
||||||
sqrt!(z)
|
sqrt!(z)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if z.imag < 0 ||
|
if z.imag < 0 ||
|
||||||
(z.imag == 0 && z.imag.to_s[0] == '-')
|
(z.imag == 0 && z.imag.to_s[0] == '-')
|
||||||
sqrt(z.conjugate).conjugate
|
sqrt(z.conjugate).conjugate
|
||||||
else
|
else
|
||||||
r = z.abs
|
r = z.abs
|
||||||
x = z.real
|
x = z.real
|
||||||
Complex(sqrt!((r + x) / 2.0), sqrt!((r - x) / 2.0))
|
Complex(sqrt!((r + x) / 2.0), sqrt!((r - x) / 2.0))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -138,7 +138,7 @@ module CMath
|
|||||||
sin!(z)
|
sin!(z)
|
||||||
else
|
else
|
||||||
Complex(sin!(z.real) * cosh!(z.imag),
|
Complex(sin!(z.real) * cosh!(z.imag),
|
||||||
cos!(z.real) * sinh!(z.imag))
|
cos!(z.real) * sinh!(z.imag))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ module CMath
|
|||||||
cos!(z)
|
cos!(z)
|
||||||
else
|
else
|
||||||
Complex(cos!(z.real) * cosh!(z.imag),
|
Complex(cos!(z.real) * cosh!(z.imag),
|
||||||
-sin!(z.real) * sinh!(z.imag))
|
-sin!(z.real) * sinh!(z.imag))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ module CMath
|
|||||||
sinh!(z)
|
sinh!(z)
|
||||||
else
|
else
|
||||||
Complex(sinh!(z.real) * cos!(z.imag),
|
Complex(sinh!(z.real) * cos!(z.imag),
|
||||||
cosh!(z.real) * sin!(z.imag))
|
cosh!(z.real) * sin!(z.imag))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ module CMath
|
|||||||
cosh!(z)
|
cosh!(z)
|
||||||
else
|
else
|
||||||
Complex(cosh!(z.real) * cos!(z.imag),
|
Complex(cosh!(z.real) * cos!(z.imag),
|
||||||
sinh!(z.real) * sin!(z.imag))
|
sinh!(z.real) * sin!(z.imag))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
984
lib/debug.rb
984
lib/debug.rb
File diff suppressed because it is too large
Load Diff
@ -330,12 +330,12 @@ end
|
|||||||
# :stopdoc:
|
# :stopdoc:
|
||||||
def Delegator.delegating_block(mid)
|
def Delegator.delegating_block(mid)
|
||||||
lambda do |*args, &block|
|
lambda do |*args, &block|
|
||||||
target = self.__getobj__
|
target = self.__getobj__
|
||||||
begin
|
begin
|
||||||
target.__send__(mid, *args, &block)
|
target.__send__(mid, *args, &block)
|
||||||
ensure
|
ensure
|
||||||
$@.delete_if {|t| /\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:/o =~ t} if $@
|
$@.delete_if {|t| /\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:/o =~ t} if $@
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# :startdoc:
|
# :startdoc:
|
||||||
@ -368,10 +368,10 @@ def DelegateClass(superclass)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
klass.define_singleton_method :public_instance_methods do |all=true|
|
klass.define_singleton_method :public_instance_methods do |all=true|
|
||||||
super(all) - superclass.protected_instance_methods
|
super(all) - superclass.protected_instance_methods
|
||||||
end
|
end
|
||||||
klass.define_singleton_method :protected_instance_methods do |all=true|
|
klass.define_singleton_method :protected_instance_methods do |all=true|
|
||||||
super(all) | superclass.protected_instance_methods
|
super(all) | superclass.protected_instance_methods
|
||||||
end
|
end
|
||||||
return klass
|
return klass
|
||||||
end
|
end
|
||||||
@ -405,7 +405,7 @@ if __FILE__ == $0
|
|||||||
foo2 = SimpleDelegator.new(foo)
|
foo2 = SimpleDelegator.new(foo)
|
||||||
p foo2
|
p foo2
|
||||||
foo2.instance_eval{print "foo\n"}
|
foo2.instance_eval{print "foo\n"}
|
||||||
p foo.test == foo2.test # => true
|
p foo.test == foo2.test # => true
|
||||||
p foo2.iter{[55,true]} # => true
|
p foo2.iter{[55,true]} # => true
|
||||||
foo2.error # raise error!
|
foo2.error # raise error!
|
||||||
end
|
end
|
||||||
|
@ -51,15 +51,15 @@ class ACL
|
|||||||
|
|
||||||
def initialize(str)
|
def initialize(str)
|
||||||
if str == '*' or str == 'all'
|
if str == '*' or str == 'all'
|
||||||
@pat = [:all]
|
@pat = [:all]
|
||||||
elsif str.include?('*')
|
elsif str.include?('*')
|
||||||
@pat = [:name, dot_pat(str)]
|
@pat = [:name, dot_pat(str)]
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@pat = [:ip, IPAddr.new(str)]
|
@pat = [:ip, IPAddr.new(str)]
|
||||||
rescue ArgumentError
|
rescue ArgumentError
|
||||||
@pat = [:name, dot_pat(str)]
|
@pat = [:name, dot_pat(str)]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ class ACL
|
|||||||
|
|
||||||
def dot_pat_str(str)
|
def dot_pat_str(str)
|
||||||
list = str.split('.').collect { |s|
|
list = str.split('.').collect { |s|
|
||||||
(s == '*') ? '.+' : s
|
(s == '*') ? '.+' : s
|
||||||
}
|
}
|
||||||
list.join("\\.")
|
list.join("\\.")
|
||||||
end
|
end
|
||||||
@ -93,19 +93,19 @@ class ACL
|
|||||||
def match(addr)
|
def match(addr)
|
||||||
case @pat[0]
|
case @pat[0]
|
||||||
when :all
|
when :all
|
||||||
true
|
true
|
||||||
when :ip
|
when :ip
|
||||||
begin
|
begin
|
||||||
ipaddr = IPAddr.new(addr[3])
|
ipaddr = IPAddr.new(addr[3])
|
||||||
ipaddr = ipaddr.ipv4_mapped if @pat[1].ipv6? && ipaddr.ipv4?
|
ipaddr = ipaddr.ipv4_mapped if @pat[1].ipv6? && ipaddr.ipv4?
|
||||||
rescue ArgumentError
|
rescue ArgumentError
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
(@pat[1].include?(ipaddr)) ? true : false
|
(@pat[1].include?(ipaddr)) ? true : false
|
||||||
when :name
|
when :name
|
||||||
(@pat[1] =~ addr[2]) ? true : false
|
(@pat[1] =~ addr[2]) ? true : false
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -130,7 +130,7 @@ class ACL
|
|||||||
|
|
||||||
def match(addr)
|
def match(addr)
|
||||||
@list.each do |e|
|
@list.each do |e|
|
||||||
return true if e.match(addr)
|
return true if e.match(addr)
|
||||||
end
|
end
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
@ -219,11 +219,11 @@ class ACL
|
|||||||
permission, domain = list.slice(i,2)
|
permission, domain = list.slice(i,2)
|
||||||
case permission.downcase
|
case permission.downcase
|
||||||
when 'allow'
|
when 'allow'
|
||||||
@allow.add(domain)
|
@allow.add(domain)
|
||||||
when 'deny'
|
when 'deny'
|
||||||
@deny.add(domain)
|
@deny.add(domain)
|
||||||
else
|
else
|
||||||
raise "Invalid ACL entry #{list.to_s}"
|
raise "Invalid ACL entry #{list.to_s}"
|
||||||
end
|
end
|
||||||
i += 2
|
i += 2
|
||||||
end
|
end
|
||||||
@ -234,17 +234,17 @@ end
|
|||||||
if __FILE__ == $0
|
if __FILE__ == $0
|
||||||
# example
|
# example
|
||||||
list = %w(deny all
|
list = %w(deny all
|
||||||
allow 192.168.1.1
|
allow 192.168.1.1
|
||||||
allow ::ffff:192.168.1.2
|
allow ::ffff:192.168.1.2
|
||||||
allow 192.168.1.3
|
allow 192.168.1.3
|
||||||
)
|
)
|
||||||
|
|
||||||
addr = ["AF_INET", 10, "lc630", "192.168.1.3"]
|
addr = ["AF_INET", 10, "lc630", "192.168.1.3"]
|
||||||
|
|
||||||
acl = ACL.new
|
acl = ACL.new
|
||||||
p acl.allow_addr?(addr)
|
p acl.allow_addr?(addr)
|
||||||
|
|
||||||
acl = ACL.new(list, ACL::DENY_ALLOW)
|
acl = ACL.new(list, ACL::DENY_ALLOW)
|
||||||
p acl.allow_addr?(addr)
|
p acl.allow_addr?(addr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
332
lib/drb/drb.rb
332
lib/drb/drb.rb
@ -466,11 +466,11 @@ module DRb
|
|||||||
def initialize(err, buf)
|
def initialize(err, buf)
|
||||||
case err.to_s
|
case err.to_s
|
||||||
when /uninitialized constant (\S+)/
|
when /uninitialized constant (\S+)/
|
||||||
@name = $1
|
@name = $1
|
||||||
when /undefined class\/module (\S+)/
|
when /undefined class\/module (\S+)/
|
||||||
@name = $1
|
@name = $1
|
||||||
else
|
else
|
||||||
@name = nil
|
@name = nil
|
||||||
end
|
end
|
||||||
@buf = buf
|
@buf = buf
|
||||||
end
|
end
|
||||||
@ -486,9 +486,9 @@ module DRb
|
|||||||
|
|
||||||
def self._load(s) # :nodoc:
|
def self._load(s) # :nodoc:
|
||||||
begin
|
begin
|
||||||
Marshal::load(s)
|
Marshal::load(s)
|
||||||
rescue NameError, ArgumentError
|
rescue NameError, ArgumentError
|
||||||
DRbUnknown.new($!, s)
|
DRbUnknown.new($!, s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -514,16 +514,16 @@ module DRb
|
|||||||
class DRbArray
|
class DRbArray
|
||||||
def initialize(ary)
|
def initialize(ary)
|
||||||
@ary = ary.collect { |obj|
|
@ary = ary.collect { |obj|
|
||||||
if obj.kind_of? DRbUndumped
|
if obj.kind_of? DRbUndumped
|
||||||
DRbObject.new(obj)
|
DRbObject.new(obj)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
Marshal.dump(obj)
|
Marshal.dump(obj)
|
||||||
obj
|
obj
|
||||||
rescue
|
rescue
|
||||||
DRbObject.new(obj)
|
DRbObject.new(obj)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -554,16 +554,16 @@ module DRb
|
|||||||
def dump(obj, error=false) # :nodoc:
|
def dump(obj, error=false) # :nodoc:
|
||||||
obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped
|
obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped
|
||||||
begin
|
begin
|
||||||
str = Marshal::dump(obj)
|
str = Marshal::dump(obj)
|
||||||
rescue
|
rescue
|
||||||
str = Marshal::dump(make_proxy(obj, error))
|
str = Marshal::dump(make_proxy(obj, error))
|
||||||
end
|
end
|
||||||
[str.size].pack('N') + str
|
[str.size].pack('N') + str
|
||||||
end
|
end
|
||||||
|
|
||||||
def load(soc) # :nodoc:
|
def load(soc) # :nodoc:
|
||||||
begin
|
begin
|
||||||
sz = soc.read(4) # sizeof (N)
|
sz = soc.read(4) # sizeof (N)
|
||||||
rescue
|
rescue
|
||||||
raise(DRbConnError, $!.message, $!.backtrace)
|
raise(DRbConnError, $!.message, $!.backtrace)
|
||||||
end
|
end
|
||||||
@ -600,7 +600,7 @@ module DRb
|
|||||||
ary.push(dump(msg_id.id2name))
|
ary.push(dump(msg_id.id2name))
|
||||||
ary.push(dump(arg.length))
|
ary.push(dump(arg.length))
|
||||||
arg.each do |e|
|
arg.each do |e|
|
||||||
ary.push(dump(e))
|
ary.push(dump(e))
|
||||||
end
|
end
|
||||||
ary.push(dump(b))
|
ary.push(dump(b))
|
||||||
stream.write(ary.join(''))
|
stream.write(ary.join(''))
|
||||||
@ -616,7 +616,7 @@ module DRb
|
|||||||
raise(DRbConnError, "too many arguments") if @argc_limit < argc
|
raise(DRbConnError, "too many arguments") if @argc_limit < argc
|
||||||
argv = Array.new(argc, nil)
|
argv = Array.new(argc, nil)
|
||||||
argc.times do |n|
|
argc.times do |n|
|
||||||
argv[n] = load(stream)
|
argv[n] = load(stream)
|
||||||
end
|
end
|
||||||
block = load(stream)
|
block = load(stream)
|
||||||
return ro, msg, argv, block
|
return ro, msg, argv, block
|
||||||
@ -727,18 +727,18 @@ module DRb
|
|||||||
# URI, but an error occurs in opening it, a DRbConnError is raised.
|
# URI, but an error occurs in opening it, a DRbConnError is raised.
|
||||||
def open(uri, config, first=true)
|
def open(uri, config, first=true)
|
||||||
@protocol.each do |prot|
|
@protocol.each do |prot|
|
||||||
begin
|
begin
|
||||||
return prot.open(uri, config)
|
return prot.open(uri, config)
|
||||||
rescue DRbBadScheme
|
rescue DRbBadScheme
|
||||||
rescue DRbConnError
|
rescue DRbConnError
|
||||||
raise($!)
|
raise($!)
|
||||||
rescue
|
rescue
|
||||||
raise(DRbConnError, "#{uri} - #{$!.inspect}")
|
raise(DRbConnError, "#{uri} - #{$!.inspect}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if first && (config[:auto_load] != false)
|
if first && (config[:auto_load] != false)
|
||||||
auto_load(uri, config)
|
auto_load(uri, config)
|
||||||
return open(uri, config, false)
|
return open(uri, config, false)
|
||||||
end
|
end
|
||||||
raise DRbBadURI, 'can\'t parse uri:' + uri
|
raise DRbBadURI, 'can\'t parse uri:' + uri
|
||||||
end
|
end
|
||||||
@ -755,14 +755,14 @@ module DRb
|
|||||||
# error is passed on to the caller.
|
# error is passed on to the caller.
|
||||||
def open_server(uri, config, first=true)
|
def open_server(uri, config, first=true)
|
||||||
@protocol.each do |prot|
|
@protocol.each do |prot|
|
||||||
begin
|
begin
|
||||||
return prot.open_server(uri, config)
|
return prot.open_server(uri, config)
|
||||||
rescue DRbBadScheme
|
rescue DRbBadScheme
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if first && (config[:auto_load] != false)
|
if first && (config[:auto_load] != false)
|
||||||
auto_load(uri, config)
|
auto_load(uri, config)
|
||||||
return open_server(uri, config, false)
|
return open_server(uri, config, false)
|
||||||
end
|
end
|
||||||
raise DRbBadURI, 'can\'t parse uri:' + uri
|
raise DRbBadURI, 'can\'t parse uri:' + uri
|
||||||
end
|
end
|
||||||
@ -776,15 +776,15 @@ module DRb
|
|||||||
# URI, then a DRbBadURI error is raised.
|
# URI, then a DRbBadURI error is raised.
|
||||||
def uri_option(uri, config, first=true)
|
def uri_option(uri, config, first=true)
|
||||||
@protocol.each do |prot|
|
@protocol.each do |prot|
|
||||||
begin
|
begin
|
||||||
uri, opt = prot.uri_option(uri, config)
|
uri, opt = prot.uri_option(uri, config)
|
||||||
# opt = nil if opt == ''
|
# opt = nil if opt == ''
|
||||||
return uri, opt
|
return uri, opt
|
||||||
rescue DRbBadScheme
|
rescue DRbBadScheme
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if first && (config[:auto_load] != false)
|
if first && (config[:auto_load] != false)
|
||||||
auto_load(uri, config)
|
auto_load(uri, config)
|
||||||
return uri_option(uri, config, false)
|
return uri_option(uri, config, false)
|
||||||
end
|
end
|
||||||
raise DRbBadURI, 'can\'t parse uri:' + uri
|
raise DRbBadURI, 'can\'t parse uri:' + uri
|
||||||
@ -793,7 +793,7 @@ module DRb
|
|||||||
|
|
||||||
def auto_load(uri, config) # :nodoc:
|
def auto_load(uri, config) # :nodoc:
|
||||||
if uri =~ /^drb([a-z0-9]+):/
|
if uri =~ /^drb([a-z0-9]+):/
|
||||||
require("drb/#{$1}") rescue nil
|
require("drb/#{$1}") rescue nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
module_function :auto_load
|
module_function :auto_load
|
||||||
@ -806,13 +806,13 @@ module DRb
|
|||||||
private
|
private
|
||||||
def self.parse_uri(uri)
|
def self.parse_uri(uri)
|
||||||
if uri =~ /^druby:\/\/(.*?):(\d+)(\?(.*))?$/
|
if uri =~ /^druby:\/\/(.*?):(\d+)(\?(.*))?$/
|
||||||
host = $1
|
host = $1
|
||||||
port = $2.to_i
|
port = $2.to_i
|
||||||
option = $4
|
option = $4
|
||||||
[host, port, option]
|
[host, port, option]
|
||||||
else
|
else
|
||||||
raise(DRbBadScheme, uri) unless uri =~ /^druby:/
|
raise(DRbBadScheme, uri) unless uri =~ /^druby:/
|
||||||
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -858,7 +858,7 @@ module DRb
|
|||||||
host = getservername
|
host = getservername
|
||||||
soc = open_server_inaddr_any(host, port)
|
soc = open_server_inaddr_any(host, port)
|
||||||
else
|
else
|
||||||
soc = TCPServer.open(host, port)
|
soc = TCPServer.open(host, port)
|
||||||
end
|
end
|
||||||
port = soc.addr[1] if port == 0
|
port = soc.addr[1] if port == 0
|
||||||
config[:tcp_port] = port
|
config[:tcp_port] = port
|
||||||
@ -928,8 +928,8 @@ module DRb
|
|||||||
# client-server session.
|
# client-server session.
|
||||||
def close
|
def close
|
||||||
if @socket
|
if @socket
|
||||||
@socket.close
|
@socket.close
|
||||||
@socket = nil
|
@socket = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -938,9 +938,9 @@ module DRb
|
|||||||
# the server's side of this client-server session.
|
# the server's side of this client-server session.
|
||||||
def accept
|
def accept
|
||||||
while true
|
while true
|
||||||
s = @socket.accept
|
s = @socket.accept
|
||||||
break if (@acl ? @acl.allow_socket?(s) : true)
|
break if (@acl ? @acl.allow_socket?(s) : true)
|
||||||
s.close
|
s.close
|
||||||
end
|
end
|
||||||
if @config[:tcp_original_host].to_s.size == 0
|
if @config[:tcp_original_host].to_s.size == 0
|
||||||
uri = "druby://#{s.addr[3]}:#{@config[:tcp_port]}"
|
uri = "druby://#{s.addr[3]}:#{@config[:tcp_port]}"
|
||||||
@ -954,8 +954,8 @@ module DRb
|
|||||||
def alive?
|
def alive?
|
||||||
return false unless @socket
|
return false unless @socket
|
||||||
if IO.select([@socket], nil, nil, 0)
|
if IO.select([@socket], nil, nil, 0)
|
||||||
close
|
close
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
@ -1004,7 +1004,7 @@ module DRb
|
|||||||
uri, ref = Marshal.load(s)
|
uri, ref = Marshal.load(s)
|
||||||
|
|
||||||
if DRb.here?(uri)
|
if DRb.here?(uri)
|
||||||
obj = DRb.to_obj(ref)
|
obj = DRb.to_obj(ref)
|
||||||
if ((! obj.tainted?) && Thread.current[:drb_untaint])
|
if ((! obj.tainted?) && Thread.current[:drb_untaint])
|
||||||
Thread.current[:drb_untaint].push(obj)
|
Thread.current[:drb_untaint].push(obj)
|
||||||
end
|
end
|
||||||
@ -1042,12 +1042,12 @@ module DRb
|
|||||||
@uri = nil
|
@uri = nil
|
||||||
@ref = nil
|
@ref = nil
|
||||||
if obj.nil?
|
if obj.nil?
|
||||||
return if uri.nil?
|
return if uri.nil?
|
||||||
@uri, option = DRbProtocol.uri_option(uri, DRb.config)
|
@uri, option = DRbProtocol.uri_option(uri, DRb.config)
|
||||||
@ref = DRbURIOption.new(option) unless option.nil?
|
@ref = DRbURIOption.new(option) unless option.nil?
|
||||||
else
|
else
|
||||||
@uri = uri ? uri : (DRb.uri rescue nil)
|
@uri = uri ? uri : (DRb.uri rescue nil)
|
||||||
@ref = obj ? DRb.to_id(obj) : nil
|
@ref = obj ? DRb.to_id(obj) : nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1078,9 +1078,9 @@ module DRb
|
|||||||
# Routes method calls to the referenced object.
|
# Routes method calls to the referenced object.
|
||||||
def method_missing(msg_id, *a, &b)
|
def method_missing(msg_id, *a, &b)
|
||||||
if DRb.here?(@uri)
|
if DRb.here?(@uri)
|
||||||
obj = DRb.to_obj(@ref)
|
obj = DRb.to_obj(@ref)
|
||||||
DRb.current_server.check_insecure_method(obj, msg_id)
|
DRb.current_server.check_insecure_method(obj, msg_id)
|
||||||
return obj.__send__(msg_id, *a, &b)
|
return obj.__send__(msg_id, *a, &b)
|
||||||
end
|
end
|
||||||
|
|
||||||
succ, result = self.class.with_friend(@uri) do
|
succ, result = self.class.with_friend(@uri) do
|
||||||
@ -1095,7 +1095,7 @@ module DRb
|
|||||||
raise result
|
raise result
|
||||||
else
|
else
|
||||||
bt = self.class.prepare_backtrace(@uri, result)
|
bt = self.class.prepare_backtrace(@uri, result)
|
||||||
result.set_backtrace(bt + caller)
|
result.set_backtrace(bt + caller)
|
||||||
raise result
|
raise result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1117,7 +1117,7 @@ module DRb
|
|||||||
result.backtrace.each do |x|
|
result.backtrace.each do |x|
|
||||||
break if /`__send__'$/ =~ x
|
break if /`__send__'$/ =~ x
|
||||||
if /^\(druby:\/\// =~ x
|
if /^\(druby:\/\// =~ x
|
||||||
bt.push(x)
|
bt.push(x)
|
||||||
else
|
else
|
||||||
bt.push(prefix + x)
|
bt.push(prefix + x)
|
||||||
end
|
end
|
||||||
@ -1153,36 +1153,36 @@ module DRb
|
|||||||
|
|
||||||
def self.open(remote_uri) # :nodoc:
|
def self.open(remote_uri) # :nodoc:
|
||||||
begin
|
begin
|
||||||
conn = nil
|
conn = nil
|
||||||
|
|
||||||
@mutex.synchronize do
|
@mutex.synchronize do
|
||||||
#FIXME
|
#FIXME
|
||||||
new_pool = []
|
new_pool = []
|
||||||
@pool.each do |c|
|
@pool.each do |c|
|
||||||
if conn.nil? and c.uri == remote_uri
|
if conn.nil? and c.uri == remote_uri
|
||||||
conn = c if c.alive?
|
conn = c if c.alive?
|
||||||
else
|
else
|
||||||
new_pool.push c
|
new_pool.push c
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@pool = new_pool
|
@pool = new_pool
|
||||||
end
|
end
|
||||||
|
|
||||||
conn = self.new(remote_uri) unless conn
|
conn = self.new(remote_uri) unless conn
|
||||||
succ, result = yield(conn)
|
succ, result = yield(conn)
|
||||||
return succ, result
|
return succ, result
|
||||||
|
|
||||||
ensure
|
ensure
|
||||||
if conn
|
if conn
|
||||||
if succ
|
if succ
|
||||||
@mutex.synchronize do
|
@mutex.synchronize do
|
||||||
@pool.unshift(conn)
|
@pool.unshift(conn)
|
||||||
@pool.pop.close while @pool.size > POOL_SIZE
|
@pool.pop.close while @pool.size > POOL_SIZE
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
conn.close
|
conn.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1274,11 +1274,11 @@ module DRb
|
|||||||
|
|
||||||
def self.make_config(hash={}) # :nodoc:
|
def self.make_config(hash={}) # :nodoc:
|
||||||
default_config = {
|
default_config = {
|
||||||
:idconv => @@idconv,
|
:idconv => @@idconv,
|
||||||
:verbose => @@verbose,
|
:verbose => @@verbose,
|
||||||
:tcp_acl => @@acl,
|
:tcp_acl => @@acl,
|
||||||
:load_limit => @@load_limit,
|
:load_limit => @@load_limit,
|
||||||
:argc_limit => @@argc_limit,
|
:argc_limit => @@argc_limit,
|
||||||
:safe_level => @@safe_level
|
:safe_level => @@safe_level
|
||||||
}
|
}
|
||||||
default_config.update(hash)
|
default_config.update(hash)
|
||||||
@ -1329,12 +1329,12 @@ module DRb
|
|||||||
# The server will immediately start running in its own thread.
|
# The server will immediately start running in its own thread.
|
||||||
def initialize(uri=nil, front=nil, config_or_acl=nil)
|
def initialize(uri=nil, front=nil, config_or_acl=nil)
|
||||||
if Hash === config_or_acl
|
if Hash === config_or_acl
|
||||||
config = config_or_acl.dup
|
config = config_or_acl.dup
|
||||||
else
|
else
|
||||||
acl = config_or_acl || @@acl
|
acl = config_or_acl || @@acl
|
||||||
config = {
|
config = {
|
||||||
:tcp_acl => acl
|
:tcp_acl => acl
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@config = self.class.make_config(config)
|
@config = self.class.make_config(config)
|
||||||
@ -1414,28 +1414,28 @@ module DRb
|
|||||||
private
|
private
|
||||||
def kill_sub_thread
|
def kill_sub_thread
|
||||||
Thread.new do
|
Thread.new do
|
||||||
grp = ThreadGroup.new
|
grp = ThreadGroup.new
|
||||||
grp.add(Thread.current)
|
grp.add(Thread.current)
|
||||||
list = @grp.list
|
list = @grp.list
|
||||||
while list.size > 0
|
while list.size > 0
|
||||||
list.each do |th|
|
list.each do |th|
|
||||||
th.kill if th.alive?
|
th.kill if th.alive?
|
||||||
end
|
end
|
||||||
list = @grp.list
|
list = @grp.list
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
Thread.start do
|
Thread.start do
|
||||||
begin
|
begin
|
||||||
while true
|
while true
|
||||||
main_loop
|
main_loop
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
@protocol.close if @protocol
|
@protocol.close if @protocol
|
||||||
kill_sub_thread
|
kill_sub_thread
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1473,10 +1473,10 @@ module DRb
|
|||||||
raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id)
|
raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id)
|
||||||
|
|
||||||
if obj.private_methods.include?(msg_id)
|
if obj.private_methods.include?(msg_id)
|
||||||
desc = any_to_s(obj)
|
desc = any_to_s(obj)
|
||||||
raise NoMethodError, "private method `#{msg_id}' called for #{desc}"
|
raise NoMethodError, "private method `#{msg_id}' called for #{desc}"
|
||||||
elsif obj.protected_methods.include?(msg_id)
|
elsif obj.protected_methods.include?(msg_id)
|
||||||
desc = any_to_s(obj)
|
desc = any_to_s(obj)
|
||||||
raise NoMethodError, "protected method `#{msg_id}' called for #{desc}"
|
raise NoMethodError, "protected method `#{msg_id}' called for #{desc}"
|
||||||
else
|
else
|
||||||
true
|
true
|
||||||
@ -1486,15 +1486,15 @@ module DRb
|
|||||||
|
|
||||||
class InvokeMethod # :nodoc:
|
class InvokeMethod # :nodoc:
|
||||||
def initialize(drb_server, client)
|
def initialize(drb_server, client)
|
||||||
@drb_server = drb_server
|
@drb_server = drb_server
|
||||||
@safe_level = drb_server.safe_level
|
@safe_level = drb_server.safe_level
|
||||||
@client = client
|
@client = client
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
@result = nil
|
@result = nil
|
||||||
@succ = false
|
@succ = false
|
||||||
setup_message
|
setup_message
|
||||||
|
|
||||||
if $SAFE < @safe_level
|
if $SAFE < @safe_level
|
||||||
info = Thread.current['DRb']
|
info = Thread.current['DRb']
|
||||||
@ -1518,19 +1518,19 @@ module DRb
|
|||||||
@result = perform_without_block
|
@result = perform_without_block
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@succ = true
|
@succ = true
|
||||||
if @msg_id == :to_ary && @result.class == Array
|
if @msg_id == :to_ary && @result.class == Array
|
||||||
@result = DRbArray.new(@result)
|
@result = DRbArray.new(@result)
|
||||||
end
|
end
|
||||||
return @succ, @result
|
return @succ, @result
|
||||||
rescue StandardError, ScriptError, Interrupt
|
rescue StandardError, ScriptError, Interrupt
|
||||||
@result = $!
|
@result = $!
|
||||||
return @succ, @result
|
return @succ, @result
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def init_with_client
|
def init_with_client
|
||||||
obj, msg, argv, block = @client.recv_request
|
obj, msg, argv, block = @client.recv_request
|
||||||
@obj = obj
|
@obj = obj
|
||||||
@msg_id = msg.intern
|
@msg_id = msg.intern
|
||||||
@argv = argv
|
@argv = argv
|
||||||
@ -1542,21 +1542,21 @@ module DRb
|
|||||||
end
|
end
|
||||||
|
|
||||||
def setup_message
|
def setup_message
|
||||||
init_with_client
|
init_with_client
|
||||||
check_insecure_method
|
check_insecure_method
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform_without_block
|
def perform_without_block
|
||||||
if Proc === @obj && @msg_id == :__drb_yield
|
if Proc === @obj && @msg_id == :__drb_yield
|
||||||
if @argv.size == 1
|
if @argv.size == 1
|
||||||
ary = @argv
|
ary = @argv
|
||||||
else
|
else
|
||||||
ary = [@argv]
|
ary = [@argv]
|
||||||
end
|
end
|
||||||
ary.collect(&@obj)[0]
|
ary.collect(&@obj)[0]
|
||||||
else
|
else
|
||||||
@obj.__send__(@msg_id, *@argv)
|
@obj.__send__(@msg_id, *@argv)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -1582,29 +1582,29 @@ module DRb
|
|||||||
# or a local method call fails.
|
# or a local method call fails.
|
||||||
def main_loop
|
def main_loop
|
||||||
Thread.start(@protocol.accept) do |client|
|
Thread.start(@protocol.accept) do |client|
|
||||||
@grp.add Thread.current
|
@grp.add Thread.current
|
||||||
Thread.current['DRb'] = { 'client' => client ,
|
Thread.current['DRb'] = { 'client' => client ,
|
||||||
'server' => self }
|
'server' => self }
|
||||||
loop do
|
loop do
|
||||||
begin
|
begin
|
||||||
succ = false
|
succ = false
|
||||||
invoke_method = InvokeMethod.new(self, client)
|
invoke_method = InvokeMethod.new(self, client)
|
||||||
succ, result = invoke_method.perform
|
succ, result = invoke_method.perform
|
||||||
if !succ && verbose
|
if !succ && verbose
|
||||||
p result
|
p result
|
||||||
result.backtrace.each do |x|
|
result.backtrace.each do |x|
|
||||||
puts x
|
puts x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
client.send_reply(succ, result) rescue nil
|
client.send_reply(succ, result) rescue nil
|
||||||
ensure
|
ensure
|
||||||
client.close unless succ
|
client.close unless succ
|
||||||
if Thread.current['DRb']['stop_service']
|
if Thread.current['DRb']['stop_service']
|
||||||
Thread.new { stop_service }
|
Thread.new { stop_service }
|
||||||
end
|
end
|
||||||
break unless succ
|
break unless succ
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
=begin
|
=begin
|
||||||
external service
|
external service
|
||||||
Copyright (c) 2000,2002 Masatoshi SEKI
|
Copyright (c) 2000,2002 Masatoshi SEKI
|
||||||
=end
|
=end
|
||||||
|
|
||||||
require 'drb/drb'
|
require 'drb/drb'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
=begin
|
=begin
|
||||||
external service manager
|
external service manager
|
||||||
Copyright (c) 2000 Masatoshi SEKI
|
Copyright (c) 2000 Masatoshi SEKI
|
||||||
=end
|
=end
|
||||||
|
|
||||||
require 'drb/drb'
|
require 'drb/drb'
|
||||||
@ -54,17 +54,17 @@ module DRb
|
|||||||
|
|
||||||
def unregist(name)
|
def unregist(name)
|
||||||
synchronize do
|
synchronize do
|
||||||
@servers.delete(name)
|
@servers.delete(name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def invoke_thread
|
def invoke_thread
|
||||||
Thread.new do
|
Thread.new do
|
||||||
while true
|
while true
|
||||||
name = @queue.pop
|
name = @queue.pop
|
||||||
invoke_service_command(name, @@command[name])
|
invoke_service_command(name, @@command[name])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -75,8 +75,8 @@ module DRb
|
|||||||
def invoke_service_command(name, command)
|
def invoke_service_command(name, command)
|
||||||
raise "invalid command. name: #{name}" unless command
|
raise "invalid command. name: #{name}" unless command
|
||||||
synchronize do
|
synchronize do
|
||||||
return if @servers.include?(name)
|
return if @servers.include?(name)
|
||||||
@servers[name] = false
|
@servers[name] = false
|
||||||
end
|
end
|
||||||
uri = @uri || DRb.uri
|
uri = @uri || DRb.uri
|
||||||
Process.detach spawn("#{command} #{uri} #{name}")
|
Process.detach spawn("#{command} #{uri} #{name}")
|
||||||
|
@ -4,9 +4,9 @@ module DRb
|
|||||||
class DRbServer
|
class DRbServer
|
||||||
module InvokeMethod18Mixin
|
module InvokeMethod18Mixin
|
||||||
def block_yield(x)
|
def block_yield(x)
|
||||||
if x.size == 1 && x[0].class == Array
|
if x.size == 1 && x[0].class == Array
|
||||||
x[0] = DRbArray.new(x[0])
|
x[0] = DRbArray.new(x[0])
|
||||||
end
|
end
|
||||||
@block.call(*x)
|
@block.call(*x)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
160
lib/drb/ssl.rb
160
lib/drb/ssl.rb
@ -10,43 +10,43 @@ module DRb
|
|||||||
class SSLConfig
|
class SSLConfig
|
||||||
|
|
||||||
DEFAULT = {
|
DEFAULT = {
|
||||||
:SSLCertificate => nil,
|
:SSLCertificate => nil,
|
||||||
:SSLPrivateKey => nil,
|
:SSLPrivateKey => nil,
|
||||||
:SSLClientCA => nil,
|
:SSLClientCA => nil,
|
||||||
:SSLCACertificatePath => nil,
|
:SSLCACertificatePath => nil,
|
||||||
:SSLCACertificateFile => nil,
|
:SSLCACertificateFile => nil,
|
||||||
:SSLVerifyMode => ::OpenSSL::SSL::VERIFY_NONE,
|
:SSLVerifyMode => ::OpenSSL::SSL::VERIFY_NONE,
|
||||||
:SSLVerifyDepth => nil,
|
:SSLVerifyDepth => nil,
|
||||||
:SSLVerifyCallback => nil, # custom verification
|
:SSLVerifyCallback => nil, # custom verification
|
||||||
:SSLCertificateStore => nil,
|
:SSLCertificateStore => nil,
|
||||||
# Must specify if you use auto generated certificate.
|
# Must specify if you use auto generated certificate.
|
||||||
:SSLCertName => nil, # e.g. [["CN","fqdn.example.com"]]
|
:SSLCertName => nil, # e.g. [["CN","fqdn.example.com"]]
|
||||||
:SSLCertComment => "Generated by Ruby/OpenSSL"
|
:SSLCertComment => "Generated by Ruby/OpenSSL"
|
||||||
}
|
}
|
||||||
|
|
||||||
def initialize(config)
|
def initialize(config)
|
||||||
@config = config
|
@config = config
|
||||||
@cert = config[:SSLCertificate]
|
@cert = config[:SSLCertificate]
|
||||||
@pkey = config[:SSLPrivateKey]
|
@pkey = config[:SSLPrivateKey]
|
||||||
@ssl_ctx = nil
|
@ssl_ctx = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def [](key);
|
def [](key);
|
||||||
@config[key] || DEFAULT[key]
|
@config[key] || DEFAULT[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
def connect(tcp)
|
def connect(tcp)
|
||||||
ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
|
ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
|
||||||
ssl.sync = true
|
ssl.sync = true
|
||||||
ssl.connect
|
ssl.connect
|
||||||
ssl
|
ssl
|
||||||
end
|
end
|
||||||
|
|
||||||
def accept(tcp)
|
def accept(tcp)
|
||||||
ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
|
ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
|
||||||
ssl.sync = true
|
ssl.sync = true
|
||||||
ssl.accept
|
ssl.accept
|
||||||
ssl
|
ssl
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup_certificate
|
def setup_certificate
|
||||||
@ -54,56 +54,56 @@ module DRb
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
rsa = OpenSSL::PKey::RSA.new(512){|p, n|
|
rsa = OpenSSL::PKey::RSA.new(512){|p, n|
|
||||||
next unless self[:verbose]
|
next unless self[:verbose]
|
||||||
case p
|
case p
|
||||||
when 0; $stderr.putc "." # BN_generate_prime
|
when 0; $stderr.putc "." # BN_generate_prime
|
||||||
when 1; $stderr.putc "+" # BN_generate_prime
|
when 1; $stderr.putc "+" # BN_generate_prime
|
||||||
when 2; $stderr.putc "*" # searching good prime,
|
when 2; $stderr.putc "*" # searching good prime,
|
||||||
# n = #of try,
|
# n = #of try,
|
||||||
# but also data from BN_generate_prime
|
# but also data from BN_generate_prime
|
||||||
when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
|
when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
|
||||||
# but also data from BN_generate_prime
|
# but also data from BN_generate_prime
|
||||||
else; $stderr.putc "*" # BN_generate_prime
|
else; $stderr.putc "*" # BN_generate_prime
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
cert = OpenSSL::X509::Certificate.new
|
cert = OpenSSL::X509::Certificate.new
|
||||||
cert.version = 3
|
cert.version = 3
|
||||||
cert.serial = 0
|
cert.serial = 0
|
||||||
name = OpenSSL::X509::Name.new(self[:SSLCertName])
|
name = OpenSSL::X509::Name.new(self[:SSLCertName])
|
||||||
cert.subject = name
|
cert.subject = name
|
||||||
cert.issuer = name
|
cert.issuer = name
|
||||||
cert.not_before = Time.now
|
cert.not_before = Time.now
|
||||||
cert.not_after = Time.now + (365*24*60*60)
|
cert.not_after = Time.now + (365*24*60*60)
|
||||||
cert.public_key = rsa.public_key
|
cert.public_key = rsa.public_key
|
||||||
|
|
||||||
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
|
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
|
||||||
cert.extensions = [
|
cert.extensions = [
|
||||||
ef.create_extension("basicConstraints","CA:FALSE"),
|
ef.create_extension("basicConstraints","CA:FALSE"),
|
||||||
ef.create_extension("subjectKeyIdentifier", "hash") ]
|
ef.create_extension("subjectKeyIdentifier", "hash") ]
|
||||||
ef.issuer_certificate = cert
|
ef.issuer_certificate = cert
|
||||||
cert.add_extension(ef.create_extension("authorityKeyIdentifier",
|
cert.add_extension(ef.create_extension("authorityKeyIdentifier",
|
||||||
"keyid:always,issuer:always"))
|
"keyid:always,issuer:always"))
|
||||||
if comment = self[:SSLCertComment]
|
if comment = self[:SSLCertComment]
|
||||||
cert.add_extension(ef.create_extension("nsComment", comment))
|
cert.add_extension(ef.create_extension("nsComment", comment))
|
||||||
end
|
end
|
||||||
cert.sign(rsa, OpenSSL::Digest::SHA1.new)
|
cert.sign(rsa, OpenSSL::Digest::SHA1.new)
|
||||||
|
|
||||||
@cert = cert
|
@cert = cert
|
||||||
@pkey = rsa
|
@pkey = rsa
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup_ssl_context
|
def setup_ssl_context
|
||||||
ctx = ::OpenSSL::SSL::SSLContext.new
|
ctx = ::OpenSSL::SSL::SSLContext.new
|
||||||
ctx.cert = @cert
|
ctx.cert = @cert
|
||||||
ctx.key = @pkey
|
ctx.key = @pkey
|
||||||
ctx.client_ca = self[:SSLClientCA]
|
ctx.client_ca = self[:SSLClientCA]
|
||||||
ctx.ca_path = self[:SSLCACertificatePath]
|
ctx.ca_path = self[:SSLCACertificatePath]
|
||||||
ctx.ca_file = self[:SSLCACertificateFile]
|
ctx.ca_file = self[:SSLCACertificateFile]
|
||||||
ctx.verify_mode = self[:SSLVerifyMode]
|
ctx.verify_mode = self[:SSLVerifyMode]
|
||||||
ctx.verify_depth = self[:SSLVerifyDepth]
|
ctx.verify_depth = self[:SSLVerifyDepth]
|
||||||
ctx.verify_callback = self[:SSLVerifyCallback]
|
ctx.verify_callback = self[:SSLVerifyCallback]
|
||||||
ctx.cert_store = self[:SSLCertificateStore]
|
ctx.cert_store = self[:SSLCertificateStore]
|
||||||
@ssl_ctx = ctx
|
@ssl_ctx = ctx
|
||||||
end
|
end
|
||||||
@ -111,13 +111,13 @@ module DRb
|
|||||||
|
|
||||||
def self.parse_uri(uri)
|
def self.parse_uri(uri)
|
||||||
if uri =~ /^drbssl:\/\/(.*?):(\d+)(\?(.*))?$/
|
if uri =~ /^drbssl:\/\/(.*?):(\d+)(\?(.*))?$/
|
||||||
host = $1
|
host = $1
|
||||||
port = $2.to_i
|
port = $2.to_i
|
||||||
option = $4
|
option = $4
|
||||||
[host, port, option]
|
[host, port, option]
|
||||||
else
|
else
|
||||||
raise(DRbBadScheme, uri) unless uri =~ /^drbssl:/
|
raise(DRbBadScheme, uri) unless uri =~ /^drbssl:/
|
||||||
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ module DRb
|
|||||||
host = getservername
|
host = getservername
|
||||||
soc = open_server_inaddr_any(host, port)
|
soc = open_server_inaddr_any(host, port)
|
||||||
else
|
else
|
||||||
soc = TCPServer.open(host, port)
|
soc = TCPServer.open(host, port)
|
||||||
end
|
end
|
||||||
port = soc.addr[1] if port == 0
|
port = soc.addr[1] if port == 0
|
||||||
@uri = "drbssl://#{host}:#{port}"
|
@uri = "drbssl://#{host}:#{port}"
|
||||||
@ -164,24 +164,24 @@ module DRb
|
|||||||
|
|
||||||
def close
|
def close
|
||||||
if @ssl
|
if @ssl
|
||||||
@ssl.close
|
@ssl.close
|
||||||
@ssl = nil
|
@ssl = nil
|
||||||
end
|
end
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def accept
|
def accept
|
||||||
begin
|
begin
|
||||||
while true
|
while true
|
||||||
soc = @socket.accept
|
soc = @socket.accept
|
||||||
break if (@acl ? @acl.allow_socket?(soc) : true)
|
break if (@acl ? @acl.allow_socket?(soc) : true)
|
||||||
soc.close
|
soc.close
|
||||||
end
|
end
|
||||||
ssl = @config.accept(soc)
|
ssl = @config.accept(soc)
|
||||||
self.class.new(uri, ssl, @config, true)
|
self.class.new(uri, ssl, @config, true)
|
||||||
rescue OpenSSL::SSL::SSLError
|
rescue OpenSSL::SSL::SSLError
|
||||||
warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose]
|
warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose]
|
||||||
retry
|
retry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -9,65 +9,65 @@ module DRb
|
|||||||
class InvalidIndexError < RuntimeError; end
|
class InvalidIndexError < RuntimeError; end
|
||||||
|
|
||||||
def initialize(timeout=600)
|
def initialize(timeout=600)
|
||||||
super()
|
super()
|
||||||
@sentinel = Object.new
|
@sentinel = Object.new
|
||||||
@gc = {}
|
@gc = {}
|
||||||
@curr = {}
|
@curr = {}
|
||||||
@renew = {}
|
@renew = {}
|
||||||
@timeout = timeout
|
@timeout = timeout
|
||||||
@keeper = keeper
|
@keeper = keeper
|
||||||
end
|
end
|
||||||
|
|
||||||
def add(obj)
|
def add(obj)
|
||||||
synchronize do
|
synchronize do
|
||||||
key = obj.__id__
|
key = obj.__id__
|
||||||
@curr[key] = obj
|
@curr[key] = obj
|
||||||
return key
|
return key
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch(key, dv=@sentinel)
|
def fetch(key, dv=@sentinel)
|
||||||
synchronize do
|
synchronize do
|
||||||
obj = peek(key)
|
obj = peek(key)
|
||||||
if obj == @sentinel
|
if obj == @sentinel
|
||||||
return dv unless dv == @sentinel
|
return dv unless dv == @sentinel
|
||||||
raise InvalidIndexError
|
raise InvalidIndexError
|
||||||
end
|
end
|
||||||
@renew[key] = obj # KeepIt
|
@renew[key] = obj # KeepIt
|
||||||
return obj
|
return obj
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def include?(key)
|
def include?(key)
|
||||||
synchronize do
|
synchronize do
|
||||||
obj = peek(key)
|
obj = peek(key)
|
||||||
return false if obj == @sentinel
|
return false if obj == @sentinel
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def peek(key)
|
def peek(key)
|
||||||
synchronize do
|
synchronize do
|
||||||
return @curr.fetch(key, @renew.fetch(key, @gc.fetch(key, @sentinel)))
|
return @curr.fetch(key, @renew.fetch(key, @gc.fetch(key, @sentinel)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def alternate
|
def alternate
|
||||||
synchronize do
|
synchronize do
|
||||||
@gc = @curr # GCed
|
@gc = @curr # GCed
|
||||||
@curr = @renew
|
@curr = @renew
|
||||||
@renew = {}
|
@renew = {}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def keeper
|
def keeper
|
||||||
Thread.new do
|
Thread.new do
|
||||||
loop do
|
loop do
|
||||||
alternate
|
alternate
|
||||||
sleep(@timeout)
|
sleep(@timeout)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -9,12 +9,12 @@ module DRb
|
|||||||
class DRbUNIXSocket < DRbTCPSocket
|
class DRbUNIXSocket < DRbTCPSocket
|
||||||
def self.parse_uri(uri)
|
def self.parse_uri(uri)
|
||||||
if /^drbunix:(.*?)(\?(.*))?$/ =~ uri
|
if /^drbunix:(.*?)(\?(.*))?$/ =~ uri
|
||||||
filename = $1
|
filename = $1
|
||||||
option = $3
|
option = $3
|
||||||
[filename, option]
|
[filename, option]
|
||||||
else
|
else
|
||||||
raise(DRbBadScheme, uri) unless uri =~ /^drbunix:/
|
raise(DRbBadScheme, uri) unless uri =~ /^drbunix:/
|
||||||
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -28,11 +28,11 @@ module DRb
|
|||||||
def self.open_server(uri, config)
|
def self.open_server(uri, config)
|
||||||
filename, = parse_uri(uri)
|
filename, = parse_uri(uri)
|
||||||
if filename.size == 0
|
if filename.size == 0
|
||||||
soc = temp_server
|
soc = temp_server
|
||||||
filename = soc.path
|
filename = soc.path
|
||||||
uri = 'drbunix:' + soc.path
|
uri = 'drbunix:' + soc.path
|
||||||
else
|
else
|
||||||
soc = UNIXServer.open(filename)
|
soc = UNIXServer.open(filename)
|
||||||
end
|
end
|
||||||
owner = config[:UNIXFileOwner]
|
owner = config[:UNIXFileOwner]
|
||||||
group = config[:UNIXFileGroup]
|
group = config[:UNIXFileGroup]
|
||||||
@ -67,18 +67,18 @@ module DRb
|
|||||||
tmpdir = Dir::tmpdir
|
tmpdir = Dir::tmpdir
|
||||||
n = 0
|
n = 0
|
||||||
while true
|
while true
|
||||||
begin
|
begin
|
||||||
tmpname = sprintf('%s/druby%d.%d', tmpdir, $$, n)
|
tmpname = sprintf('%s/druby%d.%d', tmpdir, $$, n)
|
||||||
lock = tmpname + '.lock'
|
lock = tmpname + '.lock'
|
||||||
unless File.exist?(tmpname) or File.exist?(lock)
|
unless File.exist?(tmpname) or File.exist?(lock)
|
||||||
Dir.mkdir(lock)
|
Dir.mkdir(lock)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
raise "cannot generate tempfile `%s'" % tmpname if n >= Max_try
|
raise "cannot generate tempfile `%s'" % tmpname if n >= Max_try
|
||||||
#sleep(1)
|
#sleep(1)
|
||||||
end
|
end
|
||||||
n += 1
|
n += 1
|
||||||
end
|
end
|
||||||
soc = UNIXServer.new(tmpname)
|
soc = UNIXServer.new(tmpname)
|
||||||
Dir.rmdir(lock)
|
Dir.rmdir(lock)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# e2mmap.rb - for ruby 1.1
|
# e2mmap.rb - for ruby 1.1
|
||||||
# $Release Version: 2.0$
|
# $Release Version: 2.0$
|
||||||
# $Revision: 1.10 $
|
# $Revision: 1.10 $
|
||||||
# by Keiju ISHITSUKA
|
# by Keiju ISHITSUKA
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
# Usage:
|
# Usage:
|
||||||
@ -60,19 +60,19 @@ module Exception2MessageMapper
|
|||||||
def bind(cl)
|
def bind(cl)
|
||||||
self.module_eval %[
|
self.module_eval %[
|
||||||
def Raise(err = nil, *rest)
|
def Raise(err = nil, *rest)
|
||||||
Exception2MessageMapper.Raise(self.class, err, *rest)
|
Exception2MessageMapper.Raise(self.class, err, *rest)
|
||||||
end
|
end
|
||||||
alias Fail Raise
|
alias Fail Raise
|
||||||
|
|
||||||
def self.included(mod)
|
def self.included(mod)
|
||||||
mod.extend Exception2MessageMapper
|
mod.extend Exception2MessageMapper
|
||||||
end
|
end
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Fail(err, *rest)
|
# Fail(err, *rest)
|
||||||
# err: exception
|
# err: exception
|
||||||
# rest: message arguments
|
# rest: message arguments
|
||||||
#
|
#
|
||||||
def Raise(err = nil, *rest)
|
def Raise(err = nil, *rest)
|
||||||
E2MM.Raise(self, err, *rest)
|
E2MM.Raise(self, err, *rest)
|
||||||
@ -81,19 +81,19 @@ module Exception2MessageMapper
|
|||||||
alias fail Raise
|
alias fail Raise
|
||||||
|
|
||||||
# def_e2message(c, m)
|
# def_e2message(c, m)
|
||||||
# c: exception
|
# c: exception
|
||||||
# m: message_form
|
# m: message_form
|
||||||
# define exception c with message m.
|
# define exception c with message m.
|
||||||
#
|
#
|
||||||
def def_e2message(c, m)
|
def def_e2message(c, m)
|
||||||
E2MM.def_e2message(self, c, m)
|
E2MM.def_e2message(self, c, m)
|
||||||
end
|
end
|
||||||
|
|
||||||
# def_exception(n, m, s)
|
# def_exception(n, m, s)
|
||||||
# n: exception_name
|
# n: exception_name
|
||||||
# m: message_form
|
# m: message_form
|
||||||
# s: superclass(default: StandardError)
|
# s: superclass(default: StandardError)
|
||||||
# define exception named ``c'' with message m.
|
# define exception named ``c'' with message m.
|
||||||
#
|
#
|
||||||
def def_exception(n, m, s = StandardError)
|
def def_exception(n, m, s = StandardError)
|
||||||
E2MM.def_exception(self, n, m, s)
|
E2MM.def_exception(self, n, m, s)
|
||||||
@ -106,10 +106,10 @@ module Exception2MessageMapper
|
|||||||
@MessageMap = {}
|
@MessageMap = {}
|
||||||
|
|
||||||
# E2MM.def_e2message(k, e, m)
|
# E2MM.def_e2message(k, e, m)
|
||||||
# k: class to define exception under.
|
# k: class to define exception under.
|
||||||
# e: exception
|
# e: exception
|
||||||
# m: message_form
|
# m: message_form
|
||||||
# define exception c with message m.
|
# define exception c with message m.
|
||||||
#
|
#
|
||||||
def E2MM.def_e2message(k, c, m)
|
def E2MM.def_e2message(k, c, m)
|
||||||
E2MM.instance_eval{@MessageMap[[k, c]] = m}
|
E2MM.instance_eval{@MessageMap[[k, c]] = m}
|
||||||
@ -117,11 +117,11 @@ module Exception2MessageMapper
|
|||||||
end
|
end
|
||||||
|
|
||||||
# E2MM.def_exception(k, n, m, s)
|
# E2MM.def_exception(k, n, m, s)
|
||||||
# k: class to define exception under.
|
# k: class to define exception under.
|
||||||
# n: exception_name
|
# n: exception_name
|
||||||
# m: message_form
|
# m: message_form
|
||||||
# s: superclass(default: StandardError)
|
# s: superclass(default: StandardError)
|
||||||
# define exception named ``c'' with message m.
|
# define exception named ``c'' with message m.
|
||||||
#
|
#
|
||||||
def E2MM.def_exception(k, n, m, s = StandardError)
|
def E2MM.def_exception(k, n, m, s = StandardError)
|
||||||
n = n.id2name if n.kind_of?(Fixnum)
|
n = n.id2name if n.kind_of?(Fixnum)
|
||||||
@ -131,9 +131,9 @@ module Exception2MessageMapper
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Fail(klass, err, *rest)
|
# Fail(klass, err, *rest)
|
||||||
# klass: class to define exception under.
|
# klass: class to define exception under.
|
||||||
# err: exception
|
# err: exception
|
||||||
# rest: message arguments
|
# rest: message arguments
|
||||||
#
|
#
|
||||||
def E2MM.Raise(klass = E2MM, err = nil, *rest)
|
def E2MM.Raise(klass = E2MM, err = nil, *rest)
|
||||||
if form = e2mm_message(klass, err)
|
if form = e2mm_message(klass, err)
|
||||||
@ -141,7 +141,7 @@ module Exception2MessageMapper
|
|||||||
#p $@
|
#p $@
|
||||||
#p __FILE__
|
#p __FILE__
|
||||||
b.shift if b[0] =~ /^#{Regexp.quote(__FILE__)}:/
|
b.shift if b[0] =~ /^#{Regexp.quote(__FILE__)}:/
|
||||||
raise err, sprintf(form, *rest), b
|
raise err, sprintf(form, *rest), b
|
||||||
else
|
else
|
||||||
E2MM.Fail E2MM, ErrNotRegisteredException, err.inspect
|
E2MM.Fail E2MM, ErrNotRegisteredException, err.inspect
|
||||||
end
|
end
|
||||||
@ -153,9 +153,9 @@ module Exception2MessageMapper
|
|||||||
def E2MM.e2mm_message(klass, exp)
|
def E2MM.e2mm_message(klass, exp)
|
||||||
for c in klass.ancestors
|
for c in klass.ancestors
|
||||||
if mes = @MessageMap[[c,exp]]
|
if mes = @MessageMap[[c,exp]]
|
||||||
#p mes
|
#p mes
|
||||||
m = klass.instance_eval('"' + mes + '"')
|
m = klass.instance_eval('"' + mes + '"')
|
||||||
return m
|
return m
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
nil
|
nil
|
||||||
@ -165,8 +165,8 @@ module Exception2MessageMapper
|
|||||||
end
|
end
|
||||||
|
|
||||||
E2MM.def_exception(E2MM,
|
E2MM.def_exception(E2MM,
|
||||||
:ErrNotRegisteredException,
|
:ErrNotRegisteredException,
|
||||||
"not registerd exception(%s)")
|
"not registerd exception(%s)")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
282
lib/erb.rb
282
lib/erb.rb
@ -254,7 +254,7 @@
|
|||||||
# Rails, the web application framework, uses ERB to create views.
|
# Rails, the web application framework, uses ERB to create views.
|
||||||
#
|
#
|
||||||
class ERB
|
class ERB
|
||||||
Revision = '$Date:: $' #'
|
Revision = '$Date:: $' #'
|
||||||
|
|
||||||
# Returns revision information for the erb.rb module.
|
# Returns revision information for the erb.rb module.
|
||||||
def self.version
|
def self.version
|
||||||
@ -351,21 +351,21 @@ class ERB
|
|||||||
class Scanner # :nodoc:
|
class Scanner # :nodoc:
|
||||||
@scanner_map = {}
|
@scanner_map = {}
|
||||||
def self.regist_scanner(klass, trim_mode, percent)
|
def self.regist_scanner(klass, trim_mode, percent)
|
||||||
@scanner_map[[trim_mode, percent]] = klass
|
@scanner_map[[trim_mode, percent]] = klass
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.default_scanner=(klass)
|
def self.default_scanner=(klass)
|
||||||
@default_scanner = klass
|
@default_scanner = klass
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.make_scanner(src, trim_mode, percent)
|
def self.make_scanner(src, trim_mode, percent)
|
||||||
klass = @scanner_map.fetch([trim_mode, percent], @default_scanner)
|
klass = @scanner_map.fetch([trim_mode, percent], @default_scanner)
|
||||||
klass.new(src, trim_mode, percent)
|
klass.new(src, trim_mode, percent)
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(src, trim_mode, percent)
|
def initialize(src, trim_mode, percent)
|
||||||
@src = src
|
@src = src
|
||||||
@stag = nil
|
@stag = nil
|
||||||
end
|
end
|
||||||
attr_accessor :stag
|
attr_accessor :stag
|
||||||
|
|
||||||
@ -374,44 +374,44 @@ class ERB
|
|||||||
|
|
||||||
class TrimScanner < Scanner # :nodoc:
|
class TrimScanner < Scanner # :nodoc:
|
||||||
def initialize(src, trim_mode, percent)
|
def initialize(src, trim_mode, percent)
|
||||||
super
|
super
|
||||||
@trim_mode = trim_mode
|
@trim_mode = trim_mode
|
||||||
@percent = percent
|
@percent = percent
|
||||||
if @trim_mode == '>'
|
if @trim_mode == '>'
|
||||||
@scan_line = self.method(:trim_line1)
|
@scan_line = self.method(:trim_line1)
|
||||||
elsif @trim_mode == '<>'
|
elsif @trim_mode == '<>'
|
||||||
@scan_line = self.method(:trim_line2)
|
@scan_line = self.method(:trim_line2)
|
||||||
elsif @trim_mode == '-'
|
elsif @trim_mode == '-'
|
||||||
@scan_line = self.method(:explicit_trim_line)
|
@scan_line = self.method(:explicit_trim_line)
|
||||||
else
|
else
|
||||||
@scan_line = self.method(:scan_line)
|
@scan_line = self.method(:scan_line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
attr_accessor :stag
|
attr_accessor :stag
|
||||||
|
|
||||||
def scan(&block)
|
def scan(&block)
|
||||||
@stag = nil
|
@stag = nil
|
||||||
if @percent
|
if @percent
|
||||||
@src.each_line do |line|
|
@src.each_line do |line|
|
||||||
percent_line(line, &block)
|
percent_line(line, &block)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@scan_line.call(@src, &block)
|
@scan_line.call(@src, &block)
|
||||||
end
|
end
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def percent_line(line, &block)
|
def percent_line(line, &block)
|
||||||
if @stag || line[0] != ?%
|
if @stag || line[0] != ?%
|
||||||
return @scan_line.call(line, &block)
|
return @scan_line.call(line, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
line[0] = ''
|
line[0] = ''
|
||||||
if line[0] == ?%
|
if line[0] == ?%
|
||||||
@scan_line.call(line, &block)
|
@scan_line.call(line, &block)
|
||||||
else
|
else
|
||||||
yield(PercentLine.new(line.chomp))
|
yield(PercentLine.new(line.chomp))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def scan_line(line)
|
def scan_line(line)
|
||||||
@ -420,7 +420,7 @@ class ERB
|
|||||||
next if token.empty?
|
next if token.empty?
|
||||||
yield(token)
|
yield(token)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def trim_line1(line)
|
def trim_line1(line)
|
||||||
@ -434,11 +434,11 @@ class ERB
|
|||||||
yield(token)
|
yield(token)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def trim_line2(line)
|
def trim_line2(line)
|
||||||
head = nil
|
head = nil
|
||||||
line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
|
line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
|
||||||
tokens.each do |token|
|
tokens.each do |token|
|
||||||
next if token.empty?
|
next if token.empty?
|
||||||
@ -456,7 +456,7 @@ class ERB
|
|||||||
head = nil if token == "\n"
|
head = nil if token == "\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def explicit_trim_line(line)
|
def explicit_trim_line(line)
|
||||||
@ -479,7 +479,7 @@ class ERB
|
|||||||
|
|
||||||
ERB_STAG = %w(<%= <%# <%)
|
ERB_STAG = %w(<%= <%# <%)
|
||||||
def is_erb_stag?(s)
|
def is_erb_stag?(s)
|
||||||
ERB_STAG.member?(s)
|
ERB_STAG.member?(s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -492,7 +492,7 @@ class ERB
|
|||||||
next if token.empty?
|
next if token.empty?
|
||||||
yield(token)
|
yield(token)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -515,23 +515,23 @@ class ERB
|
|||||||
Scanner.regist_scanner(SimpleScanner2, nil, false)
|
Scanner.regist_scanner(SimpleScanner2, nil, false)
|
||||||
|
|
||||||
class ExplicitScanner < Scanner # :nodoc:
|
class ExplicitScanner < Scanner # :nodoc:
|
||||||
def scan
|
def scan
|
||||||
stag_reg = /(.*?)(^[ \t]*<%-|<%%|<%=|<%#|<%-|<%|\z)/m
|
stag_reg = /(.*?)(^[ \t]*<%-|<%%|<%=|<%#|<%-|<%|\z)/m
|
||||||
etag_reg = /(.*?)(%%>|-%>|%>|\z)/m
|
etag_reg = /(.*?)(%%>|-%>|%>|\z)/m
|
||||||
scanner = StringScanner.new(@src)
|
scanner = StringScanner.new(@src)
|
||||||
while ! scanner.eos?
|
while ! scanner.eos?
|
||||||
scanner.scan(@stag ? etag_reg : stag_reg)
|
scanner.scan(@stag ? etag_reg : stag_reg)
|
||||||
yield(scanner[1])
|
yield(scanner[1])
|
||||||
|
|
||||||
elem = scanner[2]
|
elem = scanner[2]
|
||||||
if /[ \t]*<%-/ =~ elem
|
if /[ \t]*<%-/ =~ elem
|
||||||
yield('<%')
|
yield('<%')
|
||||||
elsif elem == '-%>'
|
elsif elem == '-%>'
|
||||||
yield('%>')
|
yield('%>')
|
||||||
yield(:cr) if scanner.scan(/(\n|\z)/)
|
yield(:cr) if scanner.scan(/(\n|\z)/)
|
||||||
else
|
else
|
||||||
yield(elem)
|
yield(elem)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -542,32 +542,32 @@ class ERB
|
|||||||
|
|
||||||
class Buffer # :nodoc:
|
class Buffer # :nodoc:
|
||||||
def initialize(compiler, enc=nil)
|
def initialize(compiler, enc=nil)
|
||||||
@compiler = compiler
|
@compiler = compiler
|
||||||
@line = []
|
@line = []
|
||||||
@script = enc ? "#coding:#{enc.to_s}\n" : ""
|
@script = enc ? "#coding:#{enc.to_s}\n" : ""
|
||||||
@compiler.pre_cmd.each do |x|
|
@compiler.pre_cmd.each do |x|
|
||||||
push(x)
|
push(x)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
attr_reader :script
|
attr_reader :script
|
||||||
|
|
||||||
def push(cmd)
|
def push(cmd)
|
||||||
@line << cmd
|
@line << cmd
|
||||||
end
|
end
|
||||||
|
|
||||||
def cr
|
def cr
|
||||||
@script << (@line.join('; '))
|
@script << (@line.join('; '))
|
||||||
@line = []
|
@line = []
|
||||||
@script << "\n"
|
@script << "\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
return unless @line
|
return unless @line
|
||||||
@compiler.post_cmd.each do |x|
|
@compiler.post_cmd.each do |x|
|
||||||
push(x)
|
push(x)
|
||||||
end
|
end
|
||||||
@script << (@line.join('; '))
|
@script << (@line.join('; '))
|
||||||
@line = nil
|
@line = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -594,53 +594,53 @@ class ERB
|
|||||||
scanner.scan do |token|
|
scanner.scan do |token|
|
||||||
next if token.nil?
|
next if token.nil?
|
||||||
next if token == ''
|
next if token == ''
|
||||||
if scanner.stag.nil?
|
if scanner.stag.nil?
|
||||||
case token
|
case token
|
||||||
when PercentLine
|
when PercentLine
|
||||||
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
||||||
content = ''
|
content = ''
|
||||||
out.push(token.to_s)
|
out.push(token.to_s)
|
||||||
out.cr
|
out.cr
|
||||||
when :cr
|
when :cr
|
||||||
out.cr
|
out.cr
|
||||||
when '<%', '<%=', '<%#'
|
when '<%', '<%=', '<%#'
|
||||||
scanner.stag = token
|
scanner.stag = token
|
||||||
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
||||||
content = ''
|
content = ''
|
||||||
when "\n"
|
when "\n"
|
||||||
content << "\n"
|
content << "\n"
|
||||||
out.push("#{@put_cmd} #{content_dump(content)}")
|
out.push("#{@put_cmd} #{content_dump(content)}")
|
||||||
content = ''
|
content = ''
|
||||||
when '<%%'
|
when '<%%'
|
||||||
content << '<%'
|
content << '<%'
|
||||||
else
|
else
|
||||||
content << token
|
content << token
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
case token
|
case token
|
||||||
when '%>'
|
when '%>'
|
||||||
case scanner.stag
|
case scanner.stag
|
||||||
when '<%'
|
when '<%'
|
||||||
if content[-1] == ?\n
|
if content[-1] == ?\n
|
||||||
content.chop!
|
content.chop!
|
||||||
out.push(content)
|
out.push(content)
|
||||||
out.cr
|
out.cr
|
||||||
else
|
else
|
||||||
out.push(content)
|
out.push(content)
|
||||||
end
|
end
|
||||||
when '<%='
|
when '<%='
|
||||||
out.push("#{@insert_cmd}((#{content}).to_s)")
|
out.push("#{@insert_cmd}((#{content}).to_s)")
|
||||||
when '<%#'
|
when '<%#'
|
||||||
# out.push("# #{content_dump(content)}")
|
# out.push("# #{content_dump(content)}")
|
||||||
end
|
end
|
||||||
scanner.stag = nil
|
scanner.stag = nil
|
||||||
content = ''
|
content = ''
|
||||||
when '%%>'
|
when '%%>'
|
||||||
content << '%>'
|
content << '%>'
|
||||||
else
|
else
|
||||||
content << token
|
content << token
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
||||||
out.close
|
out.close
|
||||||
@ -650,24 +650,24 @@ class ERB
|
|||||||
def prepare_trim_mode(mode) # :nodoc:
|
def prepare_trim_mode(mode) # :nodoc:
|
||||||
case mode
|
case mode
|
||||||
when 1
|
when 1
|
||||||
return [false, '>']
|
return [false, '>']
|
||||||
when 2
|
when 2
|
||||||
return [false, '<>']
|
return [false, '<>']
|
||||||
when 0
|
when 0
|
||||||
return [false, nil]
|
return [false, nil]
|
||||||
when String
|
when String
|
||||||
perc = mode.include?('%')
|
perc = mode.include?('%')
|
||||||
if mode.include?('-')
|
if mode.include?('-')
|
||||||
return [perc, '-']
|
return [perc, '-']
|
||||||
elsif mode.include?('<>')
|
elsif mode.include?('<>')
|
||||||
return [perc, '<>']
|
return [perc, '<>']
|
||||||
elsif mode.include?('>')
|
elsif mode.include?('>')
|
||||||
return [perc, '>']
|
return [perc, '>']
|
||||||
else
|
else
|
||||||
[perc, nil]
|
[perc, nil]
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return [false, nil]
|
return [false, nil]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -701,12 +701,12 @@ class ERB
|
|||||||
private
|
private
|
||||||
def detect_magic_comment(s)
|
def detect_magic_comment(s)
|
||||||
if /\A<%#(.*)%>/ =~ s or (@percent and /\A%#(.*)/ =~ s)
|
if /\A<%#(.*)%>/ =~ s or (@percent and /\A%#(.*)/ =~ s)
|
||||||
comment = $1
|
comment = $1
|
||||||
comment = $1 if comment[/-\*-\s*(.*?)\s*-*-$/]
|
comment = $1 if comment[/-\*-\s*(.*?)\s*-*-$/]
|
||||||
if %r"coding\s*[=:]\s*([[:alnum:]\-_]+)" =~ comment
|
if %r"coding\s*[=:]\s*([[:alnum:]\-_]+)" =~ comment
|
||||||
enc = $1.sub(/-(?:mac|dos|unix)/i, '')
|
enc = $1.sub(/-(?:mac|dos|unix)/i, '')
|
||||||
enc = Encoding.find(enc)
|
enc = Encoding.find(enc)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -726,9 +726,9 @@ class ERB
|
|||||||
# If _trim_mode_ is passed a String containing one or more of the following
|
# If _trim_mode_ is passed a String containing one or more of the following
|
||||||
# modifiers, ERB will adjust its code generation as listed:
|
# modifiers, ERB will adjust its code generation as listed:
|
||||||
#
|
#
|
||||||
# % enables Ruby code processing for lines beginning with %
|
# % enables Ruby code processing for lines beginning with %
|
||||||
# <> omit newline for lines starting with <% and ending in %>
|
# <> omit newline for lines starting with <% and ending in %>
|
||||||
# > omit newline for lines ending in %>
|
# > omit newline for lines ending in %>
|
||||||
#
|
#
|
||||||
# _eoutvar_ can be used to set the name of the variable ERB will build up
|
# _eoutvar_ can be used to set the name of the variable ERB will build up
|
||||||
# its output in. This is useful when you need to run multiple ERB
|
# its output in. This is useful when you need to run multiple ERB
|
||||||
@ -831,8 +831,8 @@ class ERB
|
|||||||
def result(b=TOPLEVEL_BINDING)
|
def result(b=TOPLEVEL_BINDING)
|
||||||
if @safe_level
|
if @safe_level
|
||||||
proc {
|
proc {
|
||||||
$SAFE = @safe_level
|
$SAFE = @safe_level
|
||||||
eval(@src, b, (@filename || '(erb)'), 0)
|
eval(@src, b, (@filename || '(erb)'), 0)
|
||||||
}.call
|
}.call
|
||||||
else
|
else
|
||||||
eval(@src, b, (@filename || '(erb)'), 0)
|
eval(@src, b, (@filename || '(erb)'), 0)
|
||||||
@ -899,14 +899,14 @@ class ERB
|
|||||||
#
|
#
|
||||||
# A utility method for escaping HTML tag characters in _s_.
|
# A utility method for escaping HTML tag characters in _s_.
|
||||||
#
|
#
|
||||||
# require "erb"
|
# require "erb"
|
||||||
# include ERB::Util
|
# include ERB::Util
|
||||||
#
|
#
|
||||||
# puts html_escape("is a > 0 & a < 10?")
|
# puts html_escape("is a > 0 & a < 10?")
|
||||||
#
|
#
|
||||||
# _Generates_
|
# _Generates_
|
||||||
#
|
#
|
||||||
# is a > 0 & a < 10?
|
# is a > 0 & a < 10?
|
||||||
#
|
#
|
||||||
def html_escape(s)
|
def html_escape(s)
|
||||||
s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/</, "<")
|
s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/</, "<")
|
||||||
@ -918,14 +918,14 @@ class ERB
|
|||||||
#
|
#
|
||||||
# A utility method for encoding the String _s_ as a URL.
|
# A utility method for encoding the String _s_ as a URL.
|
||||||
#
|
#
|
||||||
# require "erb"
|
# require "erb"
|
||||||
# include ERB::Util
|
# include ERB::Util
|
||||||
#
|
#
|
||||||
# puts url_encode("Programming Ruby: The Pragmatic Programmer's Guide")
|
# puts url_encode("Programming Ruby: The Pragmatic Programmer's Guide")
|
||||||
#
|
#
|
||||||
# _Generates_
|
# _Generates_
|
||||||
#
|
#
|
||||||
# Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
|
# Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
|
||||||
#
|
#
|
||||||
def url_encode(s)
|
def url_encode(s)
|
||||||
s.to_s.dup.force_encoding("ASCII-8BIT").gsub(/[^a-zA-Z0-9_\-.]/n) {
|
s.to_s.dup.force_encoding("ASCII-8BIT").gsub(/[^a-zA-Z0-9_\-.]/n) {
|
||||||
@ -971,7 +971,7 @@ class ERB
|
|||||||
#
|
#
|
||||||
module DefMethod
|
module DefMethod
|
||||||
public
|
public
|
||||||
# define _methodname_ as instance method of current module, using ERB object or eRuby file
|
# define _methodname_ as instance method of current module, using ERB object or eRuby file
|
||||||
def def_erb_method(methodname, erb_or_fname)
|
def def_erb_method(methodname, erb_or_fname)
|
||||||
if erb_or_fname.kind_of? String
|
if erb_or_fname.kind_of? String
|
||||||
fname = erb_or_fname
|
fname = erb_or_fname
|
||||||
|
@ -38,7 +38,7 @@ module Find
|
|||||||
paths.collect!{|d| raise Errno::ENOENT unless File.exist?(d); d.dup}
|
paths.collect!{|d| raise Errno::ENOENT unless File.exist?(d); d.dup}
|
||||||
while file = paths.shift
|
while file = paths.shift
|
||||||
catch(:prune) do
|
catch(:prune) do
|
||||||
yield file.dup.taint
|
yield file.dup.taint
|
||||||
begin
|
begin
|
||||||
s = File.lstat(file)
|
s = File.lstat(file)
|
||||||
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
|
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#
|
#
|
||||||
# forwardable.rb -
|
# forwardable.rb -
|
||||||
# $Release Version: 1.1$
|
# $Release Version: 1.1$
|
||||||
# $Revision$
|
# $Revision$
|
||||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||||
# original definition by delegator.rb
|
# original definition by delegator.rb
|
||||||
# Revised by Daniel J. Berger with suggestions from Florian Gross.
|
# Revised by Daniel J. Berger with suggestions from Florian Gross.
|
||||||
#
|
#
|
||||||
# Documentation by James Edward Gray II and Gavin Sinclair
|
# Documentation by James Edward Gray II and Gavin Sinclair
|
||||||
@ -84,7 +84,7 @@
|
|||||||
# def_delegator :Implementation, :service
|
# def_delegator :Implementation, :service
|
||||||
#
|
#
|
||||||
# class Implementation
|
# class Implementation
|
||||||
# def service...
|
# def service...
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
@ -178,12 +178,12 @@ module Forwardable
|
|||||||
def def_instance_delegator(accessor, method, ali = method)
|
def def_instance_delegator(accessor, method, ali = method)
|
||||||
line_no = __LINE__; str = %{
|
line_no = __LINE__; str = %{
|
||||||
def #{ali}(*args, &block)
|
def #{ali}(*args, &block)
|
||||||
begin
|
begin
|
||||||
#{accessor}.__send__(:#{method}, *args, &block)
|
#{accessor}.__send__(:#{method}, *args, &block)
|
||||||
rescue Exception
|
rescue Exception
|
||||||
$@.delete_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug
|
$@.delete_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug
|
||||||
::Kernel::raise
|
::Kernel::raise
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
# If it's not a class or module, it's an instance
|
# If it's not a class or module, it's an instance
|
||||||
@ -248,12 +248,12 @@ module SingleForwardable
|
|||||||
def def_single_delegator(accessor, method, ali = method)
|
def def_single_delegator(accessor, method, ali = method)
|
||||||
str = %{
|
str = %{
|
||||||
def #{ali}(*args, &block)
|
def #{ali}(*args, &block)
|
||||||
begin
|
begin
|
||||||
#{accessor}.__send__(:#{method}, *args, &block)
|
#{accessor}.__send__(:#{method}, *args, &block)
|
||||||
rescue Exception
|
rescue Exception
|
||||||
$@.delete_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug
|
$@.delete_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug
|
||||||
::Kernel::raise
|
::Kernel::raise
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ class GetoptLong
|
|||||||
if @status != STATUS_YET
|
if @status != STATUS_YET
|
||||||
set_error(ArgumentError, "argument error")
|
set_error(ArgumentError, "argument error")
|
||||||
raise RuntimeError,
|
raise RuntimeError,
|
||||||
"invoke ordering=, but option processing has already started"
|
"invoke ordering=, but option processing has already started"
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -273,7 +273,7 @@ class GetoptLong
|
|||||||
#
|
#
|
||||||
if @status != STATUS_YET
|
if @status != STATUS_YET
|
||||||
raise RuntimeError,
|
raise RuntimeError,
|
||||||
"invoke set_options, but option processing has already started"
|
"invoke set_options, but option processing has already started"
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -284,7 +284,7 @@ class GetoptLong
|
|||||||
|
|
||||||
arguments.each do |arg|
|
arguments.each do |arg|
|
||||||
if !arg.is_a?(Array)
|
if !arg.is_a?(Array)
|
||||||
raise ArgumentError, "the option list contains non-Array argument"
|
raise ArgumentError, "the option list contains non-Array argument"
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -292,44 +292,44 @@ class GetoptLong
|
|||||||
#
|
#
|
||||||
argument_flag = nil
|
argument_flag = nil
|
||||||
arg.each do |i|
|
arg.each do |i|
|
||||||
if ARGUMENT_FLAGS.include?(i)
|
if ARGUMENT_FLAGS.include?(i)
|
||||||
if argument_flag != nil
|
if argument_flag != nil
|
||||||
raise ArgumentError, "too many argument-flags"
|
raise ArgumentError, "too many argument-flags"
|
||||||
end
|
end
|
||||||
argument_flag = i
|
argument_flag = i
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
raise ArgumentError, "no argument-flag" if argument_flag == nil
|
raise ArgumentError, "no argument-flag" if argument_flag == nil
|
||||||
|
|
||||||
canonical_name = nil
|
canonical_name = nil
|
||||||
arg.each do |i|
|
arg.each do |i|
|
||||||
#
|
#
|
||||||
# Check an option name.
|
# Check an option name.
|
||||||
#
|
#
|
||||||
next if i == argument_flag
|
next if i == argument_flag
|
||||||
begin
|
begin
|
||||||
if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/
|
if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/
|
||||||
raise ArgumentError, "an invalid option `#{i}'"
|
raise ArgumentError, "an invalid option `#{i}'"
|
||||||
end
|
end
|
||||||
if (@canonical_names.include?(i))
|
if (@canonical_names.include?(i))
|
||||||
raise ArgumentError, "option redefined `#{i}'"
|
raise ArgumentError, "option redefined `#{i}'"
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
@canonical_names.clear
|
@canonical_names.clear
|
||||||
@argument_flags.clear
|
@argument_flags.clear
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Register the option (`i') to the `@canonical_names' and
|
# Register the option (`i') to the `@canonical_names' and
|
||||||
# `@canonical_names' Hashes.
|
# `@canonical_names' Hashes.
|
||||||
#
|
#
|
||||||
if canonical_name == nil
|
if canonical_name == nil
|
||||||
canonical_name = i
|
canonical_name = i
|
||||||
end
|
end
|
||||||
@canonical_names[i] = canonical_name
|
@canonical_names[i] = canonical_name
|
||||||
@argument_flags[i] = argument_flag
|
@argument_flags[i] = argument_flag
|
||||||
end
|
end
|
||||||
raise ArgumentError, "no option name" if canonical_name == nil
|
raise ArgumentError, "no option name" if canonical_name == nil
|
||||||
end
|
end
|
||||||
@ -447,17 +447,17 @@ class GetoptLong
|
|||||||
return nil
|
return nil
|
||||||
elsif @ordering == PERMUTE
|
elsif @ordering == PERMUTE
|
||||||
while 0 < ARGV.length && ARGV[0] !~ /^-./
|
while 0 < ARGV.length && ARGV[0] !~ /^-./
|
||||||
@non_option_arguments.push(ARGV.shift)
|
@non_option_arguments.push(ARGV.shift)
|
||||||
end
|
end
|
||||||
if ARGV.length == 0
|
if ARGV.length == 0
|
||||||
terminate
|
terminate
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
argument = ARGV.shift
|
argument = ARGV.shift
|
||||||
elsif @ordering == REQUIRE_ORDER
|
elsif @ordering == REQUIRE_ORDER
|
||||||
if (ARGV[0] !~ /^-./)
|
if (ARGV[0] !~ /^-./)
|
||||||
terminate
|
terminate
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
argument = ARGV.shift
|
argument = ARGV.shift
|
||||||
else
|
else
|
||||||
@ -482,49 +482,49 @@ class GetoptLong
|
|||||||
#
|
#
|
||||||
pattern = $1
|
pattern = $1
|
||||||
if @canonical_names.include?(pattern)
|
if @canonical_names.include?(pattern)
|
||||||
option_name = pattern
|
option_name = pattern
|
||||||
else
|
else
|
||||||
#
|
#
|
||||||
# The option `option_name' is not registered in `@canonical_names'.
|
# The option `option_name' is not registered in `@canonical_names'.
|
||||||
# It may be an abbreviated.
|
# It may be an abbreviated.
|
||||||
#
|
#
|
||||||
matches = []
|
matches = []
|
||||||
@canonical_names.each_key do |key|
|
@canonical_names.each_key do |key|
|
||||||
if key.index(pattern) == 0
|
if key.index(pattern) == 0
|
||||||
option_name = key
|
option_name = key
|
||||||
matches << key
|
matches << key
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if 2 <= matches.length
|
if 2 <= matches.length
|
||||||
set_error(AmbiguousOption, "option `#{argument}' is ambiguous between #{matches.join(', ')}")
|
set_error(AmbiguousOption, "option `#{argument}' is ambiguous between #{matches.join(', ')}")
|
||||||
elsif matches.length == 0
|
elsif matches.length == 0
|
||||||
set_error(InvalidOption, "unrecognized option `#{argument}'")
|
set_error(InvalidOption, "unrecognized option `#{argument}'")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check an argument to the option.
|
# Check an argument to the option.
|
||||||
#
|
#
|
||||||
if @argument_flags[option_name] == REQUIRED_ARGUMENT
|
if @argument_flags[option_name] == REQUIRED_ARGUMENT
|
||||||
if argument =~ /=(.*)$/
|
if argument =~ /=(.*)$/
|
||||||
option_argument = $1
|
option_argument = $1
|
||||||
elsif 0 < ARGV.length
|
elsif 0 < ARGV.length
|
||||||
option_argument = ARGV.shift
|
option_argument = ARGV.shift
|
||||||
else
|
else
|
||||||
set_error(MissingArgument,
|
set_error(MissingArgument,
|
||||||
"option `#{argument}' requires an argument")
|
"option `#{argument}' requires an argument")
|
||||||
end
|
end
|
||||||
elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
|
elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
|
||||||
if argument =~ /=(.*)$/
|
if argument =~ /=(.*)$/
|
||||||
option_argument = $1
|
option_argument = $1
|
||||||
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
||||||
option_argument = ARGV.shift
|
option_argument = ARGV.shift
|
||||||
else
|
else
|
||||||
option_argument = ''
|
option_argument = ''
|
||||||
end
|
end
|
||||||
elsif argument =~ /=(.*)$/
|
elsif argument =~ /=(.*)$/
|
||||||
set_error(NeedlessArgument,
|
set_error(NeedlessArgument,
|
||||||
"option `#{option_name}' doesn't allow an argument")
|
"option `#{option_name}' doesn't allow an argument")
|
||||||
end
|
end
|
||||||
|
|
||||||
elsif argument =~ /^(-(.))(.*)/
|
elsif argument =~ /^(-(.))(.*)/
|
||||||
@ -536,40 +536,40 @@ class GetoptLong
|
|||||||
option_name, ch, @rest_singles = $1, $2, $3
|
option_name, ch, @rest_singles = $1, $2, $3
|
||||||
|
|
||||||
if @canonical_names.include?(option_name)
|
if @canonical_names.include?(option_name)
|
||||||
#
|
#
|
||||||
# The option `option_name' is found in `@canonical_names'.
|
# The option `option_name' is found in `@canonical_names'.
|
||||||
# Check its argument.
|
# Check its argument.
|
||||||
#
|
#
|
||||||
if @argument_flags[option_name] == REQUIRED_ARGUMENT
|
if @argument_flags[option_name] == REQUIRED_ARGUMENT
|
||||||
if 0 < @rest_singles.length
|
if 0 < @rest_singles.length
|
||||||
option_argument = @rest_singles
|
option_argument = @rest_singles
|
||||||
@rest_singles = ''
|
@rest_singles = ''
|
||||||
elsif 0 < ARGV.length
|
elsif 0 < ARGV.length
|
||||||
option_argument = ARGV.shift
|
option_argument = ARGV.shift
|
||||||
else
|
else
|
||||||
# 1003.2 specifies the format of this message.
|
# 1003.2 specifies the format of this message.
|
||||||
set_error(MissingArgument, "option requires an argument -- #{ch}")
|
set_error(MissingArgument, "option requires an argument -- #{ch}")
|
||||||
end
|
end
|
||||||
elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
|
elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
|
||||||
if 0 < @rest_singles.length
|
if 0 < @rest_singles.length
|
||||||
option_argument = @rest_singles
|
option_argument = @rest_singles
|
||||||
@rest_singles = ''
|
@rest_singles = ''
|
||||||
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
||||||
option_argument = ARGV.shift
|
option_argument = ARGV.shift
|
||||||
else
|
else
|
||||||
option_argument = ''
|
option_argument = ''
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
#
|
#
|
||||||
# This is an invalid option.
|
# This is an invalid option.
|
||||||
# 1003.2 specifies the format of this message.
|
# 1003.2 specifies the format of this message.
|
||||||
#
|
#
|
||||||
if ENV.include?('POSIXLY_CORRECT')
|
if ENV.include?('POSIXLY_CORRECT')
|
||||||
set_error(InvalidOption, "invalid option -- #{ch}")
|
set_error(InvalidOption, "invalid option -- #{ch}")
|
||||||
else
|
else
|
||||||
set_error(InvalidOption, "invalid option -- #{ch}")
|
set_error(InvalidOption, "invalid option -- #{ch}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
#
|
#
|
||||||
|
@ -72,17 +72,17 @@ end
|
|||||||
#
|
#
|
||||||
# ipaddr1 = IPAddr.new "3ffe:505:2::1"
|
# ipaddr1 = IPAddr.new "3ffe:505:2::1"
|
||||||
#
|
#
|
||||||
# p ipaddr1 #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
|
# p ipaddr1 #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
|
||||||
#
|
#
|
||||||
# p ipaddr1.to_s #=> "3ffe:505:2::1"
|
# p ipaddr1.to_s #=> "3ffe:505:2::1"
|
||||||
#
|
#
|
||||||
# ipaddr2 = ipaddr1.mask(48) #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>
|
# ipaddr2 = ipaddr1.mask(48) #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>
|
||||||
#
|
#
|
||||||
# p ipaddr2.to_s #=> "3ffe:505:2::"
|
# p ipaddr2.to_s #=> "3ffe:505:2::"
|
||||||
#
|
#
|
||||||
# ipaddr3 = IPAddr.new "192.168.2.0/24"
|
# ipaddr3 = IPAddr.new "192.168.2.0/24"
|
||||||
#
|
#
|
||||||
# p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
|
# p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
|
||||||
|
|
||||||
class IPAddr
|
class IPAddr
|
||||||
|
|
||||||
@ -157,13 +157,13 @@ class IPAddr
|
|||||||
# net1 = IPAddr.new("192.168.2.0/24")
|
# net1 = IPAddr.new("192.168.2.0/24")
|
||||||
# net2 = IPAddr.new("192.168.2.100")
|
# net2 = IPAddr.new("192.168.2.100")
|
||||||
# net3 = IPAddr.new("192.168.3.0")
|
# net3 = IPAddr.new("192.168.3.0")
|
||||||
# p net1.include?(net2) #=> true
|
# p net1.include?(net2) #=> true
|
||||||
# p net1.include?(net3) #=> false
|
# p net1.include?(net3) #=> false
|
||||||
def include?(other)
|
def include?(other)
|
||||||
other = coerce_other(other)
|
other = coerce_other(other)
|
||||||
if ipv4_mapped?
|
if ipv4_mapped?
|
||||||
if (@mask_addr >> 32) != 0xffffffffffffffffffffffff
|
if (@mask_addr >> 32) != 0xffffffffffffffffffffffff
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
mask_addr = (@mask_addr & IN4MASK)
|
mask_addr = (@mask_addr & IN4MASK)
|
||||||
addr = (@addr & IN4MASK)
|
addr = (@addr & IN4MASK)
|
||||||
@ -231,7 +231,7 @@ class IPAddr
|
|||||||
return [@addr].pack('N')
|
return [@addr].pack('N')
|
||||||
when Socket::AF_INET6
|
when Socket::AF_INET6
|
||||||
return (0..7).map { |i|
|
return (0..7).map { |i|
|
||||||
(@addr >> (112 - 16 * i)) & 0xffff
|
(@addr >> (112 - 16 * i)) & 0xffff
|
||||||
}.pack('n8')
|
}.pack('n8')
|
||||||
else
|
else
|
||||||
raise "unsupported address family"
|
raise "unsupported address family"
|
||||||
@ -372,7 +372,7 @@ class IPAddr
|
|||||||
raise "unsupported address family"
|
raise "unsupported address family"
|
||||||
end
|
end
|
||||||
return sprintf("#<%s: %s:%s/%s>", self.class.name,
|
return sprintf("#<%s: %s:%s/%s>", self.class.name,
|
||||||
af, _to_string(@addr), _to_string(@mask_addr))
|
af, _to_string(@addr), _to_string(@mask_addr))
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
@ -381,11 +381,11 @@ class IPAddr
|
|||||||
case family[0] ? family[0] : @family
|
case family[0] ? family[0] : @family
|
||||||
when Socket::AF_INET
|
when Socket::AF_INET
|
||||||
if addr < 0 || addr > IN4MASK
|
if addr < 0 || addr > IN4MASK
|
||||||
raise ArgumentError, "invalid address"
|
raise ArgumentError, "invalid address"
|
||||||
end
|
end
|
||||||
when Socket::AF_INET6
|
when Socket::AF_INET6
|
||||||
if addr < 0 || addr > IN6MASK
|
if addr < 0 || addr > IN6MASK
|
||||||
raise ArgumentError, "invalid address"
|
raise ArgumentError, "invalid address"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise ArgumentError, "unsupported address family"
|
raise ArgumentError, "unsupported address family"
|
||||||
@ -400,15 +400,15 @@ class IPAddr
|
|||||||
def mask!(mask)
|
def mask!(mask)
|
||||||
if mask.kind_of?(String)
|
if mask.kind_of?(String)
|
||||||
if mask =~ /^\d+$/
|
if mask =~ /^\d+$/
|
||||||
prefixlen = mask.to_i
|
prefixlen = mask.to_i
|
||||||
else
|
else
|
||||||
m = IPAddr.new(mask)
|
m = IPAddr.new(mask)
|
||||||
if m.family != @family
|
if m.family != @family
|
||||||
raise ArgumentError, "address family is not same"
|
raise ArgumentError, "address family is not same"
|
||||||
end
|
end
|
||||||
@mask_addr = m.to_i
|
@mask_addr = m.to_i
|
||||||
@addr &= @mask_addr
|
@addr &= @mask_addr
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
prefixlen = mask
|
prefixlen = mask
|
||||||
@ -416,13 +416,13 @@ class IPAddr
|
|||||||
case @family
|
case @family
|
||||||
when Socket::AF_INET
|
when Socket::AF_INET
|
||||||
if prefixlen < 0 || prefixlen > 32
|
if prefixlen < 0 || prefixlen > 32
|
||||||
raise ArgumentError, "invalid length"
|
raise ArgumentError, "invalid length"
|
||||||
end
|
end
|
||||||
masklen = 32 - prefixlen
|
masklen = 32 - prefixlen
|
||||||
@mask_addr = ((IN4MASK >> masklen) << masklen)
|
@mask_addr = ((IN4MASK >> masklen) << masklen)
|
||||||
when Socket::AF_INET6
|
when Socket::AF_INET6
|
||||||
if prefixlen < 0 || prefixlen > 128
|
if prefixlen < 0 || prefixlen > 128
|
||||||
raise ArgumentError, "invalid length"
|
raise ArgumentError, "invalid length"
|
||||||
end
|
end
|
||||||
masklen = 128 - prefixlen
|
masklen = 128 - prefixlen
|
||||||
@mask_addr = ((IN6MASK >> masklen) << masklen)
|
@mask_addr = ((IN6MASK >> masklen) << masklen)
|
||||||
@ -461,9 +461,9 @@ class IPAddr
|
|||||||
@mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
|
@mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
|
||||||
return
|
return
|
||||||
when Socket::AF_UNSPEC
|
when Socket::AF_UNSPEC
|
||||||
raise ArgumentError, "address family must be specified"
|
raise ArgumentError, "address family must be specified"
|
||||||
else
|
else
|
||||||
raise ArgumentError, "unsupported address family: #{family}"
|
raise ArgumentError, "unsupported address family: #{family}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
prefix, prefixlen = addr.split('/')
|
prefix, prefixlen = addr.split('/')
|
||||||
@ -473,9 +473,9 @@ class IPAddr
|
|||||||
end
|
end
|
||||||
# It seems AI_NUMERICHOST doesn't do the job.
|
# It seems AI_NUMERICHOST doesn't do the job.
|
||||||
#Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
|
#Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
|
||||||
# Socket::AI_NUMERICHOST)
|
# Socket::AI_NUMERICHOST)
|
||||||
begin
|
begin
|
||||||
IPSocket.getaddress(prefix) # test if address is valid
|
IPSocket.getaddress(prefix) # test if address is valid
|
||||||
rescue
|
rescue
|
||||||
raise ArgumentError, "invalid address"
|
raise ArgumentError, "invalid address"
|
||||||
end
|
end
|
||||||
@ -483,7 +483,7 @@ class IPAddr
|
|||||||
if family == Socket::AF_UNSPEC || family == Socket::AF_INET
|
if family == Socket::AF_UNSPEC || family == Socket::AF_INET
|
||||||
@addr = in_addr(prefix)
|
@addr = in_addr(prefix)
|
||||||
if @addr
|
if @addr
|
||||||
@family = Socket::AF_INET
|
@family = Socket::AF_INET
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if !@addr && (family == Socket::AF_UNSPEC || family == Socket::AF_INET6)
|
if !@addr && (family == Socket::AF_UNSPEC || family == Socket::AF_INET6)
|
||||||
@ -514,8 +514,8 @@ class IPAddr
|
|||||||
def in_addr(addr)
|
def in_addr(addr)
|
||||||
if addr =~ /^\d+\.\d+\.\d+\.\d+$/
|
if addr =~ /^\d+\.\d+\.\d+\.\d+$/
|
||||||
return addr.split('.').inject(0) { |i, s|
|
return addr.split('.').inject(0) { |i, s|
|
||||||
i << 8 | s.to_i
|
i << 8 | s.to_i
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@ -559,7 +559,7 @@ class IPAddr
|
|||||||
case @family
|
case @family
|
||||||
when Socket::AF_INET
|
when Socket::AF_INET
|
||||||
return (0..3).map { |i|
|
return (0..3).map { |i|
|
||||||
(@addr >> (8 * i)) & 0xff
|
(@addr >> (8 * i)) & 0xff
|
||||||
}.join('.')
|
}.join('.')
|
||||||
when Socket::AF_INET6
|
when Socket::AF_INET6
|
||||||
return ("%.32x" % @addr).reverse!.gsub!(/.(?!$)/, '\&.')
|
return ("%.32x" % @addr).reverse!.gsub!(/.(?!$)/, '\&.')
|
||||||
@ -572,7 +572,7 @@ class IPAddr
|
|||||||
case @family
|
case @family
|
||||||
when Socket::AF_INET
|
when Socket::AF_INET
|
||||||
return (0..3).map { |i|
|
return (0..3).map { |i|
|
||||||
(addr >> (24 - 8 * i)) & 0xff
|
(addr >> (24 - 8 * i)) & 0xff
|
||||||
}.join('.')
|
}.join('.')
|
||||||
when Socket::AF_INET6
|
when Socket::AF_INET6
|
||||||
return (("%.32x" % addr).gsub!(/.{4}(?!$)/, '\&:'))
|
return (("%.32x" % addr).gsub!(/.{4}(?!$)/, '\&:'))
|
||||||
@ -659,7 +659,7 @@ class TC_IPAddr < Test::Unit::TestCase
|
|||||||
["[192.168.1.2]/120"],
|
["[192.168.1.2]/120"],
|
||||||
].each { |args|
|
].each { |args|
|
||||||
assert_raises(ArgumentError) {
|
assert_raises(ArgumentError) {
|
||||||
IPAddr.new(*args)
|
IPAddr.new(*args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@ -760,7 +760,7 @@ class TC_Operator < Test::Unit::TestCase
|
|||||||
assert_equal("3ffe:505:2:1::", a.to_s)
|
assert_equal("3ffe:505:2:1::", a.to_s)
|
||||||
assert_equal("3ffe:505:2::", @a.to_s)
|
assert_equal("3ffe:505:2::", @a.to_s)
|
||||||
assert_equal("3ffe:505:2:1::",
|
assert_equal("3ffe:505:2:1::",
|
||||||
(@a | 0x00000000000000010000000000000000).to_s)
|
(@a | 0x00000000000000010000000000000000).to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_and
|
def test_and
|
||||||
|
290
lib/irb.rb
290
lib/irb.rb
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# irb.rb - irb main module
|
# irb.rb - irb main module
|
||||||
# $Release Version: 0.9.6 $
|
# $Release Version: 0.9.6 $
|
||||||
# $Revision$
|
# $Revision$
|
||||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
#
|
#
|
||||||
@ -67,12 +67,12 @@ module IRB
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
catch(:IRB_EXIT) do
|
catch(:IRB_EXIT) do
|
||||||
irb.eval_input
|
irb.eval_input
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
irb_at_exit
|
irb_at_exit
|
||||||
end
|
end
|
||||||
# print "\n"
|
# print "\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
def IRB.irb_at_exit
|
def IRB.irb_at_exit
|
||||||
@ -108,99 +108,99 @@ module IRB
|
|||||||
|
|
||||||
def eval_input
|
def eval_input
|
||||||
@scanner.set_prompt do
|
@scanner.set_prompt do
|
||||||
|ltype, indent, continue, line_no|
|
|ltype, indent, continue, line_no|
|
||||||
if ltype
|
if ltype
|
||||||
f = @context.prompt_s
|
f = @context.prompt_s
|
||||||
elsif continue
|
elsif continue
|
||||||
f = @context.prompt_c
|
f = @context.prompt_c
|
||||||
elsif indent > 0
|
elsif indent > 0
|
||||||
f = @context.prompt_n
|
f = @context.prompt_n
|
||||||
else
|
else
|
||||||
f = @context.prompt_i
|
f = @context.prompt_i
|
||||||
end
|
end
|
||||||
f = "" unless f
|
f = "" unless f
|
||||||
if @context.prompting?
|
if @context.prompting?
|
||||||
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
||||||
else
|
else
|
||||||
@context.io.prompt = p = ""
|
@context.io.prompt = p = ""
|
||||||
end
|
end
|
||||||
if @context.auto_indent_mode
|
if @context.auto_indent_mode
|
||||||
unless ltype
|
unless ltype
|
||||||
ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
|
ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
|
||||||
indent * 2 - p.size
|
indent * 2 - p.size
|
||||||
ind += 2 if continue
|
ind += 2 if continue
|
||||||
@context.io.prompt = p + " " * ind if ind > 0
|
@context.io.prompt = p + " " * ind if ind > 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@scanner.set_input(@context.io) do
|
@scanner.set_input(@context.io) do
|
||||||
signal_status(:IN_INPUT) do
|
signal_status(:IN_INPUT) do
|
||||||
if l = @context.io.gets
|
if l = @context.io.gets
|
||||||
print l if @context.verbose?
|
print l if @context.verbose?
|
||||||
else
|
else
|
||||||
if @context.ignore_eof? and @context.io.readable_atfer_eof?
|
if @context.ignore_eof? and @context.io.readable_atfer_eof?
|
||||||
l = "\n"
|
l = "\n"
|
||||||
if @context.verbose?
|
if @context.verbose?
|
||||||
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print "\n"
|
print "\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
l
|
l
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@scanner.each_top_level_statement do |line, line_no|
|
@scanner.each_top_level_statement do |line, line_no|
|
||||||
signal_status(:IN_EVAL) do
|
signal_status(:IN_EVAL) do
|
||||||
begin
|
begin
|
||||||
line.untaint
|
line.untaint
|
||||||
@context.evaluate(line, line_no)
|
@context.evaluate(line, line_no)
|
||||||
output_value if @context.echo?
|
output_value if @context.echo?
|
||||||
exc = nil
|
exc = nil
|
||||||
rescue Interrupt => exc
|
rescue Interrupt => exc
|
||||||
rescue SystemExit, SignalException
|
rescue SystemExit, SignalException
|
||||||
raise
|
raise
|
||||||
rescue Exception => exc
|
rescue Exception => exc
|
||||||
end
|
end
|
||||||
if exc
|
if exc
|
||||||
print exc.class, ": ", exc, "\n"
|
print exc.class, ": ", exc, "\n"
|
||||||
if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
||||||
!(SyntaxError === exc)
|
!(SyntaxError === exc)
|
||||||
irb_bug = true
|
irb_bug = true
|
||||||
else
|
else
|
||||||
irb_bug = false
|
irb_bug = false
|
||||||
end
|
end
|
||||||
|
|
||||||
messages = []
|
messages = []
|
||||||
lasts = []
|
lasts = []
|
||||||
levels = 0
|
levels = 0
|
||||||
for m in exc.backtrace
|
for m in exc.backtrace
|
||||||
m = @context.workspace.filter_backtrace(m) unless irb_bug
|
m = @context.workspace.filter_backtrace(m) unless irb_bug
|
||||||
if m
|
if m
|
||||||
if messages.size < @context.back_trace_limit
|
if messages.size < @context.back_trace_limit
|
||||||
messages.push "\tfrom "+m
|
messages.push "\tfrom "+m
|
||||||
else
|
else
|
||||||
lasts.push "\tfrom "+m
|
lasts.push "\tfrom "+m
|
||||||
if lasts.size > @context.back_trace_limit
|
if lasts.size > @context.back_trace_limit
|
||||||
lasts.shift
|
lasts.shift
|
||||||
levels += 1
|
levels += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
print messages.join("\n"), "\n"
|
print messages.join("\n"), "\n"
|
||||||
unless lasts.empty?
|
unless lasts.empty?
|
||||||
printf "... %d levels...\n", levels if levels > 0
|
printf "... %d levels...\n", levels if levels > 0
|
||||||
print lasts.join("\n")
|
print lasts.join("\n")
|
||||||
end
|
end
|
||||||
print "Maybe IRB bug!\n" if irb_bug
|
print "Maybe IRB bug!\n" if irb_bug
|
||||||
end
|
end
|
||||||
if $SAFE > 2
|
if $SAFE > 2
|
||||||
abort "Error: irb does not work for $SAFE level higher than 2"
|
abort "Error: irb does not work for $SAFE level higher than 2"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -208,19 +208,19 @@ module IRB
|
|||||||
@context.irb_path, back_path = path, @context.irb_path if path
|
@context.irb_path, back_path = path, @context.irb_path if path
|
||||||
@context.irb_name, back_name = name, @context.irb_name if name
|
@context.irb_name, back_name = name, @context.irb_name if name
|
||||||
begin
|
begin
|
||||||
yield back_path, back_name
|
yield back_path, back_name
|
||||||
ensure
|
ensure
|
||||||
@context.irb_path = back_path if path
|
@context.irb_path = back_path if path
|
||||||
@context.irb_name = back_name if name
|
@context.irb_name = back_name if name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def suspend_workspace(workspace)
|
def suspend_workspace(workspace)
|
||||||
@context.workspace, back_workspace = workspace, @context.workspace
|
@context.workspace, back_workspace = workspace, @context.workspace
|
||||||
begin
|
begin
|
||||||
yield back_workspace
|
yield back_workspace
|
||||||
ensure
|
ensure
|
||||||
@context.workspace = back_workspace
|
@context.workspace = back_workspace
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -228,39 +228,39 @@ module IRB
|
|||||||
back_io = @context.io
|
back_io = @context.io
|
||||||
@context.instance_eval{@io = input_method}
|
@context.instance_eval{@io = input_method}
|
||||||
begin
|
begin
|
||||||
yield back_io
|
yield back_io
|
||||||
ensure
|
ensure
|
||||||
@context.instance_eval{@io = back_io}
|
@context.instance_eval{@io = back_io}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def suspend_context(context)
|
def suspend_context(context)
|
||||||
@context, back_context = context, @context
|
@context, back_context = context, @context
|
||||||
begin
|
begin
|
||||||
yield back_context
|
yield back_context
|
||||||
ensure
|
ensure
|
||||||
@context = back_context
|
@context = back_context
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def signal_handle
|
def signal_handle
|
||||||
unless @context.ignore_sigint?
|
unless @context.ignore_sigint?
|
||||||
print "\nabort!\n" if @context.verbose?
|
print "\nabort!\n" if @context.verbose?
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
|
||||||
case @signal_status
|
case @signal_status
|
||||||
when :IN_INPUT
|
when :IN_INPUT
|
||||||
print "^C\n"
|
print "^C\n"
|
||||||
raise RubyLex::TerminateLineInput
|
raise RubyLex::TerminateLineInput
|
||||||
when :IN_EVAL
|
when :IN_EVAL
|
||||||
IRB.irb_abort(self)
|
IRB.irb_abort(self)
|
||||||
when :IN_LOAD
|
when :IN_LOAD
|
||||||
IRB.irb_abort(self, LoadAbort)
|
IRB.irb_abort(self, LoadAbort)
|
||||||
when :IN_IRB
|
when :IN_IRB
|
||||||
# ignore
|
# ignore
|
||||||
else
|
else
|
||||||
# ignore other cases as well
|
# ignore other cases as well
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -270,39 +270,39 @@ module IRB
|
|||||||
signal_status_back = @signal_status
|
signal_status_back = @signal_status
|
||||||
@signal_status = status
|
@signal_status = status
|
||||||
begin
|
begin
|
||||||
yield
|
yield
|
||||||
ensure
|
ensure
|
||||||
@signal_status = signal_status_back
|
@signal_status = signal_status_back
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def prompt(prompt, ltype, indent, line_no)
|
def prompt(prompt, ltype, indent, line_no)
|
||||||
p = prompt.dup
|
p = prompt.dup
|
||||||
p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
|
p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
|
||||||
case $2
|
case $2
|
||||||
when "N"
|
when "N"
|
||||||
@context.irb_name
|
@context.irb_name
|
||||||
when "m"
|
when "m"
|
||||||
@context.main.to_s
|
@context.main.to_s
|
||||||
when "M"
|
when "M"
|
||||||
@context.main.inspect
|
@context.main.inspect
|
||||||
when "l"
|
when "l"
|
||||||
ltype
|
ltype
|
||||||
when "i"
|
when "i"
|
||||||
if $1
|
if $1
|
||||||
format("%" + $1 + "d", indent)
|
format("%" + $1 + "d", indent)
|
||||||
else
|
else
|
||||||
indent.to_s
|
indent.to_s
|
||||||
end
|
end
|
||||||
when "n"
|
when "n"
|
||||||
if $1
|
if $1
|
||||||
format("%" + $1 + "d", line_no)
|
format("%" + $1 + "d", line_no)
|
||||||
else
|
else
|
||||||
line_no.to_s
|
line_no.to_s
|
||||||
end
|
end
|
||||||
when "%"
|
when "%"
|
||||||
"%"
|
"%"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
p
|
p
|
||||||
end
|
end
|
||||||
@ -314,14 +314,14 @@ module IRB
|
|||||||
def inspect
|
def inspect
|
||||||
ary = []
|
ary = []
|
||||||
for iv in instance_variables
|
for iv in instance_variables
|
||||||
case (iv = iv.to_s)
|
case (iv = iv.to_s)
|
||||||
when "@signal_status"
|
when "@signal_status"
|
||||||
ary.push format("%s=:%s", iv, @signal_status.id2name)
|
ary.push format("%s=:%s", iv, @signal_status.id2name)
|
||||||
when "@context"
|
when "@context"
|
||||||
ary.push format("%s=%s", iv, eval(iv).__to_s__)
|
ary.push format("%s=%s", iv, eval(iv).__to_s__)
|
||||||
else
|
else
|
||||||
ary.push format("%s=%s", iv, eval(iv))
|
ary.push format("%s=%s", iv, eval(iv))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
format("#<%s: %s>", self.class, ary.join(", "))
|
format("#<%s: %s>", self.class, ary.join(", "))
|
||||||
end
|
end
|
||||||
@ -335,16 +335,16 @@ module IRB
|
|||||||
for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
|
for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
|
||||||
case k
|
case k
|
||||||
when :MAIN_CONTEXT, :__TMP__EHV__
|
when :MAIN_CONTEXT, :__TMP__EHV__
|
||||||
array.push format("CONF[:%s]=...myself...", k.id2name)
|
array.push format("CONF[:%s]=...myself...", k.id2name)
|
||||||
when :PROMPT
|
when :PROMPT
|
||||||
s = v.collect{
|
s = v.collect{
|
||||||
|kk, vv|
|
|kk, vv|
|
||||||
ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
|
ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
|
||||||
format(":%s=>{%s}", kk.id2name, ss.join(", "))
|
format(":%s=>{%s}", kk.id2name, ss.join(", "))
|
||||||
}
|
}
|
||||||
array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
|
array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
|
||||||
else
|
else
|
||||||
array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
|
array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
array.join("\n")
|
array.join("\n")
|
||||||
|
@ -263,9 +263,9 @@ class Logger
|
|||||||
alias sev_threshold level
|
alias sev_threshold level
|
||||||
alias sev_threshold= level=
|
alias sev_threshold= level=
|
||||||
|
|
||||||
# Returns +true+ iff the current severity level allows for the printing of
|
# Returns +true+ iff the current severity level allows for the printing of
|
||||||
# +DEBUG+ messages.
|
# +DEBUG+ messages.
|
||||||
def debug?; @level <= DEBUG; end
|
def debug?; @level <= DEBUG; end
|
||||||
|
|
||||||
# Returns +true+ iff the current severity level allows for the printing of
|
# Returns +true+ iff the current severity level allows for the printing of
|
||||||
# +INFO+ messages.
|
# +INFO+ messages.
|
||||||
@ -312,7 +312,7 @@ class Logger
|
|||||||
@logdev = nil
|
@logdev = nil
|
||||||
if logdev
|
if logdev
|
||||||
@logdev = LogDevice.new(logdev, :shift_age => shift_age,
|
@logdev = LogDevice.new(logdev, :shift_age => shift_age,
|
||||||
:shift_size => shift_size)
|
:shift_size => shift_size)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -376,7 +376,7 @@ class Logger
|
|||||||
end
|
end
|
||||||
@logdev.write(
|
@logdev.write(
|
||||||
format_message(format_severity(severity), Time.now, progname, message))
|
format_message(format_severity(severity), Time.now, progname, message))
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
alias log add
|
alias log add
|
||||||
|
|
||||||
@ -478,7 +478,7 @@ class Logger
|
|||||||
@logdev.close if @logdev
|
@logdev.close if @logdev
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Severity label for logging. (max 5 char)
|
# Severity label for logging. (max 5 char)
|
||||||
SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY)
|
SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY)
|
||||||
@ -507,7 +507,7 @@ private
|
|||||||
msg2str(msg)]
|
msg2str(msg)]
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def format_datetime(time)
|
def format_datetime(time)
|
||||||
if @datetime_format.nil?
|
if @datetime_format.nil?
|
||||||
@ -523,7 +523,7 @@ private
|
|||||||
msg
|
msg
|
||||||
when ::Exception
|
when ::Exception
|
||||||
"#{ msg.message } (#{ msg.class })\n" <<
|
"#{ msg.message } (#{ msg.class })\n" <<
|
||||||
(msg.backtrace || []).join("\n")
|
(msg.backtrace || []).join("\n")
|
||||||
else
|
else
|
||||||
msg.inspect
|
msg.inspect
|
||||||
end
|
end
|
||||||
@ -585,7 +585,7 @@ private
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def open_logfile(filename)
|
def open_logfile(filename)
|
||||||
if (FileTest.exist?(filename))
|
if (FileTest.exist?(filename))
|
||||||
@ -791,7 +791,7 @@ private
|
|||||||
@log.add(severity, message, @appname, &block) if @log
|
@log.add(severity, message, @appname, &block) if @log
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def run
|
def run
|
||||||
# TODO: should be an NotImplementedError
|
# TODO: should be an NotImplementedError
|
||||||
|
116
lib/mkmf.rb
116
lib/mkmf.rb
@ -299,18 +299,18 @@ end
|
|||||||
|
|
||||||
def xsystem command, opts = nil
|
def xsystem command, opts = nil
|
||||||
varpat = /\$\((\w+)\)|\$\{(\w+)\}/
|
varpat = /\$\((\w+)\)|\$\{(\w+)\}/
|
||||||
if varpat =~ command
|
if varpat =~ command
|
||||||
vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
|
vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
|
||||||
command = command.dup
|
command = command.dup
|
||||||
nil while command.gsub!(varpat) {vars[$1||$2]}
|
nil while command.gsub!(varpat) {vars[$1||$2]}
|
||||||
end
|
end
|
||||||
Logging::open do
|
Logging::open do
|
||||||
puts command.quote
|
puts command.quote
|
||||||
if opts and opts[:werror]
|
if opts and opts[:werror]
|
||||||
result = nil
|
result = nil
|
||||||
Logging.postpone do |log|
|
Logging.postpone do |log|
|
||||||
result = (system(command) and File.zero?(log.path))
|
result = (system(command) and File.zero?(log.path))
|
||||||
""
|
""
|
||||||
end
|
end
|
||||||
result
|
result
|
||||||
else
|
else
|
||||||
@ -337,12 +337,12 @@ def log_src(src)
|
|||||||
Logging::message <<"EOM"
|
Logging::message <<"EOM"
|
||||||
checked program was:
|
checked program was:
|
||||||
/* begin */
|
/* begin */
|
||||||
EOM
|
EOM
|
||||||
src.each_with_index {|line, no| Logging::message fmt, no+1, line}
|
src.each_with_index {|line, no| Logging::message fmt, no+1, line}
|
||||||
Logging::message <<"EOM"
|
Logging::message <<"EOM"
|
||||||
/* end */
|
/* end */
|
||||||
|
|
||||||
EOM
|
EOM
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_tmpsrc(src)
|
def create_tmpsrc(src)
|
||||||
@ -410,7 +410,7 @@ def cc_command(opt="")
|
|||||||
'arch_hdrdir' => "#$arch_hdrdir",
|
'arch_hdrdir' => "#$arch_hdrdir",
|
||||||
'top_srcdir' => $top_srcdir.quote)
|
'top_srcdir' => $top_srcdir.quote)
|
||||||
RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
|
RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
|
||||||
conf)
|
conf)
|
||||||
end
|
end
|
||||||
|
|
||||||
def cpp_command(outfile, opt="")
|
def cpp_command(outfile, opt="")
|
||||||
@ -418,7 +418,7 @@ def cpp_command(outfile, opt="")
|
|||||||
'arch_hdrdir' => "#$arch_hdrdir",
|
'arch_hdrdir' => "#$arch_hdrdir",
|
||||||
'top_srcdir' => $top_srcdir.quote)
|
'top_srcdir' => $top_srcdir.quote)
|
||||||
RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
|
RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
|
||||||
conf)
|
conf)
|
||||||
end
|
end
|
||||||
|
|
||||||
def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
|
def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
|
||||||
@ -547,7 +547,7 @@ end
|
|||||||
def try_static_assert(expr, headers = nil, opt = "", &b)
|
def try_static_assert(expr, headers = nil, opt = "", &b)
|
||||||
headers = cpp_include(headers)
|
headers = cpp_include(headers)
|
||||||
try_compile(<<SRC, opt, &b)
|
try_compile(<<SRC, opt, &b)
|
||||||
#{headers}
|
#{headers}
|
||||||
/*top*/
|
/*top*/
|
||||||
int conftest_const[(#{expr}) ? 1 : -1];
|
int conftest_const[(#{expr}) ? 1 : -1];
|
||||||
SRC
|
SRC
|
||||||
@ -616,15 +616,15 @@ def try_func(func, libs, headers = nil, &b)
|
|||||||
decltype = proc {|x| "void ((*#{x})())"}
|
decltype = proc {|x| "void ((*#{x})())"}
|
||||||
end
|
end
|
||||||
try_link(<<"SRC", libs, &b) or
|
try_link(<<"SRC", libs, &b) or
|
||||||
#{headers}
|
#{headers}
|
||||||
/*top*/
|
/*top*/
|
||||||
#{MAIN_DOES_NOTHING}
|
#{MAIN_DOES_NOTHING}
|
||||||
int t() { #{decltype["volatile p"]}; p = (#{decltype[]})#{func}; return 0; }
|
int t() { #{decltype["volatile p"]}; p = (#{decltype[]})#{func}; return 0; }
|
||||||
SRC
|
SRC
|
||||||
call && try_link(<<"SRC", libs, &b)
|
call && try_link(<<"SRC", libs, &b)
|
||||||
#{headers}
|
#{headers}
|
||||||
/*top*/
|
/*top*/
|
||||||
#{MAIN_DOES_NOTHING}
|
#{MAIN_DOES_NOTHING}
|
||||||
int t() { #{func}(); return 0; }
|
int t() { #{func}(); return 0; }
|
||||||
SRC
|
SRC
|
||||||
end
|
end
|
||||||
@ -633,9 +633,9 @@ end
|
|||||||
def try_var(var, headers = nil, &b)
|
def try_var(var, headers = nil, &b)
|
||||||
headers = cpp_include(headers)
|
headers = cpp_include(headers)
|
||||||
try_compile(<<"SRC", &b)
|
try_compile(<<"SRC", &b)
|
||||||
#{headers}
|
#{headers}
|
||||||
/*top*/
|
/*top*/
|
||||||
#{MAIN_DOES_NOTHING}
|
#{MAIN_DOES_NOTHING}
|
||||||
int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
|
int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
|
||||||
SRC
|
SRC
|
||||||
end
|
end
|
||||||
@ -659,18 +659,18 @@ def egrep_cpp(pat, src, opt = "", &b)
|
|||||||
if Regexp === pat
|
if Regexp === pat
|
||||||
puts(" ruby -ne 'print if #{pat.inspect}'")
|
puts(" ruby -ne 'print if #{pat.inspect}'")
|
||||||
f.grep(pat) {|l|
|
f.grep(pat) {|l|
|
||||||
puts "#{f.lineno}: #{l}"
|
puts "#{f.lineno}: #{l}"
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
puts(" egrep '#{pat}'")
|
puts(" egrep '#{pat}'")
|
||||||
begin
|
begin
|
||||||
stdin = $stdin.dup
|
stdin = $stdin.dup
|
||||||
$stdin.reopen(f)
|
$stdin.reopen(f)
|
||||||
system("egrep", pat)
|
system("egrep", pat)
|
||||||
ensure
|
ensure
|
||||||
$stdin.reopen(stdin)
|
$stdin.reopen(stdin)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -867,11 +867,11 @@ def find_library(lib, func, *paths, &b)
|
|||||||
libs = append_library($libs, lib)
|
libs = append_library($libs, lib)
|
||||||
begin
|
begin
|
||||||
until r = try_func(func, libs, &b) or paths.empty?
|
until r = try_func(func, libs, &b) or paths.empty?
|
||||||
$LIBPATH = libpath | [paths.shift]
|
$LIBPATH = libpath | [paths.shift]
|
||||||
end
|
end
|
||||||
if r
|
if r
|
||||||
$libs = libs
|
$libs = libs
|
||||||
libpath = nil
|
libpath = nil
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
$LIBPATH = libpath if libpath
|
$LIBPATH = libpath if libpath
|
||||||
@ -999,9 +999,9 @@ end
|
|||||||
def have_struct_member(type, member, headers = nil, &b)
|
def have_struct_member(type, member, headers = nil, &b)
|
||||||
checking_for checking_message("#{type}.#{member}", headers) do
|
checking_for checking_message("#{type}.#{member}", headers) do
|
||||||
if try_compile(<<"SRC", &b)
|
if try_compile(<<"SRC", &b)
|
||||||
#{cpp_include(headers)}
|
#{cpp_include(headers)}
|
||||||
/*top*/
|
/*top*/
|
||||||
#{MAIN_DOES_NOTHING}
|
#{MAIN_DOES_NOTHING}
|
||||||
int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
|
int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
|
||||||
SRC
|
SRC
|
||||||
$defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp))
|
$defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp))
|
||||||
@ -1019,7 +1019,7 @@ end
|
|||||||
#
|
#
|
||||||
def try_type(type, headers = nil, opt = "", &b)
|
def try_type(type, headers = nil, opt = "", &b)
|
||||||
if try_compile(<<"SRC", opt, &b)
|
if try_compile(<<"SRC", opt, &b)
|
||||||
#{cpp_include(headers)}
|
#{cpp_include(headers)}
|
||||||
/*top*/
|
/*top*/
|
||||||
typedef #{type} conftest_type;
|
typedef #{type} conftest_type;
|
||||||
int conftestval[sizeof(conftest_type)?1:-1];
|
int conftestval[sizeof(conftest_type)?1:-1];
|
||||||
@ -1077,7 +1077,7 @@ end
|
|||||||
def try_const(const, headers = nil, opt = "", &b)
|
def try_const(const, headers = nil, opt = "", &b)
|
||||||
const, type = *const
|
const, type = *const
|
||||||
if try_compile(<<"SRC", opt, &b)
|
if try_compile(<<"SRC", opt, &b)
|
||||||
#{cpp_include(headers)}
|
#{cpp_include(headers)}
|
||||||
/*top*/
|
/*top*/
|
||||||
typedef #{type || 'int'} conftest_type;
|
typedef #{type || 'int'} conftest_type;
|
||||||
conftest_type conftestval = #{type ? '' : '(int)'}#{const};
|
conftest_type conftestval = #{type ? '' : '(int)'}#{const};
|
||||||
@ -1217,18 +1217,18 @@ def convertible_int(type, headers = nil, opts = nil, &b)
|
|||||||
u = "unsigned " if signed > 0
|
u = "unsigned " if signed > 0
|
||||||
prelude << "extern rbcv_typedef_ foo();"
|
prelude << "extern rbcv_typedef_ foo();"
|
||||||
compat = UNIVERSAL_INTS.find {|t|
|
compat = UNIVERSAL_INTS.find {|t|
|
||||||
try_compile([prelude, "extern #{u}#{t} foo();"].join("\n"), opts, :werror=>true, &b)
|
try_compile([prelude, "extern #{u}#{t} foo();"].join("\n"), opts, :werror=>true, &b)
|
||||||
}
|
}
|
||||||
if compat
|
if compat
|
||||||
macname ||= type.sub(/_(?=t\z)/, '').tr_cpp
|
macname ||= type.sub(/_(?=t\z)/, '').tr_cpp
|
||||||
conv = (compat == "long long" ? "LL" : compat.upcase)
|
conv = (compat == "long long" ? "LL" : compat.upcase)
|
||||||
compat = "#{u}#{compat}"
|
compat = "#{u}#{compat}"
|
||||||
$defs.push(format("-DTYPEOF_%s=%s", type.tr_cpp, compat.quote))
|
$defs.push(format("-DTYPEOF_%s=%s", type.tr_cpp, compat.quote))
|
||||||
$defs.push(format("-DPRI_%s_PREFIX=PRI_%s_PREFIX", macname, conv))
|
$defs.push(format("-DPRI_%s_PREFIX=PRI_%s_PREFIX", macname, conv))
|
||||||
conv = (u ? "U" : "") + conv
|
conv = (u ? "U" : "") + conv
|
||||||
$defs.push(format("-D%s2NUM=%s2NUM", macname, conv))
|
$defs.push(format("-D%s2NUM=%s2NUM", macname, conv))
|
||||||
$defs.push(format("-DNUM2%s=NUM2%s", macname, conv))
|
$defs.push(format("-DNUM2%s=NUM2%s", macname, conv))
|
||||||
compat
|
compat
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1239,10 +1239,10 @@ end
|
|||||||
# pointer.
|
# pointer.
|
||||||
def scalar_ptr_type?(type, member = nil, headers = nil, &b)
|
def scalar_ptr_type?(type, member = nil, headers = nil, &b)
|
||||||
try_compile(<<"SRC", &b) # pointer
|
try_compile(<<"SRC", &b) # pointer
|
||||||
#{cpp_include(headers)}
|
#{cpp_include(headers)}
|
||||||
/*top*/
|
/*top*/
|
||||||
volatile #{type} conftestval;
|
volatile #{type} conftestval;
|
||||||
#{MAIN_DOES_NOTHING}
|
#{MAIN_DOES_NOTHING}
|
||||||
int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
|
int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
|
||||||
SRC
|
SRC
|
||||||
end
|
end
|
||||||
@ -1251,10 +1251,10 @@ end
|
|||||||
# pointer.
|
# pointer.
|
||||||
def scalar_type?(type, member = nil, headers = nil, &b)
|
def scalar_type?(type, member = nil, headers = nil, &b)
|
||||||
try_compile(<<"SRC", &b) # pointer
|
try_compile(<<"SRC", &b) # pointer
|
||||||
#{cpp_include(headers)}
|
#{cpp_include(headers)}
|
||||||
/*top*/
|
/*top*/
|
||||||
volatile #{type} conftestval;
|
volatile #{type} conftestval;
|
||||||
#{MAIN_DOES_NOTHING}
|
#{MAIN_DOES_NOTHING}
|
||||||
int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
|
int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
|
||||||
SRC
|
SRC
|
||||||
end
|
end
|
||||||
@ -1266,7 +1266,7 @@ def have_typeof?
|
|||||||
$typeof = %w[__typeof__ typeof].find do |t|
|
$typeof = %w[__typeof__ typeof].find do |t|
|
||||||
try_compile(<<SRC)
|
try_compile(<<SRC)
|
||||||
int rbcv_foo;
|
int rbcv_foo;
|
||||||
#{t}(rbcv_foo) rbcv_bar;
|
#{t}(rbcv_foo) rbcv_bar;
|
||||||
SRC
|
SRC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1644,7 +1644,7 @@ ECHO1 = $(V:1=@:)
|
|||||||
ECHO = $(ECHO1:0=@echo)
|
ECHO = $(ECHO1:0=@echo)
|
||||||
|
|
||||||
#### Start of system configuration section. ####
|
#### Start of system configuration section. ####
|
||||||
#{"top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/") if $extmk}
|
#{"top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/") if $extmk}
|
||||||
srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2])}.quote}
|
srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2])}.quote}
|
||||||
topdir = #{mkintpath($extmk ? CONFIG["topdir"] : $topdir).quote}
|
topdir = #{mkintpath($extmk ? CONFIG["topdir"] : $topdir).quote}
|
||||||
hdrdir = #{mkintpath(CONFIG["hdrdir"]).quote}
|
hdrdir = #{mkintpath(CONFIG["hdrdir"]).quote}
|
||||||
@ -1730,7 +1730,7 @@ preload = #{defined?($preload) && $preload ? $preload.join(' ') : ''}
|
|||||||
x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
|
x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
|
||||||
"!ifndef " + $1 + "\n" +
|
"!ifndef " + $1 + "\n" +
|
||||||
$& +
|
$& +
|
||||||
"!endif\n"
|
"!endif\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -2006,7 +2006,7 @@ static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
|
|||||||
mfile.print "#{dest}: #{f}\n\t@-$(MAKEDIRS) $(@D#{sep})\n"
|
mfile.print "#{dest}: #{f}\n\t@-$(MAKEDIRS) $(@D#{sep})\n"
|
||||||
mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} $(@D#{sep})\n"
|
mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} $(@D#{sep})\n"
|
||||||
if defined?($installed_list)
|
if defined?($installed_list)
|
||||||
mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
|
mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -2020,17 +2020,17 @@ static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
|
|||||||
files = install_files(mfile, i, nil, srcprefix) or next
|
files = install_files(mfile, i, nil, srcprefix) or next
|
||||||
for dir, *files in files
|
for dir, *files in files
|
||||||
unless dirs.include?(dir)
|
unless dirs.include?(dir)
|
||||||
dirs << dir
|
dirs << dir
|
||||||
mfile.print "pre-install-rb#{sfx}: #{dir}\n"
|
mfile.print "pre-install-rb#{sfx}: #{dir}\n"
|
||||||
end
|
end
|
||||||
for f in files
|
for f in files
|
||||||
dest = "#{dir}/#{File.basename(f)}"
|
dest = "#{dir}/#{File.basename(f)}"
|
||||||
mfile.print("install-rb#{sfx}: #{dest} #{dir}\n")
|
mfile.print("install-rb#{sfx}: #{dest} #{dir}\n")
|
||||||
mfile.print("#{dest}: #{f}\n")
|
mfile.print("#{dest}: #{f}\n")
|
||||||
mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $(@D#{sep})\n")
|
mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $(@D#{sep})\n")
|
||||||
if defined?($installed_list) and !$extout
|
if defined?($installed_list) and !$extout
|
||||||
mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
|
mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
|
||||||
end
|
end
|
||||||
if $extout
|
if $extout
|
||||||
mfile.print("clean-rb#{sfx}::\n")
|
mfile.print("clean-rb#{sfx}::\n")
|
||||||
mfile.print("\t@-$(RM) #{fseprepl[dest]}\n")
|
mfile.print("\t@-$(RM) #{fseprepl[dest]}\n")
|
||||||
|
@ -109,7 +109,7 @@ module MonitorMixin
|
|||||||
#
|
#
|
||||||
def wait_while
|
def wait_while
|
||||||
while yield
|
while yield
|
||||||
wait
|
wait
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ module MonitorMixin
|
|||||||
#
|
#
|
||||||
def wait_until
|
def wait_until
|
||||||
until yield
|
until yield
|
||||||
wait
|
wait
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
#
|
#
|
||||||
# mutex_m.rb -
|
# mutex_m.rb -
|
||||||
# $Release Version: 3.0$
|
# $Release Version: 3.0$
|
||||||
# $Revision: 1.7 $
|
# $Revision: 1.7 $
|
||||||
# Original from mutex.rb
|
# Original from mutex.rb
|
||||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||||
# modified by matz
|
# modified by matz
|
||||||
# patched by akira yamada
|
# patched by akira yamada
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
# Usage:
|
# Usage:
|
||||||
# require "mutex_m.rb"
|
# require "mutex_m.rb"
|
||||||
# obj = Object.new
|
# obj = Object.new
|
||||||
# obj.extend Mutex_m
|
# obj.extend Mutex_m
|
||||||
# ...
|
# ...
|
||||||
# extended object can be handled like Mutex
|
# extended object can be handled like Mutex
|
||||||
# or
|
# or
|
||||||
# class Foo
|
# class Foo
|
||||||
# include Mutex_m
|
# include Mutex_m
|
||||||
# ...
|
# ...
|
||||||
# end
|
# end
|
||||||
# obj = Foo.new
|
# obj = Foo.new
|
||||||
# this obj can be handled like Mutex
|
# this obj can be handled like Mutex
|
||||||
#
|
#
|
||||||
|
|
||||||
require 'thread'
|
require 'thread'
|
||||||
@ -48,11 +48,11 @@ module Mutex_m
|
|||||||
|
|
||||||
def mu_extended
|
def mu_extended
|
||||||
unless (defined? locked? and
|
unless (defined? locked? and
|
||||||
defined? lock and
|
defined? lock and
|
||||||
defined? unlock and
|
defined? unlock and
|
||||||
defined? try_lock and
|
defined? try_lock and
|
||||||
defined? synchronize)
|
defined? synchronize)
|
||||||
Mutex_m.define_aliases(singleton_class)
|
Mutex_m.define_aliases(singleton_class)
|
||||||
end
|
end
|
||||||
mu_initialize
|
mu_initialize
|
||||||
end
|
end
|
||||||
|
336
lib/net/ftp.rb
336
lib/net/ftp.rb
@ -136,10 +136,10 @@ module Net
|
|||||||
@sock = NullSocket.new
|
@sock = NullSocket.new
|
||||||
@logged_in = false
|
@logged_in = false
|
||||||
if host
|
if host
|
||||||
connect(host)
|
connect(host)
|
||||||
if user
|
if user
|
||||||
login(user, passwd, acct)
|
login(user, passwd, acct)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -197,10 +197,10 @@ module Net
|
|||||||
# else a TCPSocket is returned.
|
# else a TCPSocket is returned.
|
||||||
def open_socket(host, port)
|
def open_socket(host, port)
|
||||||
if defined? SOCKSSocket and ENV["SOCKS_SERVER"]
|
if defined? SOCKSSocket and ENV["SOCKS_SERVER"]
|
||||||
@passive = true
|
@passive = true
|
||||||
return SOCKSSocket.open(host, port)
|
return SOCKSSocket.open(host, port)
|
||||||
else
|
else
|
||||||
return TCPSocket.open(host, port)
|
return TCPSocket.open(host, port)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private :open_socket
|
private :open_socket
|
||||||
@ -213,11 +213,11 @@ module Net
|
|||||||
#
|
#
|
||||||
def connect(host, port = FTP_PORT)
|
def connect(host, port = FTP_PORT)
|
||||||
if @debug_mode
|
if @debug_mode
|
||||||
print "connect: ", host, ", ", port, "\n"
|
print "connect: ", host, ", ", port, "\n"
|
||||||
end
|
end
|
||||||
synchronize do
|
synchronize do
|
||||||
@sock = open_socket(host, port)
|
@sock = open_socket(host, port)
|
||||||
voidresp
|
voidresp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -226,10 +226,10 @@ module Net
|
|||||||
#
|
#
|
||||||
def set_socket(sock, get_greeting = true)
|
def set_socket(sock, get_greeting = true)
|
||||||
synchronize do
|
synchronize do
|
||||||
@sock = sock
|
@sock = sock
|
||||||
if get_greeting
|
if get_greeting
|
||||||
voidresp
|
voidresp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -237,9 +237,9 @@ module Net
|
|||||||
# then the contents of the password are cleaned from the string using "*"
|
# then the contents of the password are cleaned from the string using "*"
|
||||||
def sanitize(s)
|
def sanitize(s)
|
||||||
if s =~ /^PASS /i
|
if s =~ /^PASS /i
|
||||||
return s[0, 5] + "*" * (s.length - 5)
|
return s[0, 5] + "*" * (s.length - 5)
|
||||||
else
|
else
|
||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private :sanitize
|
private :sanitize
|
||||||
@ -248,7 +248,7 @@ module Net
|
|||||||
# and writes it to the socket.
|
# and writes it to the socket.
|
||||||
def putline(line)
|
def putline(line)
|
||||||
if @debug_mode
|
if @debug_mode
|
||||||
print "put: ", sanitize(line), "\n"
|
print "put: ", sanitize(line), "\n"
|
||||||
end
|
end
|
||||||
line = line + CRLF
|
line = line + CRLF
|
||||||
@sock.write(line)
|
@sock.write(line)
|
||||||
@ -261,7 +261,7 @@ module Net
|
|||||||
line = @sock.readline # if get EOF, raise EOFError
|
line = @sock.readline # if get EOF, raise EOFError
|
||||||
line.sub!(/(\r\n|\n|\r)\z/n, "")
|
line.sub!(/(\r\n|\n|\r)\z/n, "")
|
||||||
if @debug_mode
|
if @debug_mode
|
||||||
print "get: ", sanitize(line), "\n"
|
print "get: ", sanitize(line), "\n"
|
||||||
end
|
end
|
||||||
return line
|
return line
|
||||||
end
|
end
|
||||||
@ -272,11 +272,11 @@ module Net
|
|||||||
line = getline
|
line = getline
|
||||||
buff = line
|
buff = line
|
||||||
if line[3] == ?-
|
if line[3] == ?-
|
||||||
code = line[0, 3]
|
code = line[0, 3]
|
||||||
begin
|
begin
|
||||||
line = getline
|
line = getline
|
||||||
buff << "\n" << line
|
buff << "\n" << line
|
||||||
end until line[0, 3] == code and line[3] != ?-
|
end until line[0, 3] == code and line[3] != ?-
|
||||||
end
|
end
|
||||||
return buff << "\n"
|
return buff << "\n"
|
||||||
end
|
end
|
||||||
@ -290,13 +290,13 @@ module Net
|
|||||||
@last_response_code = @last_response[0, 3]
|
@last_response_code = @last_response[0, 3]
|
||||||
case @last_response_code
|
case @last_response_code
|
||||||
when /\A[123]/
|
when /\A[123]/
|
||||||
return @last_response
|
return @last_response
|
||||||
when /\A4/
|
when /\A4/
|
||||||
raise FTPTempError, @last_response
|
raise FTPTempError, @last_response
|
||||||
when /\A5/
|
when /\A5/
|
||||||
raise FTPPermError, @last_response
|
raise FTPPermError, @last_response
|
||||||
else
|
else
|
||||||
raise FTPProtoError, @last_response
|
raise FTPProtoError, @last_response
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private :getresp
|
private :getresp
|
||||||
@ -306,7 +306,7 @@ module Net
|
|||||||
def voidresp
|
def voidresp
|
||||||
resp = getresp
|
resp = getresp
|
||||||
if resp[0] != ?2
|
if resp[0] != ?2
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private :voidresp
|
private :voidresp
|
||||||
@ -316,8 +316,8 @@ module Net
|
|||||||
#
|
#
|
||||||
def sendcmd(cmd)
|
def sendcmd(cmd)
|
||||||
synchronize do
|
synchronize do
|
||||||
putline(cmd)
|
putline(cmd)
|
||||||
return getresp
|
return getresp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -326,8 +326,8 @@ module Net
|
|||||||
#
|
#
|
||||||
def voidcmd(cmd)
|
def voidcmd(cmd)
|
||||||
synchronize do
|
synchronize do
|
||||||
putline(cmd)
|
putline(cmd)
|
||||||
voidresp
|
voidresp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -335,11 +335,11 @@ module Net
|
|||||||
def sendport(host, port)
|
def sendport(host, port)
|
||||||
af = (@sock.peeraddr)[0]
|
af = (@sock.peeraddr)[0]
|
||||||
if af == "AF_INET"
|
if af == "AF_INET"
|
||||||
cmd = "PORT " + (host.split(".") + port.divmod(256)).join(",")
|
cmd = "PORT " + (host.split(".") + port.divmod(256)).join(",")
|
||||||
elsif af == "AF_INET6"
|
elsif af == "AF_INET6"
|
||||||
cmd = sprintf("EPRT |2|%s|%d|", host, port)
|
cmd = sprintf("EPRT |2|%s|%d|", host, port)
|
||||||
else
|
else
|
||||||
raise FTPProtoError, host
|
raise FTPProtoError, host
|
||||||
end
|
end
|
||||||
voidcmd(cmd)
|
voidcmd(cmd)
|
||||||
end
|
end
|
||||||
@ -360,10 +360,10 @@ module Net
|
|||||||
# sends the appropriate command to enable a passive connection
|
# sends the appropriate command to enable a passive connection
|
||||||
def makepasv
|
def makepasv
|
||||||
if @sock.peeraddr[0] == "AF_INET"
|
if @sock.peeraddr[0] == "AF_INET"
|
||||||
host, port = parse227(sendcmd("PASV"))
|
host, port = parse227(sendcmd("PASV"))
|
||||||
else
|
else
|
||||||
host, port = parse229(sendcmd("EPSV"))
|
host, port = parse229(sendcmd("EPSV"))
|
||||||
# host, port = parse228(sendcmd("LPSV"))
|
# host, port = parse228(sendcmd("LPSV"))
|
||||||
end
|
end
|
||||||
return host, port
|
return host, port
|
||||||
end
|
end
|
||||||
@ -372,36 +372,36 @@ module Net
|
|||||||
# Constructs a connection for transferring data
|
# Constructs a connection for transferring data
|
||||||
def transfercmd(cmd, rest_offset = nil)
|
def transfercmd(cmd, rest_offset = nil)
|
||||||
if @passive
|
if @passive
|
||||||
host, port = makepasv
|
host, port = makepasv
|
||||||
conn = open_socket(host, port)
|
conn = open_socket(host, port)
|
||||||
if @resume and rest_offset
|
if @resume and rest_offset
|
||||||
resp = sendcmd("REST " + rest_offset.to_s)
|
resp = sendcmd("REST " + rest_offset.to_s)
|
||||||
if resp[0] != ?3
|
if resp[0] != ?3
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
resp = sendcmd(cmd)
|
resp = sendcmd(cmd)
|
||||||
# skip 2XX for some ftp servers
|
# skip 2XX for some ftp servers
|
||||||
resp = getresp if resp[0] == ?2
|
resp = getresp if resp[0] == ?2
|
||||||
if resp[0] != ?1
|
if resp[0] != ?1
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
sock = makeport
|
sock = makeport
|
||||||
if @resume and rest_offset
|
if @resume and rest_offset
|
||||||
resp = sendcmd("REST " + rest_offset.to_s)
|
resp = sendcmd("REST " + rest_offset.to_s)
|
||||||
if resp[0] != ?3
|
if resp[0] != ?3
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
resp = sendcmd(cmd)
|
resp = sendcmd(cmd)
|
||||||
# skip 2XX for some ftp servers
|
# skip 2XX for some ftp servers
|
||||||
resp = getresp if resp[0] == ?2
|
resp = getresp if resp[0] == ?2
|
||||||
if resp[0] != ?1
|
if resp[0] != ?1
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
conn = sock.accept
|
conn = sock.accept
|
||||||
sock.close
|
sock.close
|
||||||
end
|
end
|
||||||
return conn
|
return conn
|
||||||
end
|
end
|
||||||
@ -417,23 +417,23 @@ module Net
|
|||||||
#
|
#
|
||||||
def login(user = "anonymous", passwd = nil, acct = nil)
|
def login(user = "anonymous", passwd = nil, acct = nil)
|
||||||
if user == "anonymous" and passwd == nil
|
if user == "anonymous" and passwd == nil
|
||||||
passwd = "anonymous@"
|
passwd = "anonymous@"
|
||||||
end
|
end
|
||||||
|
|
||||||
resp = ""
|
resp = ""
|
||||||
synchronize do
|
synchronize do
|
||||||
resp = sendcmd('USER ' + user)
|
resp = sendcmd('USER ' + user)
|
||||||
if resp[0] == ?3
|
if resp[0] == ?3
|
||||||
raise FTPReplyError, resp if passwd.nil?
|
raise FTPReplyError, resp if passwd.nil?
|
||||||
resp = sendcmd('PASS ' + passwd)
|
resp = sendcmd('PASS ' + passwd)
|
||||||
end
|
end
|
||||||
if resp[0] == ?3
|
if resp[0] == ?3
|
||||||
raise FTPReplyError, resp if acct.nil?
|
raise FTPReplyError, resp if acct.nil?
|
||||||
resp = sendcmd('ACCT ' + acct)
|
resp = sendcmd('ACCT ' + acct)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if resp[0] != ?2
|
if resp[0] != ?2
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
@welcome = resp
|
@welcome = resp
|
||||||
send_type_command
|
send_type_command
|
||||||
@ -448,7 +448,7 @@ module Net
|
|||||||
#
|
#
|
||||||
def retrbinary(cmd, blocksize, rest_offset = nil) # :yield: data
|
def retrbinary(cmd, blocksize, rest_offset = nil) # :yield: data
|
||||||
synchronize do
|
synchronize do
|
||||||
with_binary(true) do
|
with_binary(true) do
|
||||||
conn = transfercmd(cmd, rest_offset)
|
conn = transfercmd(cmd, rest_offset)
|
||||||
loop do
|
loop do
|
||||||
data = conn.read(blocksize)
|
data = conn.read(blocksize)
|
||||||
@ -469,7 +469,7 @@ module Net
|
|||||||
#
|
#
|
||||||
def retrlines(cmd) # :yield: line
|
def retrlines(cmd) # :yield: line
|
||||||
synchronize do
|
synchronize do
|
||||||
with_binary(false) do
|
with_binary(false) do
|
||||||
conn = transfercmd(cmd)
|
conn = transfercmd(cmd)
|
||||||
loop do
|
loop do
|
||||||
line = conn.gets
|
line = conn.gets
|
||||||
@ -493,7 +493,7 @@ module Net
|
|||||||
file.seek(rest_offset, IO::SEEK_SET)
|
file.seek(rest_offset, IO::SEEK_SET)
|
||||||
end
|
end
|
||||||
synchronize do
|
synchronize do
|
||||||
with_binary(true) do
|
with_binary(true) do
|
||||||
conn = transfercmd(cmd)
|
conn = transfercmd(cmd)
|
||||||
loop do
|
loop do
|
||||||
buf = file.read(blocksize)
|
buf = file.read(blocksize)
|
||||||
@ -522,7 +522,7 @@ module Net
|
|||||||
#
|
#
|
||||||
def storlines(cmd, file, &block) # :yield: line
|
def storlines(cmd, file, &block) # :yield: line
|
||||||
synchronize do
|
synchronize do
|
||||||
with_binary(false) do
|
with_binary(false) do
|
||||||
conn = transfercmd(cmd)
|
conn = transfercmd(cmd)
|
||||||
loop do
|
loop do
|
||||||
buf = file.gets
|
buf = file.gets
|
||||||
@ -553,7 +553,7 @@ module Net
|
|||||||
# chunks.
|
# chunks.
|
||||||
#
|
#
|
||||||
def getbinaryfile(remotefile, localfile = File.basename(remotefile),
|
def getbinaryfile(remotefile, localfile = File.basename(remotefile),
|
||||||
blocksize = DEFAULT_BLOCKSIZE) # :yield: data
|
blocksize = DEFAULT_BLOCKSIZE) # :yield: data
|
||||||
result = nil
|
result = nil
|
||||||
if localfile
|
if localfile
|
||||||
if @resume
|
if @resume
|
||||||
@ -567,15 +567,15 @@ module Net
|
|||||||
result = ""
|
result = ""
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
f.binmode if localfile
|
f.binmode if localfile
|
||||||
retrbinary("RETR " + remotefile.to_s, blocksize, rest_offset) do |data|
|
retrbinary("RETR " + remotefile.to_s, blocksize, rest_offset) do |data|
|
||||||
f.write(data) if localfile
|
f.write(data) if localfile
|
||||||
yield(data) if block_given?
|
yield(data) if block_given?
|
||||||
result.concat(data) if result
|
result.concat(data) if result
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
ensure
|
ensure
|
||||||
f.close if localfile
|
f.close if localfile
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -594,15 +594,15 @@ module Net
|
|||||||
result = ""
|
result = ""
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
retrlines("RETR " + remotefile) do |line, newline|
|
retrlines("RETR " + remotefile) do |line, newline|
|
||||||
l = newline ? line + "\n" : line
|
l = newline ? line + "\n" : line
|
||||||
f.print(l) if localfile
|
f.print(l) if localfile
|
||||||
yield(line, newline) if block_given?
|
yield(line, newline) if block_given?
|
||||||
result.concat(l) if result
|
result.concat(l) if result
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
ensure
|
ensure
|
||||||
f.close if localfile
|
f.close if localfile
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -611,11 +611,11 @@ module Net
|
|||||||
# binary). See #gettextfile and #getbinaryfile.
|
# binary). See #gettextfile and #getbinaryfile.
|
||||||
#
|
#
|
||||||
def get(remotefile, localfile = File.basename(remotefile),
|
def get(remotefile, localfile = File.basename(remotefile),
|
||||||
blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
|
blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
|
||||||
if @binary
|
if @binary
|
||||||
getbinaryfile(remotefile, localfile, blocksize, &block)
|
getbinaryfile(remotefile, localfile, blocksize, &block)
|
||||||
else
|
else
|
||||||
gettextfile(remotefile, localfile, &block)
|
gettextfile(remotefile, localfile, &block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -625,7 +625,7 @@ module Net
|
|||||||
# data in +blocksize+ chunks.
|
# data in +blocksize+ chunks.
|
||||||
#
|
#
|
||||||
def putbinaryfile(localfile, remotefile = File.basename(localfile),
|
def putbinaryfile(localfile, remotefile = File.basename(localfile),
|
||||||
blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
|
blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
|
||||||
if @resume
|
if @resume
|
||||||
begin
|
begin
|
||||||
rest_offset = size(remotefile)
|
rest_offset = size(remotefile)
|
||||||
@ -633,18 +633,18 @@ module Net
|
|||||||
rest_offset = nil
|
rest_offset = nil
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
rest_offset = nil
|
rest_offset = nil
|
||||||
end
|
end
|
||||||
f = open(localfile)
|
f = open(localfile)
|
||||||
begin
|
begin
|
||||||
f.binmode
|
f.binmode
|
||||||
if rest_offset
|
if rest_offset
|
||||||
storbinary("APPE " + remotefile, f, blocksize, rest_offset, &block)
|
storbinary("APPE " + remotefile, f, blocksize, rest_offset, &block)
|
||||||
else
|
else
|
||||||
storbinary("STOR " + remotefile, f, blocksize, rest_offset, &block)
|
storbinary("STOR " + remotefile, f, blocksize, rest_offset, &block)
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
f.close
|
f.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -656,9 +656,9 @@ module Net
|
|||||||
def puttextfile(localfile, remotefile = File.basename(localfile), &block) # :yield: line
|
def puttextfile(localfile, remotefile = File.basename(localfile), &block) # :yield: line
|
||||||
f = open(localfile)
|
f = open(localfile)
|
||||||
begin
|
begin
|
||||||
storlines("STOR " + remotefile, f, &block)
|
storlines("STOR " + remotefile, f, &block)
|
||||||
ensure
|
ensure
|
||||||
f.close
|
f.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -667,11 +667,11 @@ module Net
|
|||||||
# (text or binary). See #puttextfile and #putbinaryfile.
|
# (text or binary). See #puttextfile and #putbinaryfile.
|
||||||
#
|
#
|
||||||
def put(localfile, remotefile = File.basename(localfile),
|
def put(localfile, remotefile = File.basename(localfile),
|
||||||
blocksize = DEFAULT_BLOCKSIZE, &block)
|
blocksize = DEFAULT_BLOCKSIZE, &block)
|
||||||
if @binary
|
if @binary
|
||||||
putbinaryfile(localfile, remotefile, blocksize, &block)
|
putbinaryfile(localfile, remotefile, blocksize, &block)
|
||||||
else
|
else
|
||||||
puttextfile(localfile, remotefile, &block)
|
puttextfile(localfile, remotefile, &block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -692,11 +692,11 @@ module Net
|
|||||||
def nlst(dir = nil)
|
def nlst(dir = nil)
|
||||||
cmd = "NLST"
|
cmd = "NLST"
|
||||||
if dir
|
if dir
|
||||||
cmd = cmd + " " + dir
|
cmd = cmd + " " + dir
|
||||||
end
|
end
|
||||||
files = []
|
files = []
|
||||||
retrlines(cmd) do |line|
|
retrlines(cmd) do |line|
|
||||||
files.push(line)
|
files.push(line)
|
||||||
end
|
end
|
||||||
return files
|
return files
|
||||||
end
|
end
|
||||||
@ -708,16 +708,16 @@ module Net
|
|||||||
def list(*args, &block) # :yield: line
|
def list(*args, &block) # :yield: line
|
||||||
cmd = "LIST"
|
cmd = "LIST"
|
||||||
args.each do |arg|
|
args.each do |arg|
|
||||||
cmd = cmd + " " + arg.to_s
|
cmd = cmd + " " + arg.to_s
|
||||||
end
|
end
|
||||||
if block
|
if block
|
||||||
retrlines(cmd, &block)
|
retrlines(cmd, &block)
|
||||||
else
|
else
|
||||||
lines = []
|
lines = []
|
||||||
retrlines(cmd) do |line|
|
retrlines(cmd) do |line|
|
||||||
lines << line
|
lines << line
|
||||||
end
|
end
|
||||||
return lines
|
return lines
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias ls list
|
alias ls list
|
||||||
@ -729,7 +729,7 @@ module Net
|
|||||||
def rename(fromname, toname)
|
def rename(fromname, toname)
|
||||||
resp = sendcmd("RNFR " + fromname)
|
resp = sendcmd("RNFR " + fromname)
|
||||||
if resp[0] != ?3
|
if resp[0] != ?3
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
voidcmd("RNTO " + toname)
|
voidcmd("RNTO " + toname)
|
||||||
end
|
end
|
||||||
@ -740,11 +740,11 @@ module Net
|
|||||||
def delete(filename)
|
def delete(filename)
|
||||||
resp = sendcmd("DELE " + filename)
|
resp = sendcmd("DELE " + filename)
|
||||||
if resp[0, 3] == "250"
|
if resp[0, 3] == "250"
|
||||||
return
|
return
|
||||||
elsif resp[0] == ?5
|
elsif resp[0] == ?5
|
||||||
raise FTPPermError, resp
|
raise FTPPermError, resp
|
||||||
else
|
else
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -753,14 +753,14 @@ module Net
|
|||||||
#
|
#
|
||||||
def chdir(dirname)
|
def chdir(dirname)
|
||||||
if dirname == ".."
|
if dirname == ".."
|
||||||
begin
|
begin
|
||||||
voidcmd("CDUP")
|
voidcmd("CDUP")
|
||||||
return
|
return
|
||||||
rescue FTPPermError => e
|
rescue FTPPermError => e
|
||||||
if e.message[0, 3] != "500"
|
if e.message[0, 3] != "500"
|
||||||
raise e
|
raise e
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
cmd = "CWD " + dirname
|
cmd = "CWD " + dirname
|
||||||
voidcmd(cmd)
|
voidcmd(cmd)
|
||||||
@ -781,15 +781,15 @@ module Net
|
|||||||
|
|
||||||
MDTM_REGEXP = /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/ # :nodoc:
|
MDTM_REGEXP = /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/ # :nodoc:
|
||||||
|
|
||||||
#
|
#
|
||||||
# Returns the last modification time of the (remote) file. If +local+ is
|
# Returns the last modification time of the (remote) file. If +local+ is
|
||||||
# +true+, it is returned as a local time, otherwise it's a UTC time.
|
# +true+, it is returned as a local time, otherwise it's a UTC time.
|
||||||
#
|
#
|
||||||
def mtime(filename, local = false)
|
def mtime(filename, local = false)
|
||||||
str = mdtm(filename)
|
str = mdtm(filename)
|
||||||
ary = str.scan(MDTM_REGEXP)[0].collect {|i| i.to_i}
|
ary = str.scan(MDTM_REGEXP)[0].collect {|i| i.to_i}
|
||||||
return local ? Time.local(*ary) : Time.gm(*ary)
|
return local ? Time.local(*ary) : Time.gm(*ary)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Creates a remote directory.
|
# Creates a remote directory.
|
||||||
@ -821,7 +821,7 @@ module Net
|
|||||||
def system
|
def system
|
||||||
resp = sendcmd("SYST")
|
resp = sendcmd("SYST")
|
||||||
if resp[0, 3] != "215"
|
if resp[0, 3] != "215"
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
return resp[4 .. -1]
|
return resp[4 .. -1]
|
||||||
end
|
end
|
||||||
@ -835,7 +835,7 @@ module Net
|
|||||||
@sock.send(line, Socket::MSG_OOB)
|
@sock.send(line, Socket::MSG_OOB)
|
||||||
resp = getmultiline
|
resp = getmultiline
|
||||||
unless ["426", "226", "225"].include?(resp[0, 3])
|
unless ["426", "226", "225"].include?(resp[0, 3])
|
||||||
raise FTPProtoError, resp
|
raise FTPProtoError, resp
|
||||||
end
|
end
|
||||||
return resp
|
return resp
|
||||||
end
|
end
|
||||||
@ -856,7 +856,7 @@ module Net
|
|||||||
def mdtm(filename)
|
def mdtm(filename)
|
||||||
resp = sendcmd("MDTM " + filename)
|
resp = sendcmd("MDTM " + filename)
|
||||||
if resp[0, 3] == "213"
|
if resp[0, 3] == "213"
|
||||||
return resp[3 .. -1].strip
|
return resp[3 .. -1].strip
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -866,7 +866,7 @@ module Net
|
|||||||
def help(arg = nil)
|
def help(arg = nil)
|
||||||
cmd = "HELP"
|
cmd = "HELP"
|
||||||
if arg
|
if arg
|
||||||
cmd = cmd + " " + arg
|
cmd = cmd + " " + arg
|
||||||
end
|
end
|
||||||
sendcmd(cmd)
|
sendcmd(cmd)
|
||||||
end
|
end
|
||||||
@ -916,16 +916,16 @@ module Net
|
|||||||
# Returns host and port.
|
# Returns host and port.
|
||||||
def parse227(resp)
|
def parse227(resp)
|
||||||
if resp[0, 3] != "227"
|
if resp[0, 3] != "227"
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
left = resp.index("(")
|
left = resp.index("(")
|
||||||
right = resp.index(")")
|
right = resp.index(")")
|
||||||
if left == nil or right == nil
|
if left == nil or right == nil
|
||||||
raise FTPProtoError, resp
|
raise FTPProtoError, resp
|
||||||
end
|
end
|
||||||
numbers = resp[left + 1 .. right - 1].split(",")
|
numbers = resp[left + 1 .. right - 1].split(",")
|
||||||
if numbers.length != 6
|
if numbers.length != 6
|
||||||
raise FTPProtoError, resp
|
raise FTPProtoError, resp
|
||||||
end
|
end
|
||||||
host = numbers[0, 4].join(".")
|
host = numbers[0, 4].join(".")
|
||||||
port = (numbers[4].to_i << 8) + numbers[5].to_i
|
port = (numbers[4].to_i << 8) + numbers[5].to_i
|
||||||
@ -939,31 +939,31 @@ module Net
|
|||||||
# Returns host and port.
|
# Returns host and port.
|
||||||
def parse228(resp)
|
def parse228(resp)
|
||||||
if resp[0, 3] != "228"
|
if resp[0, 3] != "228"
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
left = resp.index("(")
|
left = resp.index("(")
|
||||||
right = resp.index(")")
|
right = resp.index(")")
|
||||||
if left == nil or right == nil
|
if left == nil or right == nil
|
||||||
raise FTPProtoError, resp
|
raise FTPProtoError, resp
|
||||||
end
|
end
|
||||||
numbers = resp[left + 1 .. right - 1].split(",")
|
numbers = resp[left + 1 .. right - 1].split(",")
|
||||||
if numbers[0] == "4"
|
if numbers[0] == "4"
|
||||||
if numbers.length != 9 || numbers[1] != "4" || numbers[2 + 4] != "2"
|
if numbers.length != 9 || numbers[1] != "4" || numbers[2 + 4] != "2"
|
||||||
raise FTPProtoError, resp
|
raise FTPProtoError, resp
|
||||||
end
|
end
|
||||||
host = numbers[2, 4].join(".")
|
host = numbers[2, 4].join(".")
|
||||||
port = (numbers[7].to_i << 8) + numbers[8].to_i
|
port = (numbers[7].to_i << 8) + numbers[8].to_i
|
||||||
elsif numbers[0] == "6"
|
elsif numbers[0] == "6"
|
||||||
if numbers.length != 21 || numbers[1] != "16" || numbers[2 + 16] != "2"
|
if numbers.length != 21 || numbers[1] != "16" || numbers[2 + 16] != "2"
|
||||||
raise FTPProtoError, resp
|
raise FTPProtoError, resp
|
||||||
end
|
end
|
||||||
v6 = ["", "", "", "", "", "", "", ""]
|
v6 = ["", "", "", "", "", "", "", ""]
|
||||||
for i in 0 .. 7
|
for i in 0 .. 7
|
||||||
v6[i] = sprintf("%02x%02x", numbers[(i * 2) + 2].to_i,
|
v6[i] = sprintf("%02x%02x", numbers[(i * 2) + 2].to_i,
|
||||||
numbers[(i * 2) + 3].to_i)
|
numbers[(i * 2) + 3].to_i)
|
||||||
end
|
end
|
||||||
host = v6[0, 8].join(":")
|
host = v6[0, 8].join(":")
|
||||||
port = (numbers[19].to_i << 8) + numbers[20].to_i
|
port = (numbers[19].to_i << 8) + numbers[20].to_i
|
||||||
end
|
end
|
||||||
return host, port
|
return host, port
|
||||||
end
|
end
|
||||||
@ -975,16 +975,16 @@ module Net
|
|||||||
# Returns host and port.
|
# Returns host and port.
|
||||||
def parse229(resp)
|
def parse229(resp)
|
||||||
if resp[0, 3] != "229"
|
if resp[0, 3] != "229"
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
left = resp.index("(")
|
left = resp.index("(")
|
||||||
right = resp.index(")")
|
right = resp.index(")")
|
||||||
if left == nil or right == nil
|
if left == nil or right == nil
|
||||||
raise FTPProtoError, resp
|
raise FTPProtoError, resp
|
||||||
end
|
end
|
||||||
numbers = resp[left + 1 .. right - 1].split(resp[left + 1, 1])
|
numbers = resp[left + 1 .. right - 1].split(resp[left + 1, 1])
|
||||||
if numbers.length != 4
|
if numbers.length != 4
|
||||||
raise FTPProtoError, resp
|
raise FTPProtoError, resp
|
||||||
end
|
end
|
||||||
port = numbers[3].to_i
|
port = numbers[3].to_i
|
||||||
host = (@sock.peeraddr())[3]
|
host = (@sock.peeraddr())[3]
|
||||||
@ -998,24 +998,24 @@ module Net
|
|||||||
# Returns host and port.
|
# Returns host and port.
|
||||||
def parse257(resp)
|
def parse257(resp)
|
||||||
if resp[0, 3] != "257"
|
if resp[0, 3] != "257"
|
||||||
raise FTPReplyError, resp
|
raise FTPReplyError, resp
|
||||||
end
|
end
|
||||||
if resp[3, 2] != ' "'
|
if resp[3, 2] != ' "'
|
||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
dirname = ""
|
dirname = ""
|
||||||
i = 5
|
i = 5
|
||||||
n = resp.length
|
n = resp.length
|
||||||
while i < n
|
while i < n
|
||||||
c = resp[i, 1]
|
c = resp[i, 1]
|
||||||
i = i + 1
|
i = i + 1
|
||||||
if c == '"'
|
if c == '"'
|
||||||
if i > n or resp[i, 1] != '"'
|
if i > n or resp[i, 1] != '"'
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
dirname = dirname + c
|
dirname = dirname + c
|
||||||
end
|
end
|
||||||
return dirname
|
return dirname
|
||||||
end
|
end
|
||||||
|
320
lib/net/imap.rb
320
lib/net/imap.rb
@ -1091,7 +1091,7 @@ module Net
|
|||||||
when UntaggedResponse
|
when UntaggedResponse
|
||||||
record_response(resp.name, resp.data)
|
record_response(resp.name, resp.data)
|
||||||
if resp.data.instance_of?(ResponseText) &&
|
if resp.data.instance_of?(ResponseText) &&
|
||||||
(code = resp.data.code)
|
(code = resp.data.code)
|
||||||
record_response(code.name, code.data)
|
record_response(code.name, code.data)
|
||||||
end
|
end
|
||||||
if resp.name == "BYE" && @logout_command_tag.nil?
|
if resp.name == "BYE" && @logout_command_tag.nil?
|
||||||
@ -1550,7 +1550,7 @@ module Net
|
|||||||
def ensure_nz_number(num)
|
def ensure_nz_number(num)
|
||||||
if num < -1 || num == 0 || num >= 4294967296
|
if num < -1 || num == 0 || num >= 4294967296
|
||||||
msg = "nz_number must be non-zero unsigned 32-bit integer: " +
|
msg = "nz_number must be non-zero unsigned 32-bit integer: " +
|
||||||
num.inspect
|
num.inspect
|
||||||
raise DataFormatError, msg
|
raise DataFormatError, msg
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -2032,43 +2032,43 @@ module Net
|
|||||||
T_TEXT = :TEXT
|
T_TEXT = :TEXT
|
||||||
|
|
||||||
BEG_REGEXP = /\G(?:\
|
BEG_REGEXP = /\G(?:\
|
||||||
(?# 1: SPACE )( +)|\
|
(?# 1: SPACE )( +)|\
|
||||||
(?# 2: NIL )(NIL)(?=[\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+])|\
|
(?# 2: NIL )(NIL)(?=[\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+])|\
|
||||||
(?# 3: NUMBER )(\d+)(?=[\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+])|\
|
(?# 3: NUMBER )(\d+)(?=[\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+])|\
|
||||||
(?# 4: ATOM )([^\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+]+)|\
|
(?# 4: ATOM )([^\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+]+)|\
|
||||||
(?# 5: QUOTED )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\
|
(?# 5: QUOTED )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\
|
||||||
(?# 6: LPAR )(\()|\
|
(?# 6: LPAR )(\()|\
|
||||||
(?# 7: RPAR )(\))|\
|
(?# 7: RPAR )(\))|\
|
||||||
(?# 8: BSLASH )(\\)|\
|
(?# 8: BSLASH )(\\)|\
|
||||||
(?# 9: STAR )(\*)|\
|
(?# 9: STAR )(\*)|\
|
||||||
(?# 10: LBRA )(\[)|\
|
(?# 10: LBRA )(\[)|\
|
||||||
(?# 11: RBRA )(\])|\
|
(?# 11: RBRA )(\])|\
|
||||||
(?# 12: LITERAL )\{(\d+)\}\r\n|\
|
(?# 12: LITERAL )\{(\d+)\}\r\n|\
|
||||||
(?# 13: PLUS )(\+)|\
|
(?# 13: PLUS )(\+)|\
|
||||||
(?# 14: PERCENT )(%)|\
|
(?# 14: PERCENT )(%)|\
|
||||||
(?# 15: CRLF )(\r\n)|\
|
(?# 15: CRLF )(\r\n)|\
|
||||||
(?# 16: EOF )(\z))/ni
|
(?# 16: EOF )(\z))/ni
|
||||||
|
|
||||||
DATA_REGEXP = /\G(?:\
|
DATA_REGEXP = /\G(?:\
|
||||||
(?# 1: SPACE )( )|\
|
(?# 1: SPACE )( )|\
|
||||||
(?# 2: NIL )(NIL)|\
|
(?# 2: NIL )(NIL)|\
|
||||||
(?# 3: NUMBER )(\d+)|\
|
(?# 3: NUMBER )(\d+)|\
|
||||||
(?# 4: QUOTED )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\
|
(?# 4: QUOTED )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\
|
||||||
(?# 5: LITERAL )\{(\d+)\}\r\n|\
|
(?# 5: LITERAL )\{(\d+)\}\r\n|\
|
||||||
(?# 6: LPAR )(\()|\
|
(?# 6: LPAR )(\()|\
|
||||||
(?# 7: RPAR )(\)))/ni
|
(?# 7: RPAR )(\)))/ni
|
||||||
|
|
||||||
TEXT_REGEXP = /\G(?:\
|
TEXT_REGEXP = /\G(?:\
|
||||||
(?# 1: TEXT )([^\x00\r\n]*))/ni
|
(?# 1: TEXT )([^\x00\r\n]*))/ni
|
||||||
|
|
||||||
RTEXT_REGEXP = /\G(?:\
|
RTEXT_REGEXP = /\G(?:\
|
||||||
(?# 1: LBRA )(\[)|\
|
(?# 1: LBRA )(\[)|\
|
||||||
(?# 2: TEXT )([^\x00\r\n]*))/ni
|
(?# 2: TEXT )([^\x00\r\n]*))/ni
|
||||||
|
|
||||||
CTEXT_REGEXP = /\G(?:\
|
CTEXT_REGEXP = /\G(?:\
|
||||||
(?# 1: TEXT )([^\x00\r\n\]]*))/ni
|
(?# 1: TEXT )([^\x00\r\n\]]*))/ni
|
||||||
|
|
||||||
Token = Struct.new(:symbol, :value)
|
Token = Struct.new(:symbol, :value)
|
||||||
|
|
||||||
def response
|
def response
|
||||||
token = lookahead
|
token = lookahead
|
||||||
@ -2932,11 +2932,11 @@ module Net
|
|||||||
end
|
end
|
||||||
|
|
||||||
ADDRESS_REGEXP = /\G\
|
ADDRESS_REGEXP = /\G\
|
||||||
(?# 1: NAME )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
(?# 1: NAME )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
||||||
(?# 2: ROUTE )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
(?# 2: ROUTE )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
||||||
(?# 3: MAILBOX )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
(?# 3: MAILBOX )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
||||||
(?# 4: HOST )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)")\
|
(?# 4: HOST )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)")\
|
||||||
\)/ni
|
\)/ni
|
||||||
|
|
||||||
def address
|
def address
|
||||||
match(T_LPAR)
|
match(T_LPAR)
|
||||||
@ -2965,62 +2965,62 @@ module Net
|
|||||||
return Address.new(name, route, mailbox, host)
|
return Address.new(name, route, mailbox, host)
|
||||||
end
|
end
|
||||||
|
|
||||||
# def flag_list
|
# def flag_list
|
||||||
# result = []
|
# result = []
|
||||||
# match(T_LPAR)
|
# match(T_LPAR)
|
||||||
# while true
|
# while true
|
||||||
# token = lookahead
|
# token = lookahead
|
||||||
# case token.symbol
|
# case token.symbol
|
||||||
# when T_RPAR
|
# when T_RPAR
|
||||||
# shift_token
|
# shift_token
|
||||||
# break
|
# break
|
||||||
# when T_SPACE
|
# when T_SPACE
|
||||||
# shift_token
|
# shift_token
|
||||||
# end
|
# end
|
||||||
# result.push(flag)
|
# result.push(flag)
|
||||||
# end
|
# end
|
||||||
# return result
|
# return result
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# def flag
|
# def flag
|
||||||
# token = lookahead
|
# token = lookahead
|
||||||
# if token.symbol == T_BSLASH
|
# if token.symbol == T_BSLASH
|
||||||
# shift_token
|
# shift_token
|
||||||
# token = lookahead
|
# token = lookahead
|
||||||
# if token.symbol == T_STAR
|
# if token.symbol == T_STAR
|
||||||
# shift_token
|
# shift_token
|
||||||
# return token.value.intern
|
# return token.value.intern
|
||||||
# else
|
# else
|
||||||
# return atom.intern
|
# return atom.intern
|
||||||
# end
|
# end
|
||||||
# else
|
# else
|
||||||
# return atom
|
# return atom
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
|
|
||||||
FLAG_REGEXP = /\
|
FLAG_REGEXP = /\
|
||||||
(?# FLAG )\\([^\x80-\xff(){ \x00-\x1f\x7f%"\\]+)|\
|
(?# FLAG )\\([^\x80-\xff(){ \x00-\x1f\x7f%"\\]+)|\
|
||||||
(?# ATOM )([^\x80-\xff(){ \x00-\x1f\x7f%*"\\]+)/n
|
(?# ATOM )([^\x80-\xff(){ \x00-\x1f\x7f%*"\\]+)/n
|
||||||
|
|
||||||
def flag_list
|
def flag_list
|
||||||
if @str.index(/\(([^)]*)\)/ni, @pos)
|
if @str.index(/\(([^)]*)\)/ni, @pos)
|
||||||
@pos = $~.end(0)
|
@pos = $~.end(0)
|
||||||
return $1.scan(FLAG_REGEXP).collect { |flag, atom|
|
return $1.scan(FLAG_REGEXP).collect { |flag, atom|
|
||||||
if atom
|
if atom
|
||||||
atom
|
atom
|
||||||
else
|
else
|
||||||
symbol = flag.capitalize.untaint.intern
|
symbol = flag.capitalize.untaint.intern
|
||||||
@flag_symbols[symbol] = true
|
@flag_symbols[symbol] = true
|
||||||
if @flag_symbols.length > IMAP.max_flag_count
|
if @flag_symbols.length > IMAP.max_flag_count
|
||||||
raise FlagCountError, "number of flag symbols exceeded"
|
raise FlagCountError, "number of flag symbols exceeded"
|
||||||
|
end
|
||||||
|
symbol
|
||||||
|
end
|
||||||
|
}
|
||||||
|
else
|
||||||
|
parse_error("invalid flag list")
|
||||||
end
|
end
|
||||||
symbol
|
|
||||||
end
|
end
|
||||||
}
|
|
||||||
else
|
|
||||||
parse_error("invalid flag list")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def nstring
|
def nstring
|
||||||
token = lookahead
|
token = lookahead
|
||||||
@ -3347,73 +3347,73 @@ module Net
|
|||||||
# #authenticate().
|
# #authenticate().
|
||||||
class DigestMD5Authenticator
|
class DigestMD5Authenticator
|
||||||
def process(challenge)
|
def process(challenge)
|
||||||
case @stage
|
case @stage
|
||||||
when STAGE_ONE
|
when STAGE_ONE
|
||||||
@stage = STAGE_TWO
|
@stage = STAGE_TWO
|
||||||
sparams = {}
|
sparams = {}
|
||||||
c = StringScanner.new(challenge)
|
c = StringScanner.new(challenge)
|
||||||
while c.scan(/(?:\s*,)?\s*(\w+)=("(?:[^\\"]+|\\.)*"|[^,]+)\s*/)
|
while c.scan(/(?:\s*,)?\s*(\w+)=("(?:[^\\"]+|\\.)*"|[^,]+)\s*/)
|
||||||
k, v = c[1], c[2]
|
k, v = c[1], c[2]
|
||||||
if v =~ /^"(.*)"$/
|
if v =~ /^"(.*)"$/
|
||||||
v = $1
|
v = $1
|
||||||
if v =~ /,/
|
if v =~ /,/
|
||||||
v = v.split(',')
|
v = v.split(',')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
sparams[k] = v
|
sparams[k] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
raise DataFormatError, "Bad Challenge: '#{challenge}'" unless c.rest.size == 0
|
raise DataFormatError, "Bad Challenge: '#{challenge}'" unless c.rest.size == 0
|
||||||
raise Error, "Server does not support auth (qop = #{sparams['qop'].join(',')})" unless sparams['qop'].include?("auth")
|
raise Error, "Server does not support auth (qop = #{sparams['qop'].join(',')})" unless sparams['qop'].include?("auth")
|
||||||
|
|
||||||
response = {
|
response = {
|
||||||
:nonce => sparams['nonce'],
|
:nonce => sparams['nonce'],
|
||||||
:username => @user,
|
:username => @user,
|
||||||
:realm => sparams['realm'],
|
:realm => sparams['realm'],
|
||||||
:cnonce => Digest::MD5.hexdigest("%.15f:%.15f:%d" % [Time.now.to_f, rand, Process.pid.to_s]),
|
:cnonce => Digest::MD5.hexdigest("%.15f:%.15f:%d" % [Time.now.to_f, rand, Process.pid.to_s]),
|
||||||
:'digest-uri' => 'imap/' + sparams['realm'],
|
:'digest-uri' => 'imap/' + sparams['realm'],
|
||||||
:qop => 'auth',
|
:qop => 'auth',
|
||||||
:maxbuf => 65535,
|
:maxbuf => 65535,
|
||||||
:nc => "%08d" % nc(sparams['nonce']),
|
:nc => "%08d" % nc(sparams['nonce']),
|
||||||
:charset => sparams['charset'],
|
:charset => sparams['charset'],
|
||||||
}
|
}
|
||||||
|
|
||||||
response[:authzid] = @authname unless @authname.nil?
|
response[:authzid] = @authname unless @authname.nil?
|
||||||
|
|
||||||
# now, the real thing
|
# now, the real thing
|
||||||
a0 = Digest::MD5.digest( [ response.values_at(:username, :realm), @password ].join(':') )
|
a0 = Digest::MD5.digest( [ response.values_at(:username, :realm), @password ].join(':') )
|
||||||
|
|
||||||
a1 = [ a0, response.values_at(:nonce,:cnonce) ].join(':')
|
a1 = [ a0, response.values_at(:nonce,:cnonce) ].join(':')
|
||||||
a1 << ':' + response[:authzid] unless response[:authzid].nil?
|
a1 << ':' + response[:authzid] unless response[:authzid].nil?
|
||||||
|
|
||||||
a2 = "AUTHENTICATE:" + response[:'digest-uri']
|
a2 = "AUTHENTICATE:" + response[:'digest-uri']
|
||||||
a2 << ":00000000000000000000000000000000" if response[:qop] and response[:qop] =~ /^auth-(?:conf|int)$/
|
a2 << ":00000000000000000000000000000000" if response[:qop] and response[:qop] =~ /^auth-(?:conf|int)$/
|
||||||
|
|
||||||
response[:response] = Digest::MD5.hexdigest(
|
response[:response] = Digest::MD5.hexdigest(
|
||||||
[
|
[
|
||||||
Digest::MD5.hexdigest(a1),
|
Digest::MD5.hexdigest(a1),
|
||||||
response.values_at(:nonce, :nc, :cnonce, :qop),
|
response.values_at(:nonce, :nc, :cnonce, :qop),
|
||||||
Digest::MD5.hexdigest(a2)
|
Digest::MD5.hexdigest(a2)
|
||||||
].join(':')
|
].join(':')
|
||||||
)
|
)
|
||||||
|
|
||||||
return response.keys.map {|key| qdval(key.to_s, response[key]) }.join(',')
|
return response.keys.map {|key| qdval(key.to_s, response[key]) }.join(',')
|
||||||
when STAGE_TWO
|
when STAGE_TWO
|
||||||
@stage = nil
|
@stage = nil
|
||||||
# if at the second stage, return an empty string
|
# if at the second stage, return an empty string
|
||||||
if challenge =~ /rspauth=/
|
if challenge =~ /rspauth=/
|
||||||
return ''
|
return ''
|
||||||
else
|
else
|
||||||
raise ResponseParseError, challenge
|
raise ResponseParseError, challenge
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise ResponseParseError, challenge
|
raise ResponseParseError, challenge
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(user, password, authname = nil)
|
def initialize(user, password, authname = nil)
|
||||||
@user, @password, @authname = user, password, authname
|
@user, @password, @authname = user, password, authname
|
||||||
@nc, @stage = {}, STAGE_ONE
|
@nc, @stage = {}, STAGE_ONE
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -3422,23 +3422,23 @@ module Net
|
|||||||
STAGE_TWO = :stage_two
|
STAGE_TWO = :stage_two
|
||||||
|
|
||||||
def nc(nonce)
|
def nc(nonce)
|
||||||
if @nc.has_key? nonce
|
if @nc.has_key? nonce
|
||||||
@nc[nonce] = @nc[nonce] + 1
|
@nc[nonce] = @nc[nonce] + 1
|
||||||
else
|
else
|
||||||
@nc[nonce] = 1
|
@nc[nonce] = 1
|
||||||
end
|
end
|
||||||
return @nc[nonce]
|
return @nc[nonce]
|
||||||
end
|
end
|
||||||
|
|
||||||
# some responses need quoting
|
# some responses need quoting
|
||||||
def qdval(k, v)
|
def qdval(k, v)
|
||||||
return if k.nil? or v.nil?
|
return if k.nil? or v.nil?
|
||||||
if %w"username authzid realm nonce cnonce digest-uri qop".include? k
|
if %w"username authzid realm nonce cnonce digest-uri qop".include? k
|
||||||
v.gsub!(/([\\"])/, "\\\1")
|
v.gsub!(/([\\"])/, "\\\1")
|
||||||
return '%s="%s"' % [k, v]
|
return '%s="%s"' % [k, v]
|
||||||
else
|
else
|
||||||
return '%s=%s' % [k, v]
|
return '%s=%s' % [k, v]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
add_authenticator "DIGEST-MD5", DigestMD5Authenticator
|
add_authenticator "DIGEST-MD5", DigestMD5Authenticator
|
||||||
@ -3514,7 +3514,7 @@ usage: #{$0} [options] <host>
|
|||||||
--auth=AUTH specifies auth type
|
--auth=AUTH specifies auth type
|
||||||
--starttls use starttls
|
--starttls use starttls
|
||||||
--ssl use ssl
|
--ssl use ssl
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -3649,7 +3649,7 @@ summary display summary
|
|||||||
fetch [msgno] display message
|
fetch [msgno] display message
|
||||||
logout logout
|
logout logout
|
||||||
help, ? display help message
|
help, ? display help message
|
||||||
EOF
|
EOF
|
||||||
else
|
else
|
||||||
print "unknown command: ", cmd, "\n"
|
print "unknown command: ", cmd, "\n"
|
||||||
end
|
end
|
||||||
|
@ -433,18 +433,18 @@ module Net
|
|||||||
# combine CR+NULL into CR
|
# combine CR+NULL into CR
|
||||||
string = string.gsub(/#{CR}#{NULL}/no, CR) if @options["Telnetmode"]
|
string = string.gsub(/#{CR}#{NULL}/no, CR) if @options["Telnetmode"]
|
||||||
|
|
||||||
# combine EOL into "\n"
|
# combine EOL into "\n"
|
||||||
string = string.gsub(/#{EOL}/no, "\n") unless @options["Binmode"]
|
string = string.gsub(/#{EOL}/no, "\n") unless @options["Binmode"]
|
||||||
|
|
||||||
# remove NULL
|
# remove NULL
|
||||||
string = string.gsub(/#{NULL}/no, '') unless @options["Binmode"]
|
string = string.gsub(/#{NULL}/no, '') unless @options["Binmode"]
|
||||||
|
|
||||||
string.gsub(/#{IAC}(
|
string.gsub(/#{IAC}(
|
||||||
[#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|
|
[#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|
|
||||||
[#{DO}#{DONT}#{WILL}#{WONT}]
|
[#{DO}#{DONT}#{WILL}#{WONT}]
|
||||||
[#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]|
|
[#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]|
|
||||||
#{SB}[^#{IAC}]*#{IAC}#{SE}
|
#{SB}[^#{IAC}]*#{IAC}#{SE}
|
||||||
)/xno) do
|
)/xno) do
|
||||||
if IAC == $1 # handle escaped IAC characters
|
if IAC == $1 # handle escaped IAC characters
|
||||||
IAC
|
IAC
|
||||||
elsif AYT == $1 # respond to "IAC AYT" (are you there)
|
elsif AYT == $1 # respond to "IAC AYT" (are you there)
|
||||||
@ -464,301 +464,301 @@ module Net
|
|||||||
elsif WILL[0] == $1[0] # respond to "IAC WILL x"
|
elsif WILL[0] == $1[0] # respond to "IAC WILL x"
|
||||||
if OPT_BINARY[0] == $1[1]
|
if OPT_BINARY[0] == $1[1]
|
||||||
self.write(IAC + DO + OPT_BINARY)
|
self.write(IAC + DO + OPT_BINARY)
|
||||||
elsif OPT_ECHO[0] == $1[1]
|
elsif OPT_ECHO[0] == $1[1]
|
||||||
self.write(IAC + DO + OPT_ECHO)
|
self.write(IAC + DO + OPT_ECHO)
|
||||||
elsif OPT_SGA[0] == $1[1]
|
elsif OPT_SGA[0] == $1[1]
|
||||||
@telnet_option["SGA"] = true
|
@telnet_option["SGA"] = true
|
||||||
self.write(IAC + DO + OPT_SGA)
|
self.write(IAC + DO + OPT_SGA)
|
||||||
else
|
else
|
||||||
self.write(IAC + DONT + $1[1..1])
|
self.write(IAC + DONT + $1[1..1])
|
||||||
end
|
end
|
||||||
''
|
''
|
||||||
elsif WONT[0] == $1[0] # respond to "IAC WON'T x"
|
elsif WONT[0] == $1[0] # respond to "IAC WON'T x"
|
||||||
if OPT_ECHO[0] == $1[1]
|
if OPT_ECHO[0] == $1[1]
|
||||||
self.write(IAC + DONT + OPT_ECHO)
|
self.write(IAC + DONT + OPT_ECHO)
|
||||||
elsif OPT_SGA[0] == $1[1]
|
elsif OPT_SGA[0] == $1[1]
|
||||||
@telnet_option["SGA"] = false
|
@telnet_option["SGA"] = false
|
||||||
self.write(IAC + DONT + OPT_SGA)
|
self.write(IAC + DONT + OPT_SGA)
|
||||||
else
|
else
|
||||||
self.write(IAC + DONT + $1[1..1])
|
self.write(IAC + DONT + $1[1..1])
|
||||||
end
|
end
|
||||||
''
|
''
|
||||||
else
|
else
|
||||||
''
|
''
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end # preprocess
|
|
||||||
|
|
||||||
# Read data from the host until a certain sequence is matched.
|
|
||||||
#
|
|
||||||
# If a block is given, the received data will be yielded as it
|
|
||||||
# is read in (not necessarily all in one go), or nil if EOF
|
|
||||||
# occurs before any data is received. Whether a block is given
|
|
||||||
# or not, all data read will be returned in a single string, or again
|
|
||||||
# nil if EOF occurs before any data is received. Note that
|
|
||||||
# received data includes the matched sequence we were looking for.
|
|
||||||
#
|
|
||||||
# +options+ can be either a regular expression or a hash of options.
|
|
||||||
# If a regular expression, this specifies the data to wait for.
|
|
||||||
# If a hash, this can specify the following options:
|
|
||||||
#
|
|
||||||
# Match:: a regular expression, specifying the data to wait for.
|
|
||||||
# Prompt:: as for Match; used only if Match is not specified.
|
|
||||||
# String:: as for Match, except a string that will be converted
|
|
||||||
# into a regular expression. Used only if Match and
|
|
||||||
# Prompt are not specified.
|
|
||||||
# Timeout:: the number of seconds to wait for data from the host
|
|
||||||
# before raising a TimeoutError. If set to false,
|
|
||||||
# no timeout will occur. If not specified, the
|
|
||||||
# Timeout option value specified when this instance
|
|
||||||
# was created will be used, or, failing that, the
|
|
||||||
# default value of 10 seconds.
|
|
||||||
# Waittime:: the number of seconds to wait after matching against
|
|
||||||
# the input data to see if more data arrives. If more
|
|
||||||
# data arrives within this time, we will judge ourselves
|
|
||||||
# not to have matched successfully, and will continue
|
|
||||||
# trying to match. If not specified, the Waittime option
|
|
||||||
# value specified when this instance was created will be
|
|
||||||
# used, or, failing that, the default value of 0 seconds,
|
|
||||||
# which means not to wait for more input.
|
|
||||||
# FailEOF:: if true, when the remote end closes the connection then an
|
|
||||||
# EOFError will be raised. Otherwise, defaults to the old
|
|
||||||
# behaviour that the function will return whatever data
|
|
||||||
# has been received already, or nil if nothing was received.
|
|
||||||
#
|
|
||||||
def waitfor(options) # :yield: recvdata
|
|
||||||
time_out = @options["Timeout"]
|
|
||||||
waittime = @options["Waittime"]
|
|
||||||
fail_eof = @options["FailEOF"]
|
|
||||||
|
|
||||||
if options.kind_of?(Hash)
|
|
||||||
prompt = if options.has_key?("Match")
|
|
||||||
options["Match"]
|
|
||||||
elsif options.has_key?("Prompt")
|
|
||||||
options["Prompt"]
|
|
||||||
elsif options.has_key?("String")
|
|
||||||
Regexp.new( Regexp.quote(options["String"]) )
|
|
||||||
end
|
|
||||||
time_out = options["Timeout"] if options.has_key?("Timeout")
|
|
||||||
waittime = options["Waittime"] if options.has_key?("Waittime")
|
|
||||||
fail_eof = options["FailEOF"] if options.has_key?("FailEOF")
|
|
||||||
else
|
|
||||||
prompt = options
|
|
||||||
end
|
|
||||||
|
|
||||||
if time_out == false
|
|
||||||
time_out = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
line = ''
|
|
||||||
buf = ''
|
|
||||||
rest = ''
|
|
||||||
until(prompt === line and not IO::select([@sock], nil, nil, waittime))
|
|
||||||
unless IO::select([@sock], nil, nil, time_out)
|
|
||||||
raise TimeoutError, "timed out while waiting for more data"
|
|
||||||
end
|
|
||||||
begin
|
|
||||||
c = @sock.readpartial(1024 * 1024)
|
|
||||||
@dumplog.log_dump('<', c) if @options.has_key?("Dump_log")
|
|
||||||
if @options["Telnetmode"]
|
|
||||||
c = rest + c
|
|
||||||
if Integer(c.rindex(/#{IAC}#{SE}/no) || 0) <
|
|
||||||
Integer(c.rindex(/#{IAC}#{SB}/no) || 0)
|
|
||||||
buf = preprocess(c[0 ... c.rindex(/#{IAC}#{SB}/no)])
|
|
||||||
rest = c[c.rindex(/#{IAC}#{SB}/no) .. -1]
|
|
||||||
elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) ||
|
|
||||||
c.rindex(/\r\z/no)
|
|
||||||
buf = preprocess(c[0 ... pt])
|
|
||||||
rest = c[pt .. -1]
|
|
||||||
else
|
|
||||||
buf = preprocess(c)
|
|
||||||
rest = ''
|
|
||||||
end
|
end
|
||||||
else
|
end # preprocess
|
||||||
# Not Telnetmode.
|
|
||||||
#
|
# Read data from the host until a certain sequence is matched.
|
||||||
# We cannot use preprocess() on this data, because that
|
#
|
||||||
# method makes some Telnetmode-specific assumptions.
|
# If a block is given, the received data will be yielded as it
|
||||||
buf = rest + c
|
# is read in (not necessarily all in one go), or nil if EOF
|
||||||
rest = ''
|
# occurs before any data is received. Whether a block is given
|
||||||
unless @options["Binmode"]
|
# or not, all data read will be returned in a single string, or again
|
||||||
if pt = buf.rindex(/\r\z/no)
|
# nil if EOF occurs before any data is received. Note that
|
||||||
buf = buf[0 ... pt]
|
# received data includes the matched sequence we were looking for.
|
||||||
rest = buf[pt .. -1]
|
#
|
||||||
end
|
# +options+ can be either a regular expression or a hash of options.
|
||||||
buf.gsub!(/#{EOL}/no, "\n")
|
# If a regular expression, this specifies the data to wait for.
|
||||||
end
|
# If a hash, this can specify the following options:
|
||||||
|
#
|
||||||
|
# Match:: a regular expression, specifying the data to wait for.
|
||||||
|
# Prompt:: as for Match; used only if Match is not specified.
|
||||||
|
# String:: as for Match, except a string that will be converted
|
||||||
|
# into a regular expression. Used only if Match and
|
||||||
|
# Prompt are not specified.
|
||||||
|
# Timeout:: the number of seconds to wait for data from the host
|
||||||
|
# before raising a TimeoutError. If set to false,
|
||||||
|
# no timeout will occur. If not specified, the
|
||||||
|
# Timeout option value specified when this instance
|
||||||
|
# was created will be used, or, failing that, the
|
||||||
|
# default value of 10 seconds.
|
||||||
|
# Waittime:: the number of seconds to wait after matching against
|
||||||
|
# the input data to see if more data arrives. If more
|
||||||
|
# data arrives within this time, we will judge ourselves
|
||||||
|
# not to have matched successfully, and will continue
|
||||||
|
# trying to match. If not specified, the Waittime option
|
||||||
|
# value specified when this instance was created will be
|
||||||
|
# used, or, failing that, the default value of 0 seconds,
|
||||||
|
# which means not to wait for more input.
|
||||||
|
# FailEOF:: if true, when the remote end closes the connection then an
|
||||||
|
# EOFError will be raised. Otherwise, defaults to the old
|
||||||
|
# behaviour that the function will return whatever data
|
||||||
|
# has been received already, or nil if nothing was received.
|
||||||
|
#
|
||||||
|
def waitfor(options) # :yield: recvdata
|
||||||
|
time_out = @options["Timeout"]
|
||||||
|
waittime = @options["Waittime"]
|
||||||
|
fail_eof = @options["FailEOF"]
|
||||||
|
|
||||||
|
if options.kind_of?(Hash)
|
||||||
|
prompt = if options.has_key?("Match")
|
||||||
|
options["Match"]
|
||||||
|
elsif options.has_key?("Prompt")
|
||||||
|
options["Prompt"]
|
||||||
|
elsif options.has_key?("String")
|
||||||
|
Regexp.new( Regexp.quote(options["String"]) )
|
||||||
|
end
|
||||||
|
time_out = options["Timeout"] if options.has_key?("Timeout")
|
||||||
|
waittime = options["Waittime"] if options.has_key?("Waittime")
|
||||||
|
fail_eof = options["FailEOF"] if options.has_key?("FailEOF")
|
||||||
|
else
|
||||||
|
prompt = options
|
||||||
|
end
|
||||||
|
|
||||||
|
if time_out == false
|
||||||
|
time_out = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
line = ''
|
||||||
|
buf = ''
|
||||||
|
rest = ''
|
||||||
|
until(prompt === line and not IO::select([@sock], nil, nil, waittime))
|
||||||
|
unless IO::select([@sock], nil, nil, time_out)
|
||||||
|
raise TimeoutError, "timed out while waiting for more data"
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
c = @sock.readpartial(1024 * 1024)
|
||||||
|
@dumplog.log_dump('<', c) if @options.has_key?("Dump_log")
|
||||||
|
if @options["Telnetmode"]
|
||||||
|
c = rest + c
|
||||||
|
if Integer(c.rindex(/#{IAC}#{SE}/no) || 0) <
|
||||||
|
Integer(c.rindex(/#{IAC}#{SB}/no) || 0)
|
||||||
|
buf = preprocess(c[0 ... c.rindex(/#{IAC}#{SB}/no)])
|
||||||
|
rest = c[c.rindex(/#{IAC}#{SB}/no) .. -1]
|
||||||
|
elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) ||
|
||||||
|
c.rindex(/\r\z/no)
|
||||||
|
buf = preprocess(c[0 ... pt])
|
||||||
|
rest = c[pt .. -1]
|
||||||
|
else
|
||||||
|
buf = preprocess(c)
|
||||||
|
rest = ''
|
||||||
|
end
|
||||||
|
else
|
||||||
|
# Not Telnetmode.
|
||||||
|
#
|
||||||
|
# We cannot use preprocess() on this data, because that
|
||||||
|
# method makes some Telnetmode-specific assumptions.
|
||||||
|
buf = rest + c
|
||||||
|
rest = ''
|
||||||
|
unless @options["Binmode"]
|
||||||
|
if pt = buf.rindex(/\r\z/no)
|
||||||
|
buf = buf[0 ... pt]
|
||||||
|
rest = buf[pt .. -1]
|
||||||
|
end
|
||||||
|
buf.gsub!(/#{EOL}/no, "\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@log.print(buf) if @options.has_key?("Output_log")
|
||||||
|
line += buf
|
||||||
|
yield buf if block_given?
|
||||||
|
rescue EOFError # End of file reached
|
||||||
|
raise if fail_eof
|
||||||
|
if line == ''
|
||||||
|
line = nil
|
||||||
|
yield nil if block_given?
|
||||||
|
end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
line
|
||||||
end
|
end
|
||||||
@log.print(buf) if @options.has_key?("Output_log")
|
|
||||||
line += buf
|
# Write +string+ to the host.
|
||||||
yield buf if block_given?
|
#
|
||||||
rescue EOFError # End of file reached
|
# Does not perform any conversions on +string+. Will log +string+ to the
|
||||||
raise if fail_eof
|
# dumplog, if the Dump_log option is set.
|
||||||
if line == ''
|
def write(string)
|
||||||
line = nil
|
length = string.length
|
||||||
yield nil if block_given?
|
while 0 < length
|
||||||
|
IO::select(nil, [@sock])
|
||||||
|
@dumplog.log_dump('>', string[-length..-1]) if @options.has_key?("Dump_log")
|
||||||
|
length -= @sock.syswrite(string[-length..-1])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
line
|
|
||||||
end
|
|
||||||
|
|
||||||
# Write +string+ to the host.
|
# Sends a string to the host.
|
||||||
#
|
#
|
||||||
# Does not perform any conversions on +string+. Will log +string+ to the
|
# This does _not_ automatically append a newline to the string. Embedded
|
||||||
# dumplog, if the Dump_log option is set.
|
# newlines may be converted and telnet command sequences escaped
|
||||||
def write(string)
|
# depending upon the values of telnetmode, binmode, and telnet options
|
||||||
length = string.length
|
# set by the host.
|
||||||
while 0 < length
|
def print(string)
|
||||||
IO::select(nil, [@sock])
|
string = string.gsub(/#{IAC}/no, IAC + IAC) if @options["Telnetmode"]
|
||||||
@dumplog.log_dump('>', string[-length..-1]) if @options.has_key?("Dump_log")
|
|
||||||
length -= @sock.syswrite(string[-length..-1])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sends a string to the host.
|
if @options["Binmode"]
|
||||||
#
|
self.write(string)
|
||||||
# This does _not_ automatically append a newline to the string. Embedded
|
else
|
||||||
# newlines may be converted and telnet command sequences escaped
|
if @telnet_option["BINARY"] and @telnet_option["SGA"]
|
||||||
# depending upon the values of telnetmode, binmode, and telnet options
|
# IAC WILL SGA IAC DO BIN send EOL --> CR
|
||||||
# set by the host.
|
self.write(string.gsub(/\n/n, CR))
|
||||||
def print(string)
|
elsif @telnet_option["SGA"]
|
||||||
string = string.gsub(/#{IAC}/no, IAC + IAC) if @options["Telnetmode"]
|
# IAC WILL SGA send EOL --> CR+NULL
|
||||||
|
self.write(string.gsub(/\n/n, CR + NULL))
|
||||||
|
else
|
||||||
|
# NONE send EOL --> CR+LF
|
||||||
|
self.write(string.gsub(/\n/n, EOL))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if @options["Binmode"]
|
# Sends a string to the host.
|
||||||
self.write(string)
|
#
|
||||||
else
|
# Same as #print(), but appends a newline to the string.
|
||||||
if @telnet_option["BINARY"] and @telnet_option["SGA"]
|
def puts(string)
|
||||||
# IAC WILL SGA IAC DO BIN send EOL --> CR
|
self.print(string + "\n")
|
||||||
self.write(string.gsub(/\n/n, CR))
|
end
|
||||||
elsif @telnet_option["SGA"]
|
|
||||||
# IAC WILL SGA send EOL --> CR+NULL
|
|
||||||
self.write(string.gsub(/\n/n, CR + NULL))
|
|
||||||
else
|
|
||||||
# NONE send EOL --> CR+LF
|
|
||||||
self.write(string.gsub(/\n/n, EOL))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sends a string to the host.
|
# Send a command to the host.
|
||||||
#
|
#
|
||||||
# Same as #print(), but appends a newline to the string.
|
# More exactly, sends a string to the host, and reads in all received
|
||||||
def puts(string)
|
# data until is sees the prompt or other matched sequence.
|
||||||
self.print(string + "\n")
|
#
|
||||||
end
|
# If a block is given, the received data will be yielded to it as
|
||||||
|
# it is read in. Whether a block is given or not, the received data
|
||||||
|
# will be return as a string. Note that the received data includes
|
||||||
|
# the prompt and in most cases the host's echo of our command.
|
||||||
|
#
|
||||||
|
# +options+ is either a String, specified the string or command to
|
||||||
|
# send to the host; or it is a hash of options. If a hash, the
|
||||||
|
# following options can be specified:
|
||||||
|
#
|
||||||
|
# String:: the command or other string to send to the host.
|
||||||
|
# Match:: a regular expression, the sequence to look for in
|
||||||
|
# the received data before returning. If not specified,
|
||||||
|
# the Prompt option value specified when this instance
|
||||||
|
# was created will be used, or, failing that, the default
|
||||||
|
# prompt of /[$%#>] \z/n.
|
||||||
|
# Timeout:: the seconds to wait for data from the host before raising
|
||||||
|
# a Timeout error. If not specified, the Timeout option
|
||||||
|
# value specified when this instance was created will be
|
||||||
|
# used, or, failing that, the default value of 10 seconds.
|
||||||
|
#
|
||||||
|
# The command or other string will have the newline sequence appended
|
||||||
|
# to it.
|
||||||
|
def cmd(options) # :yield: recvdata
|
||||||
|
match = @options["Prompt"]
|
||||||
|
time_out = @options["Timeout"]
|
||||||
|
fail_eof = @options["FailEOF"]
|
||||||
|
|
||||||
# Send a command to the host.
|
if options.kind_of?(Hash)
|
||||||
#
|
string = options["String"]
|
||||||
# More exactly, sends a string to the host, and reads in all received
|
match = options["Match"] if options.has_key?("Match")
|
||||||
# data until is sees the prompt or other matched sequence.
|
time_out = options["Timeout"] if options.has_key?("Timeout")
|
||||||
#
|
fail_eof = options["FailEOF"] if options.has_key?("FailEOF")
|
||||||
# If a block is given, the received data will be yielded to it as
|
else
|
||||||
# it is read in. Whether a block is given or not, the received data
|
string = options
|
||||||
# will be return as a string. Note that the received data includes
|
end
|
||||||
# the prompt and in most cases the host's echo of our command.
|
|
||||||
#
|
|
||||||
# +options+ is either a String, specified the string or command to
|
|
||||||
# send to the host; or it is a hash of options. If a hash, the
|
|
||||||
# following options can be specified:
|
|
||||||
#
|
|
||||||
# String:: the command or other string to send to the host.
|
|
||||||
# Match:: a regular expression, the sequence to look for in
|
|
||||||
# the received data before returning. If not specified,
|
|
||||||
# the Prompt option value specified when this instance
|
|
||||||
# was created will be used, or, failing that, the default
|
|
||||||
# prompt of /[$%#>] \z/n.
|
|
||||||
# Timeout:: the seconds to wait for data from the host before raising
|
|
||||||
# a Timeout error. If not specified, the Timeout option
|
|
||||||
# value specified when this instance was created will be
|
|
||||||
# used, or, failing that, the default value of 10 seconds.
|
|
||||||
#
|
|
||||||
# The command or other string will have the newline sequence appended
|
|
||||||
# to it.
|
|
||||||
def cmd(options) # :yield: recvdata
|
|
||||||
match = @options["Prompt"]
|
|
||||||
time_out = @options["Timeout"]
|
|
||||||
fail_eof = @options["FailEOF"]
|
|
||||||
|
|
||||||
if options.kind_of?(Hash)
|
self.puts(string)
|
||||||
string = options["String"]
|
if block_given?
|
||||||
match = options["Match"] if options.has_key?("Match")
|
waitfor({"Prompt" => match, "Timeout" => time_out, "FailEOF" => fail_eof}){|c| yield c }
|
||||||
time_out = options["Timeout"] if options.has_key?("Timeout")
|
else
|
||||||
fail_eof = options["FailEOF"] if options.has_key?("FailEOF")
|
waitfor({"Prompt" => match, "Timeout" => time_out, "FailEOF" => fail_eof})
|
||||||
else
|
end
|
||||||
string = options
|
end
|
||||||
end
|
|
||||||
|
|
||||||
self.puts(string)
|
# Login to the host with a given username and password.
|
||||||
if block_given?
|
#
|
||||||
waitfor({"Prompt" => match, "Timeout" => time_out, "FailEOF" => fail_eof}){|c| yield c }
|
# The username and password can either be provided as two string
|
||||||
else
|
# arguments in that order, or as a hash with keys "Name" and
|
||||||
waitfor({"Prompt" => match, "Timeout" => time_out, "FailEOF" => fail_eof})
|
# "Password".
|
||||||
end
|
#
|
||||||
end
|
# This method looks for the strings "login" and "Password" from the
|
||||||
|
# host to determine when to send the username and password. If the
|
||||||
|
# login sequence does not follow this pattern (for instance, you
|
||||||
|
# are connecting to a service other than telnet), you will need
|
||||||
|
# to handle login yourself.
|
||||||
|
#
|
||||||
|
# The password can be omitted, either by only
|
||||||
|
# provided one String argument, which will be used as the username,
|
||||||
|
# or by providing a has that has no "Password" key. In this case,
|
||||||
|
# the method will not look for the "Password:" prompt; if it is
|
||||||
|
# sent, it will have to be dealt with by later calls.
|
||||||
|
#
|
||||||
|
# The method returns all data received during the login process from
|
||||||
|
# the host, including the echoed username but not the password (which
|
||||||
|
# the host should not echo). If a block is passed in, this received
|
||||||
|
# data is also yielded to the block as it is received.
|
||||||
|
def login(options, password = nil) # :yield: recvdata
|
||||||
|
login_prompt = /[Ll]ogin[: ]*\z/n
|
||||||
|
password_prompt = /[Pp]ass(?:word|phrase)[: ]*\z/n
|
||||||
|
if options.kind_of?(Hash)
|
||||||
|
username = options["Name"]
|
||||||
|
password = options["Password"]
|
||||||
|
login_prompt = options["LoginPrompt"] if options["LoginPrompt"]
|
||||||
|
password_prompt = options["PasswordPrompt"] if options["PasswordPrompt"]
|
||||||
|
else
|
||||||
|
username = options
|
||||||
|
end
|
||||||
|
|
||||||
# Login to the host with a given username and password.
|
if block_given?
|
||||||
#
|
line = waitfor(login_prompt){|c| yield c }
|
||||||
# The username and password can either be provided as two string
|
if password
|
||||||
# arguments in that order, or as a hash with keys "Name" and
|
line += cmd({"String" => username,
|
||||||
# "Password".
|
"Match" => password_prompt}){|c| yield c }
|
||||||
#
|
line += cmd(password){|c| yield c }
|
||||||
# This method looks for the strings "login" and "Password" from the
|
else
|
||||||
# host to determine when to send the username and password. If the
|
line += cmd(username){|c| yield c }
|
||||||
# login sequence does not follow this pattern (for instance, you
|
end
|
||||||
# are connecting to a service other than telnet), you will need
|
else
|
||||||
# to handle login yourself.
|
line = waitfor(login_prompt)
|
||||||
#
|
if password
|
||||||
# The password can be omitted, either by only
|
line += cmd({"String" => username,
|
||||||
# provided one String argument, which will be used as the username,
|
"Match" => password_prompt})
|
||||||
# or by providing a has that has no "Password" key. In this case,
|
line += cmd(password)
|
||||||
# the method will not look for the "Password:" prompt; if it is
|
else
|
||||||
# sent, it will have to be dealt with by later calls.
|
line += cmd(username)
|
||||||
#
|
end
|
||||||
# The method returns all data received during the login process from
|
end
|
||||||
# the host, including the echoed username but not the password (which
|
line
|
||||||
# the host should not echo). If a block is passed in, this received
|
end
|
||||||
# data is also yielded to the block as it is received.
|
|
||||||
def login(options, password = nil) # :yield: recvdata
|
|
||||||
login_prompt = /[Ll]ogin[: ]*\z/n
|
|
||||||
password_prompt = /[Pp]ass(?:word|phrase)[: ]*\z/n
|
|
||||||
if options.kind_of?(Hash)
|
|
||||||
username = options["Name"]
|
|
||||||
password = options["Password"]
|
|
||||||
login_prompt = options["LoginPrompt"] if options["LoginPrompt"]
|
|
||||||
password_prompt = options["PasswordPrompt"] if options["PasswordPrompt"]
|
|
||||||
else
|
|
||||||
username = options
|
|
||||||
end
|
|
||||||
|
|
||||||
if block_given?
|
# Closes the connection
|
||||||
line = waitfor(login_prompt){|c| yield c }
|
def close
|
||||||
if password
|
@sock.close
|
||||||
line += cmd({"String" => username,
|
end
|
||||||
"Match" => password_prompt}){|c| yield c }
|
|
||||||
line += cmd(password){|c| yield c }
|
|
||||||
else
|
|
||||||
line += cmd(username){|c| yield c }
|
|
||||||
end
|
|
||||||
else
|
|
||||||
line = waitfor(login_prompt)
|
|
||||||
if password
|
|
||||||
line += cmd({"String" => username,
|
|
||||||
"Match" => password_prompt})
|
|
||||||
line += cmd(password)
|
|
||||||
else
|
|
||||||
line += cmd(username)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
line
|
|
||||||
end
|
|
||||||
|
|
||||||
# Closes the connection
|
end # class Telnet
|
||||||
def close
|
end # module Net
|
||||||
@sock.close
|
|
||||||
end
|
|
||||||
|
|
||||||
end # class Telnet
|
|
||||||
end # module Net
|
|
||||||
|
|
||||||
|
@ -205,9 +205,9 @@ module Open3
|
|||||||
result = [*parent_io, wait_thr]
|
result = [*parent_io, wait_thr]
|
||||||
if defined? yield
|
if defined? yield
|
||||||
begin
|
begin
|
||||||
return yield(*result)
|
return yield(*result)
|
||||||
ensure
|
ensure
|
||||||
parent_io.each{|io| io.close unless io.closed?}
|
parent_io.each{|io| io.close unless io.closed?}
|
||||||
wait_thr.join
|
wait_thr.join
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -700,9 +700,9 @@ module Open3
|
|||||||
child_io.each {|io| io.close }
|
child_io.each {|io| io.close }
|
||||||
if defined? yield
|
if defined? yield
|
||||||
begin
|
begin
|
||||||
return yield(*result)
|
return yield(*result)
|
||||||
ensure
|
ensure
|
||||||
parent_io.each{|io| io.close unless io.closed?}
|
parent_io.each{|io| io.close unless io.closed?}
|
||||||
wait_thrs.each {|t| t.join }
|
wait_thrs.each {|t| t.join }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
752
lib/prime.rb
752
lib/prime.rb
@ -99,397 +99,397 @@ class Prime
|
|||||||
|
|
||||||
def method_added(method) # :nodoc:
|
def method_added(method) # :nodoc:
|
||||||
(class<< self;self;end).def_delegator :instance, method
|
(class<< self;self;end).def_delegator :instance, method
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Iterates the given block over all prime numbers.
|
||||||
|
#
|
||||||
|
# == Parameters
|
||||||
|
# +ubound+::
|
||||||
|
# Optional. An arbitrary positive number.
|
||||||
|
# The upper bound of enumeration. The method enumerates
|
||||||
|
# prime numbers infinitely if +ubound+ is nil.
|
||||||
|
# +generator+::
|
||||||
|
# Optional. An implementation of pseudo-prime generator.
|
||||||
|
#
|
||||||
|
# == Return value
|
||||||
|
# An evaluated value of the given block at the last time.
|
||||||
|
# Or an enumerator which is compatible to an +Enumerator+
|
||||||
|
# if no block given.
|
||||||
|
#
|
||||||
|
# == Description
|
||||||
|
# Calls +block+ once for each prime number, passing the prime as
|
||||||
|
# a parameter.
|
||||||
|
#
|
||||||
|
# +ubound+::
|
||||||
|
# Upper bound of prime numbers. The iterator stops after
|
||||||
|
# yields all prime numbers p <= +ubound+.
|
||||||
|
#
|
||||||
|
# == Note
|
||||||
|
# +Prime+.+new+ returns a object extended by +Prime+::+OldCompatibility+
|
||||||
|
# in order to compatibility to Ruby 1.8, and +Prime+#each is overwritten
|
||||||
|
# by +Prime+::+OldCompatibility+#+each+.
|
||||||
|
#
|
||||||
|
# +Prime+.+new+ is now obsolete. Use +Prime+.+instance+.+each+ or simply
|
||||||
|
# +Prime+.+each+.
|
||||||
|
def each(ubound = nil, generator = EratosthenesGenerator.new, &block)
|
||||||
|
generator.upper_bound = ubound
|
||||||
|
generator.each(&block)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Returns true if +value+ is prime, false for a composite.
|
||||||
|
#
|
||||||
|
# == Parameters
|
||||||
|
# +value+:: an arbitrary integer to be checked.
|
||||||
|
# +generator+:: optional. A pseudo-prime generator.
|
||||||
|
def prime?(value, generator = Prime::Generator23.new)
|
||||||
|
value = -value if value < 0
|
||||||
|
return false if value < 2
|
||||||
|
for num in generator
|
||||||
|
q,r = value.divmod num
|
||||||
|
return true if q < num
|
||||||
|
return false if r == 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Re-composes a prime factorization and returns the product.
|
||||||
|
#
|
||||||
|
# == Parameters
|
||||||
|
# +pd+:: Array of pairs of integers. The each internal
|
||||||
|
# pair consists of a prime number -- a prime factor --
|
||||||
|
# and a natural number -- an exponent.
|
||||||
|
#
|
||||||
|
# == Example
|
||||||
|
# For [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]], it returns
|
||||||
|
# p_1**e_1 * p_2**e_2 * .... * p_n**e_n.
|
||||||
|
#
|
||||||
|
# Prime.int_from_prime_division([[2,2], [3,1]]) #=> 12
|
||||||
|
def int_from_prime_division(pd)
|
||||||
|
pd.inject(1){|value, (prime, index)|
|
||||||
|
value *= prime**index
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the factorization of +value+.
|
||||||
|
#
|
||||||
|
# == Parameters
|
||||||
|
# +value+:: An arbitrary integer.
|
||||||
|
# +generator+:: Optional. A pseudo-prime generator.
|
||||||
|
# +generator+.succ must return the next
|
||||||
|
# pseudo-prime number in the ascendent
|
||||||
|
# order. It must generate all prime numbers,
|
||||||
|
# but may generate non prime numbers.
|
||||||
|
#
|
||||||
|
# === Exceptions
|
||||||
|
# +ZeroDivisionError+:: when +value+ is zero.
|
||||||
|
#
|
||||||
|
# == Example
|
||||||
|
# For an arbitrary integer
|
||||||
|
# n = p_1**e_1 * p_2**e_2 * .... * p_n**e_n,
|
||||||
|
# prime_division(n) returns
|
||||||
|
# [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]].
|
||||||
|
#
|
||||||
|
# Prime.prime_division(12) #=> [[2,2], [3,1]]
|
||||||
|
#
|
||||||
|
def prime_division(value, generator= Prime::Generator23.new)
|
||||||
|
raise ZeroDivisionError if value == 0
|
||||||
|
if value < 0
|
||||||
|
value = -value
|
||||||
|
pv = [[-1, 1]]
|
||||||
|
else
|
||||||
|
pv = []
|
||||||
|
end
|
||||||
|
for prime in generator
|
||||||
|
count = 0
|
||||||
|
while (value1, mod = value.divmod(prime)
|
||||||
|
mod) == 0
|
||||||
|
value = value1
|
||||||
|
count += 1
|
||||||
end
|
end
|
||||||
end
|
if count != 0
|
||||||
|
pv.push [prime, count]
|
||||||
# Iterates the given block over all prime numbers.
|
|
||||||
#
|
|
||||||
# == Parameters
|
|
||||||
# +ubound+::
|
|
||||||
# Optional. An arbitrary positive number.
|
|
||||||
# The upper bound of enumeration. The method enumerates
|
|
||||||
# prime numbers infinitely if +ubound+ is nil.
|
|
||||||
# +generator+::
|
|
||||||
# Optional. An implementation of pseudo-prime generator.
|
|
||||||
#
|
|
||||||
# == Return value
|
|
||||||
# An evaluated value of the given block at the last time.
|
|
||||||
# Or an enumerator which is compatible to an +Enumerator+
|
|
||||||
# if no block given.
|
|
||||||
#
|
|
||||||
# == Description
|
|
||||||
# Calls +block+ once for each prime number, passing the prime as
|
|
||||||
# a parameter.
|
|
||||||
#
|
|
||||||
# +ubound+::
|
|
||||||
# Upper bound of prime numbers. The iterator stops after
|
|
||||||
# yields all prime numbers p <= +ubound+.
|
|
||||||
#
|
|
||||||
# == Note
|
|
||||||
# +Prime+.+new+ returns a object extended by +Prime+::+OldCompatibility+
|
|
||||||
# in order to compatibility to Ruby 1.8, and +Prime+#each is overwritten
|
|
||||||
# by +Prime+::+OldCompatibility+#+each+.
|
|
||||||
#
|
|
||||||
# +Prime+.+new+ is now obsolete. Use +Prime+.+instance+.+each+ or simply
|
|
||||||
# +Prime+.+each+.
|
|
||||||
def each(ubound = nil, generator = EratosthenesGenerator.new, &block)
|
|
||||||
generator.upper_bound = ubound
|
|
||||||
generator.each(&block)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# Returns true if +value+ is prime, false for a composite.
|
|
||||||
#
|
|
||||||
# == Parameters
|
|
||||||
# +value+:: an arbitrary integer to be checked.
|
|
||||||
# +generator+:: optional. A pseudo-prime generator.
|
|
||||||
def prime?(value, generator = Prime::Generator23.new)
|
|
||||||
value = -value if value < 0
|
|
||||||
return false if value < 2
|
|
||||||
for num in generator
|
|
||||||
q,r = value.divmod num
|
|
||||||
return true if q < num
|
|
||||||
return false if r == 0
|
|
||||||
end
|
end
|
||||||
|
break if value1 <= prime
|
||||||
|
end
|
||||||
|
if value > 1
|
||||||
|
pv.push [value, 1]
|
||||||
|
end
|
||||||
|
return pv
|
||||||
|
end
|
||||||
|
|
||||||
|
# An abstract class for enumerating pseudo-prime numbers.
|
||||||
|
#
|
||||||
|
# Concrete subclasses should override succ, next, rewind.
|
||||||
|
class PseudoPrimeGenerator
|
||||||
|
include Enumerable
|
||||||
|
|
||||||
|
def initialize(ubound = nil)
|
||||||
|
@ubound = ubound
|
||||||
end
|
end
|
||||||
|
|
||||||
# Re-composes a prime factorization and returns the product.
|
def upper_bound=(ubound)
|
||||||
#
|
@ubound = ubound
|
||||||
# == Parameters
|
end
|
||||||
# +pd+:: Array of pairs of integers. The each internal
|
def upper_bound
|
||||||
# pair consists of a prime number -- a prime factor --
|
@ubound
|
||||||
# and a natural number -- an exponent.
|
|
||||||
#
|
|
||||||
# == Example
|
|
||||||
# For [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]], it returns
|
|
||||||
# p_1**e_1 * p_2**e_2 * .... * p_n**e_n.
|
|
||||||
#
|
|
||||||
# Prime.int_from_prime_division([[2,2], [3,1]]) #=> 12
|
|
||||||
def int_from_prime_division(pd)
|
|
||||||
pd.inject(1){|value, (prime, index)|
|
|
||||||
value *= prime**index
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the factorization of +value+.
|
# returns the next pseudo-prime number, and move the internal
|
||||||
|
# position forward.
|
||||||
#
|
#
|
||||||
# == Parameters
|
# +PseudoPrimeGenerator+#succ raises +NotImplementedError+.
|
||||||
# +value+:: An arbitrary integer.
|
def succ
|
||||||
# +generator+:: Optional. A pseudo-prime generator.
|
raise NotImplementedError, "need to define `succ'"
|
||||||
# +generator+.succ must return the next
|
end
|
||||||
# pseudo-prime number in the ascendent
|
|
||||||
# order. It must generate all prime numbers,
|
# alias of +succ+.
|
||||||
# but may generate non prime numbers.
|
def next
|
||||||
|
raise NotImplementedError, "need to define `next'"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Rewinds the internal position for enumeration.
|
||||||
#
|
#
|
||||||
# === Exceptions
|
# See +Enumerator+#rewind.
|
||||||
# +ZeroDivisionError+:: when +value+ is zero.
|
def rewind
|
||||||
#
|
raise NotImplementedError, "need to define `rewind'"
|
||||||
# == Example
|
end
|
||||||
# For an arbitrary integer
|
|
||||||
# n = p_1**e_1 * p_2**e_2 * .... * p_n**e_n,
|
# Iterates the given block for each prime numbers.
|
||||||
# prime_division(n) returns
|
def each(&block)
|
||||||
# [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]].
|
return self.dup unless block
|
||||||
#
|
if @ubound
|
||||||
# Prime.prime_division(12) #=> [[2,2], [3,1]]
|
last_value = nil
|
||||||
#
|
loop do
|
||||||
def prime_division(value, generator= Prime::Generator23.new)
|
prime = succ
|
||||||
raise ZeroDivisionError if value == 0
|
break last_value if prime > @ubound
|
||||||
if value < 0
|
last_value = block.call(prime)
|
||||||
value = -value
|
end
|
||||||
pv = [[-1, 1]]
|
|
||||||
else
|
else
|
||||||
pv = []
|
|
||||||
end
|
|
||||||
for prime in generator
|
|
||||||
count = 0
|
|
||||||
while (value1, mod = value.divmod(prime)
|
|
||||||
mod) == 0
|
|
||||||
value = value1
|
|
||||||
count += 1
|
|
||||||
end
|
|
||||||
if count != 0
|
|
||||||
pv.push [prime, count]
|
|
||||||
end
|
|
||||||
break if value1 <= prime
|
|
||||||
end
|
|
||||||
if value > 1
|
|
||||||
pv.push [value, 1]
|
|
||||||
end
|
|
||||||
return pv
|
|
||||||
end
|
|
||||||
|
|
||||||
# An abstract class for enumerating pseudo-prime numbers.
|
|
||||||
#
|
|
||||||
# Concrete subclasses should override succ, next, rewind.
|
|
||||||
class PseudoPrimeGenerator
|
|
||||||
include Enumerable
|
|
||||||
|
|
||||||
def initialize(ubound = nil)
|
|
||||||
@ubound = ubound
|
|
||||||
end
|
|
||||||
|
|
||||||
def upper_bound=(ubound)
|
|
||||||
@ubound = ubound
|
|
||||||
end
|
|
||||||
def upper_bound
|
|
||||||
@ubound
|
|
||||||
end
|
|
||||||
|
|
||||||
# returns the next pseudo-prime number, and move the internal
|
|
||||||
# position forward.
|
|
||||||
#
|
|
||||||
# +PseudoPrimeGenerator+#succ raises +NotImplementedError+.
|
|
||||||
def succ
|
|
||||||
raise NotImplementedError, "need to define `succ'"
|
|
||||||
end
|
|
||||||
|
|
||||||
# alias of +succ+.
|
|
||||||
def next
|
|
||||||
raise NotImplementedError, "need to define `next'"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Rewinds the internal position for enumeration.
|
|
||||||
#
|
|
||||||
# See +Enumerator+#rewind.
|
|
||||||
def rewind
|
|
||||||
raise NotImplementedError, "need to define `rewind'"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Iterates the given block for each prime numbers.
|
|
||||||
def each(&block)
|
|
||||||
return self.dup unless block
|
|
||||||
if @ubound
|
|
||||||
last_value = nil
|
|
||||||
loop do
|
|
||||||
prime = succ
|
|
||||||
break last_value if prime > @ubound
|
|
||||||
last_value = block.call(prime)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
loop do
|
|
||||||
block.call(succ)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# see +Enumerator+#with_index.
|
|
||||||
alias with_index each_with_index
|
|
||||||
|
|
||||||
# see +Enumerator+#with_object.
|
|
||||||
def with_object(obj)
|
|
||||||
return enum_for(:with_object) unless block_given?
|
|
||||||
each do |prime|
|
|
||||||
yield prime, obj
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# An implementation of +PseudoPrimeGenerator+.
|
|
||||||
#
|
|
||||||
# Uses +EratosthenesSieve+.
|
|
||||||
class EratosthenesGenerator < PseudoPrimeGenerator
|
|
||||||
def initialize
|
|
||||||
@last_prime = nil
|
|
||||||
super
|
|
||||||
end
|
|
||||||
|
|
||||||
def succ
|
|
||||||
@last_prime = @last_prime ? EratosthenesSieve.instance.next_to(@last_prime) : 2
|
|
||||||
end
|
|
||||||
def rewind
|
|
||||||
initialize
|
|
||||||
end
|
|
||||||
alias next succ
|
|
||||||
end
|
|
||||||
|
|
||||||
# An implementation of +PseudoPrimeGenerator+ which uses
|
|
||||||
# a prime table generated by trial division.
|
|
||||||
class TrialDivisionGenerator<PseudoPrimeGenerator
|
|
||||||
def initialize
|
|
||||||
@index = -1
|
|
||||||
super
|
|
||||||
end
|
|
||||||
|
|
||||||
def succ
|
|
||||||
TrialDivision.instance[@index += 1]
|
|
||||||
end
|
|
||||||
def rewind
|
|
||||||
initialize
|
|
||||||
end
|
|
||||||
alias next succ
|
|
||||||
end
|
|
||||||
|
|
||||||
# Generates all integer which are greater than 2 and
|
|
||||||
# are not divided by 2 nor 3.
|
|
||||||
#
|
|
||||||
# This is a pseudo-prime generator, suitable on
|
|
||||||
# checking primality of a integer by brute force
|
|
||||||
# method.
|
|
||||||
class Generator23<PseudoPrimeGenerator
|
|
||||||
def initialize
|
|
||||||
@prime = 1
|
|
||||||
@step = nil
|
|
||||||
super
|
|
||||||
end
|
|
||||||
|
|
||||||
def succ
|
|
||||||
loop do
|
loop do
|
||||||
if (@step)
|
block.call(succ)
|
||||||
@prime += @step
|
|
||||||
@step = 6 - @step
|
|
||||||
else
|
|
||||||
case @prime
|
|
||||||
when 1; @prime = 2
|
|
||||||
when 2; @prime = 3
|
|
||||||
when 3; @prime = 5; @step = 2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return @prime
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias next succ
|
|
||||||
def rewind
|
|
||||||
initialize
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# see +Enumerator+#with_index.
|
||||||
|
alias with_index each_with_index
|
||||||
|
|
||||||
|
# see +Enumerator+#with_object.
|
||||||
|
def with_object(obj)
|
||||||
# Internal use. An implementation of prime table by trial division method.
|
return enum_for(:with_object) unless block_given?
|
||||||
class TrialDivision
|
each do |prime|
|
||||||
include Singleton
|
yield prime, obj
|
||||||
|
|
||||||
def initialize # :nodoc:
|
|
||||||
# These are included as class variables to cache them for later uses. If memory
|
|
||||||
# usage is a problem, they can be put in Prime#initialize as instance variables.
|
|
||||||
|
|
||||||
# There must be no primes between @primes[-1] and @next_to_check.
|
|
||||||
@primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
|
|
||||||
# @next_to_check % 6 must be 1.
|
|
||||||
@next_to_check = 103 # @primes[-1] - @primes[-1] % 6 + 7
|
|
||||||
@ulticheck_index = 3 # @primes.index(@primes.reverse.find {|n|
|
|
||||||
# n < Math.sqrt(@@next_to_check) })
|
|
||||||
@ulticheck_next_squared = 121 # @primes[@ulticheck_index + 1] ** 2
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the cached prime numbers.
|
|
||||||
def cache
|
|
||||||
return @primes
|
|
||||||
end
|
|
||||||
alias primes cache
|
|
||||||
alias primes_so_far cache
|
|
||||||
|
|
||||||
# Returns the +index+th prime number.
|
|
||||||
#
|
|
||||||
# +index+ is a 0-based index.
|
|
||||||
def [](index)
|
|
||||||
while index >= @primes.length
|
|
||||||
# Only check for prime factors up to the square root of the potential primes,
|
|
||||||
# but without the performance hit of an actual square root calculation.
|
|
||||||
if @next_to_check + 4 > @ulticheck_next_squared
|
|
||||||
@ulticheck_index += 1
|
|
||||||
@ulticheck_next_squared = @primes.at(@ulticheck_index + 1) ** 2
|
|
||||||
end
|
|
||||||
# Only check numbers congruent to one and five, modulo six. All others
|
|
||||||
|
|
||||||
# are divisible by two or three. This also allows us to skip checking against
|
|
||||||
# two and three.
|
|
||||||
@primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?
|
|
||||||
@next_to_check += 4
|
|
||||||
@primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?
|
|
||||||
@next_to_check += 2
|
|
||||||
end
|
|
||||||
return @primes[index]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Internal use. An implementation of eratosthenes's sieve
|
|
||||||
class EratosthenesSieve
|
|
||||||
include Singleton
|
|
||||||
|
|
||||||
BITS_PER_ENTRY = 16 # each entry is a set of 16-bits in a Fixnum
|
|
||||||
NUMS_PER_ENTRY = BITS_PER_ENTRY * 2 # twiced because even numbers are omitted
|
|
||||||
ENTRIES_PER_TABLE = 8
|
|
||||||
NUMS_PER_TABLE = NUMS_PER_ENTRY * ENTRIES_PER_TABLE
|
|
||||||
FILLED_ENTRY = (1 << NUMS_PER_ENTRY) - 1
|
|
||||||
|
|
||||||
def initialize # :nodoc:
|
|
||||||
# bitmap for odd prime numbers less than 256.
|
|
||||||
# For an arbitrary odd number n, @tables[i][j][k] is
|
|
||||||
# * 1 if n is prime,
|
|
||||||
# * 0 if n is composite,
|
|
||||||
# where i,j,k = indices(n)
|
|
||||||
@tables = [[0xcb6e, 0x64b4, 0x129a, 0x816d, 0x4c32, 0x864a, 0x820d, 0x2196].freeze]
|
|
||||||
end
|
|
||||||
|
|
||||||
# returns the least odd prime number which is greater than +n+.
|
|
||||||
def next_to(n)
|
|
||||||
n = (n-1).div(2)*2+3 # the next odd number to given n
|
|
||||||
table_index, integer_index, bit_index = indices(n)
|
|
||||||
loop do
|
|
||||||
extend_table until @tables.length > table_index
|
|
||||||
for j in integer_index...ENTRIES_PER_TABLE
|
|
||||||
if !@tables[table_index][j].zero?
|
|
||||||
for k in bit_index...BITS_PER_ENTRY
|
|
||||||
return NUMS_PER_TABLE*table_index + NUMS_PER_ENTRY*j + 2*k+1 if !@tables[table_index][j][k].zero?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
bit_index = 0
|
|
||||||
end
|
|
||||||
table_index += 1; integer_index = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
# for an odd number +n+, returns (i, j, k) such that @tables[i][j][k] represents primarity of the number
|
|
||||||
def indices(n)
|
|
||||||
# binary digits of n: |0|1|2|3|4|5|6|7|8|9|10|11|....
|
|
||||||
# indices: |-| k | j | i
|
|
||||||
# because of NUMS_PER_ENTRY, NUMS_PER_TABLE
|
|
||||||
|
|
||||||
k = (n & 0b00011111) >> 1
|
|
||||||
j = (n & 0b11100000) >> 5
|
|
||||||
i = n >> 8
|
|
||||||
return i, j, k
|
|
||||||
end
|
|
||||||
|
|
||||||
def extend_table
|
|
||||||
lbound = NUMS_PER_TABLE * @tables.length
|
|
||||||
ubound = lbound + NUMS_PER_TABLE
|
|
||||||
new_table = [FILLED_ENTRY] * ENTRIES_PER_TABLE # which represents primarity in lbound...ubound
|
|
||||||
(3..Integer(Math.sqrt(ubound))).step(2) do |p|
|
|
||||||
i, j, k = indices(p)
|
|
||||||
next if @tables[i][j][k].zero?
|
|
||||||
|
|
||||||
start = (lbound.div(p)+1)*p # least multiple of p which is >= lbound
|
|
||||||
start += p if start.even?
|
|
||||||
(start...ubound).step(2*p) do |n|
|
|
||||||
_, j, k = indices(n)
|
|
||||||
new_table[j] &= FILLED_ENTRY^(1<<k)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@tables << new_table.freeze
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Provides a +Prime+ object with compatibility to Ruby 1.8 when instantiated via +Prime+.+new+.
|
|
||||||
module OldCompatibility
|
|
||||||
# Returns the next prime number and forwards internal pointer.
|
|
||||||
def succ
|
|
||||||
@generator.succ
|
|
||||||
end
|
|
||||||
alias next succ
|
|
||||||
|
|
||||||
# Overwrites Prime#each.
|
|
||||||
#
|
|
||||||
# Iterates the given block over all prime numbers. Note that enumeration starts from
|
|
||||||
# the current position of internal pointer, not rewound.
|
|
||||||
def each(&block)
|
|
||||||
return @generator.dup unless block_given?
|
|
||||||
loop do
|
|
||||||
yield succ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# An implementation of +PseudoPrimeGenerator+.
|
||||||
|
#
|
||||||
|
# Uses +EratosthenesSieve+.
|
||||||
|
class EratosthenesGenerator < PseudoPrimeGenerator
|
||||||
|
def initialize
|
||||||
|
@last_prime = nil
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def succ
|
||||||
|
@last_prime = @last_prime ? EratosthenesSieve.instance.next_to(@last_prime) : 2
|
||||||
|
end
|
||||||
|
def rewind
|
||||||
|
initialize
|
||||||
|
end
|
||||||
|
alias next succ
|
||||||
|
end
|
||||||
|
|
||||||
|
# An implementation of +PseudoPrimeGenerator+ which uses
|
||||||
|
# a prime table generated by trial division.
|
||||||
|
class TrialDivisionGenerator<PseudoPrimeGenerator
|
||||||
|
def initialize
|
||||||
|
@index = -1
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def succ
|
||||||
|
TrialDivision.instance[@index += 1]
|
||||||
|
end
|
||||||
|
def rewind
|
||||||
|
initialize
|
||||||
|
end
|
||||||
|
alias next succ
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generates all integer which are greater than 2 and
|
||||||
|
# are not divided by 2 nor 3.
|
||||||
|
#
|
||||||
|
# This is a pseudo-prime generator, suitable on
|
||||||
|
# checking primality of a integer by brute force
|
||||||
|
# method.
|
||||||
|
class Generator23<PseudoPrimeGenerator
|
||||||
|
def initialize
|
||||||
|
@prime = 1
|
||||||
|
@step = nil
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def succ
|
||||||
|
loop do
|
||||||
|
if (@step)
|
||||||
|
@prime += @step
|
||||||
|
@step = 6 - @step
|
||||||
|
else
|
||||||
|
case @prime
|
||||||
|
when 1; @prime = 2
|
||||||
|
when 2; @prime = 3
|
||||||
|
when 3; @prime = 5; @step = 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return @prime
|
||||||
|
end
|
||||||
|
end
|
||||||
|
alias next succ
|
||||||
|
def rewind
|
||||||
|
initialize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Internal use. An implementation of prime table by trial division method.
|
||||||
|
class TrialDivision
|
||||||
|
include Singleton
|
||||||
|
|
||||||
|
def initialize # :nodoc:
|
||||||
|
# These are included as class variables to cache them for later uses. If memory
|
||||||
|
# usage is a problem, they can be put in Prime#initialize as instance variables.
|
||||||
|
|
||||||
|
# There must be no primes between @primes[-1] and @next_to_check.
|
||||||
|
@primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
|
||||||
|
# @next_to_check % 6 must be 1.
|
||||||
|
@next_to_check = 103 # @primes[-1] - @primes[-1] % 6 + 7
|
||||||
|
@ulticheck_index = 3 # @primes.index(@primes.reverse.find {|n|
|
||||||
|
# n < Math.sqrt(@@next_to_check) })
|
||||||
|
@ulticheck_next_squared = 121 # @primes[@ulticheck_index + 1] ** 2
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the cached prime numbers.
|
||||||
|
def cache
|
||||||
|
return @primes
|
||||||
|
end
|
||||||
|
alias primes cache
|
||||||
|
alias primes_so_far cache
|
||||||
|
|
||||||
|
# Returns the +index+th prime number.
|
||||||
|
#
|
||||||
|
# +index+ is a 0-based index.
|
||||||
|
def [](index)
|
||||||
|
while index >= @primes.length
|
||||||
|
# Only check for prime factors up to the square root of the potential primes,
|
||||||
|
# but without the performance hit of an actual square root calculation.
|
||||||
|
if @next_to_check + 4 > @ulticheck_next_squared
|
||||||
|
@ulticheck_index += 1
|
||||||
|
@ulticheck_next_squared = @primes.at(@ulticheck_index + 1) ** 2
|
||||||
|
end
|
||||||
|
# Only check numbers congruent to one and five, modulo six. All others
|
||||||
|
|
||||||
|
# are divisible by two or three. This also allows us to skip checking against
|
||||||
|
# two and three.
|
||||||
|
@primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?
|
||||||
|
@next_to_check += 4
|
||||||
|
@primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?
|
||||||
|
@next_to_check += 2
|
||||||
|
end
|
||||||
|
return @primes[index]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Internal use. An implementation of eratosthenes's sieve
|
||||||
|
class EratosthenesSieve
|
||||||
|
include Singleton
|
||||||
|
|
||||||
|
BITS_PER_ENTRY = 16 # each entry is a set of 16-bits in a Fixnum
|
||||||
|
NUMS_PER_ENTRY = BITS_PER_ENTRY * 2 # twiced because even numbers are omitted
|
||||||
|
ENTRIES_PER_TABLE = 8
|
||||||
|
NUMS_PER_TABLE = NUMS_PER_ENTRY * ENTRIES_PER_TABLE
|
||||||
|
FILLED_ENTRY = (1 << NUMS_PER_ENTRY) - 1
|
||||||
|
|
||||||
|
def initialize # :nodoc:
|
||||||
|
# bitmap for odd prime numbers less than 256.
|
||||||
|
# For an arbitrary odd number n, @tables[i][j][k] is
|
||||||
|
# * 1 if n is prime,
|
||||||
|
# * 0 if n is composite,
|
||||||
|
# where i,j,k = indices(n)
|
||||||
|
@tables = [[0xcb6e, 0x64b4, 0x129a, 0x816d, 0x4c32, 0x864a, 0x820d, 0x2196].freeze]
|
||||||
|
end
|
||||||
|
|
||||||
|
# returns the least odd prime number which is greater than +n+.
|
||||||
|
def next_to(n)
|
||||||
|
n = (n-1).div(2)*2+3 # the next odd number to given n
|
||||||
|
table_index, integer_index, bit_index = indices(n)
|
||||||
|
loop do
|
||||||
|
extend_table until @tables.length > table_index
|
||||||
|
for j in integer_index...ENTRIES_PER_TABLE
|
||||||
|
if !@tables[table_index][j].zero?
|
||||||
|
for k in bit_index...BITS_PER_ENTRY
|
||||||
|
return NUMS_PER_TABLE*table_index + NUMS_PER_ENTRY*j + 2*k+1 if !@tables[table_index][j][k].zero?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
bit_index = 0
|
||||||
|
end
|
||||||
|
table_index += 1; integer_index = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# for an odd number +n+, returns (i, j, k) such that @tables[i][j][k] represents primarity of the number
|
||||||
|
def indices(n)
|
||||||
|
# binary digits of n: |0|1|2|3|4|5|6|7|8|9|10|11|....
|
||||||
|
# indices: |-| k | j | i
|
||||||
|
# because of NUMS_PER_ENTRY, NUMS_PER_TABLE
|
||||||
|
|
||||||
|
k = (n & 0b00011111) >> 1
|
||||||
|
j = (n & 0b11100000) >> 5
|
||||||
|
i = n >> 8
|
||||||
|
return i, j, k
|
||||||
|
end
|
||||||
|
|
||||||
|
def extend_table
|
||||||
|
lbound = NUMS_PER_TABLE * @tables.length
|
||||||
|
ubound = lbound + NUMS_PER_TABLE
|
||||||
|
new_table = [FILLED_ENTRY] * ENTRIES_PER_TABLE # which represents primarity in lbound...ubound
|
||||||
|
(3..Integer(Math.sqrt(ubound))).step(2) do |p|
|
||||||
|
i, j, k = indices(p)
|
||||||
|
next if @tables[i][j][k].zero?
|
||||||
|
|
||||||
|
start = (lbound.div(p)+1)*p # least multiple of p which is >= lbound
|
||||||
|
start += p if start.even?
|
||||||
|
(start...ubound).step(2*p) do |n|
|
||||||
|
_, j, k = indices(n)
|
||||||
|
new_table[j] &= FILLED_ENTRY^(1<<k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@tables << new_table.freeze
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Provides a +Prime+ object with compatibility to Ruby 1.8 when instantiated via +Prime+.+new+.
|
||||||
|
module OldCompatibility
|
||||||
|
# Returns the next prime number and forwards internal pointer.
|
||||||
|
def succ
|
||||||
|
@generator.succ
|
||||||
|
end
|
||||||
|
alias next succ
|
||||||
|
|
||||||
|
# Overwrites Prime#each.
|
||||||
|
#
|
||||||
|
# Iterates the given block over all prime numbers. Note that enumeration starts from
|
||||||
|
# the current position of internal pointer, not rewound.
|
||||||
|
def each(&block)
|
||||||
|
return @generator.dup unless block_given?
|
||||||
|
loop do
|
||||||
|
yield succ
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@ -6,15 +6,15 @@ module REXML
|
|||||||
STOP = ']]>'
|
STOP = ']]>'
|
||||||
ILLEGAL = /(\]\]>)/
|
ILLEGAL = /(\]\]>)/
|
||||||
|
|
||||||
# Constructor. CData is data between <![CDATA[ ... ]]>
|
# Constructor. CData is data between <![CDATA[ ... ]]>
|
||||||
#
|
#
|
||||||
# _Examples_
|
# _Examples_
|
||||||
# CData.new( source )
|
# CData.new( source )
|
||||||
# CData.new( "Here is some CDATA" )
|
# CData.new( "Here is some CDATA" )
|
||||||
# CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element )
|
# CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element )
|
||||||
def initialize( first, whitespace=true, parent=nil )
|
def initialize( first, whitespace=true, parent=nil )
|
||||||
super( first, whitespace, parent, false, true, ILLEGAL )
|
super( first, whitespace, parent, false, true, ILLEGAL )
|
||||||
end
|
end
|
||||||
|
|
||||||
# Make a copy of this object
|
# Make a copy of this object
|
||||||
#
|
#
|
||||||
|
@ -7,7 +7,7 @@ module REXML
|
|||||||
# class directly.
|
# class directly.
|
||||||
class Child
|
class Child
|
||||||
include Node
|
include Node
|
||||||
attr_reader :parent # The Parent of this object
|
attr_reader :parent # The Parent of this object
|
||||||
|
|
||||||
# Constructor. Any inheritors of this class should call super to make
|
# Constructor. Any inheritors of this class should call super to make
|
||||||
# sure this method is called.
|
# sure this method is called.
|
||||||
|
@ -38,15 +38,15 @@ module REXML
|
|||||||
# See REXML::Formatters
|
# See REXML::Formatters
|
||||||
#
|
#
|
||||||
# output::
|
# output::
|
||||||
# Where to write the string
|
# Where to write the string
|
||||||
# indent::
|
# indent::
|
||||||
# An integer. If -1, no indenting will be used; otherwise, the
|
# An integer. If -1, no indenting will be used; otherwise, the
|
||||||
# indentation will be this number of spaces, and children will be
|
# indentation will be this number of spaces, and children will be
|
||||||
# indented an additional amount.
|
# indented an additional amount.
|
||||||
# transitive::
|
# transitive::
|
||||||
# Ignored by this class. The contents of comments are never modified.
|
# Ignored by this class. The contents of comments are never modified.
|
||||||
# ie_hack::
|
# ie_hack::
|
||||||
# Needed for conformity to the child API, but not used by this class.
|
# Needed for conformity to the child API, but not used by this class.
|
||||||
def write( output, indent=-1, transitive=false, ie_hack=false )
|
def write( output, indent=-1, transitive=false, ie_hack=false )
|
||||||
Kernel.warn("Comment.write is deprecated. See REXML::Formatters")
|
Kernel.warn("Comment.write is deprecated. See REXML::Formatters")
|
||||||
indent( output, indent )
|
indent( output, indent )
|
||||||
|
@ -165,7 +165,7 @@ module REXML
|
|||||||
# Document.new("<a><b/></a>").serialize( tr )
|
# Document.new("<a><b/></a>").serialize( tr )
|
||||||
#
|
#
|
||||||
# output::
|
# output::
|
||||||
# output an object which supports '<< string'; this is where the
|
# output an object which supports '<< string'; this is where the
|
||||||
# document will be written.
|
# document will be written.
|
||||||
# indent::
|
# indent::
|
||||||
# An integer. If -1, no indenting will be used; otherwise, the
|
# An integer. If -1, no indenting will be used; otherwise, the
|
||||||
@ -188,15 +188,15 @@ module REXML
|
|||||||
output = Output.new( output, xml_decl.encoding )
|
output = Output.new( output, xml_decl.encoding )
|
||||||
end
|
end
|
||||||
formatter = if indent > -1
|
formatter = if indent > -1
|
||||||
if transitive
|
if transitive
|
||||||
require "rexml/formatters/transitive"
|
require "rexml/formatters/transitive"
|
||||||
REXML::Formatters::Transitive.new( indent, ie_hack )
|
REXML::Formatters::Transitive.new( indent, ie_hack )
|
||||||
else
|
else
|
||||||
REXML::Formatters::Pretty.new( indent, ie_hack )
|
REXML::Formatters::Pretty.new( indent, ie_hack )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
REXML::Formatters::Default.new( ie_hack )
|
REXML::Formatters::Default.new( ie_hack )
|
||||||
end
|
end
|
||||||
formatter.write( self, output )
|
formatter.write( self, output )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ module REXML
|
|||||||
class Element < Parent
|
class Element < Parent
|
||||||
include Namespace
|
include Namespace
|
||||||
|
|
||||||
UNDEFINED = "UNDEFINED"; # The default name
|
UNDEFINED = "UNDEFINED"; # The default name
|
||||||
|
|
||||||
# Mechanisms for accessing attributes and child elements of this
|
# Mechanisms for accessing attributes and child elements of this
|
||||||
# element.
|
# element.
|
||||||
@ -31,17 +31,17 @@ module REXML
|
|||||||
|
|
||||||
# Constructor
|
# Constructor
|
||||||
# arg::
|
# arg::
|
||||||
# if not supplied, will be set to the default value.
|
# if not supplied, will be set to the default value.
|
||||||
# If a String, the name of this object will be set to the argument.
|
# If a String, the name of this object will be set to the argument.
|
||||||
# If an Element, the object will be shallowly cloned; name,
|
# If an Element, the object will be shallowly cloned; name,
|
||||||
# attributes, and namespaces will be copied. Children will +not+ be
|
# attributes, and namespaces will be copied. Children will +not+ be
|
||||||
# copied.
|
# copied.
|
||||||
# parent::
|
# parent::
|
||||||
# if supplied, must be a Parent, and will be used as
|
# if supplied, must be a Parent, and will be used as
|
||||||
# the parent of this object.
|
# the parent of this object.
|
||||||
# context::
|
# context::
|
||||||
# If supplied, must be a hash containing context items. Context items
|
# If supplied, must be a hash containing context items. Context items
|
||||||
# include:
|
# include:
|
||||||
# * <tt>:respect_whitespace</tt> the value of this is :+all+ or an array of
|
# * <tt>:respect_whitespace</tt> the value of this is :+all+ or an array of
|
||||||
# strings being the names of the elements to respect
|
# strings being the names of the elements to respect
|
||||||
# whitespace for. Defaults to :+all+.
|
# whitespace for. Defaults to :+all+.
|
||||||
@ -297,7 +297,7 @@ module REXML
|
|||||||
el = @elements.add(element)
|
el = @elements.add(element)
|
||||||
attrs.each do |key, value|
|
attrs.each do |key, value|
|
||||||
el.attributes[key]=value
|
el.attributes[key]=value
|
||||||
end if attrs.kind_of? Hash
|
end if attrs.kind_of? Hash
|
||||||
el
|
el
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -667,7 +667,7 @@ module REXML
|
|||||||
#
|
#
|
||||||
# Writes out this element, and recursively, all children.
|
# Writes out this element, and recursively, all children.
|
||||||
# output::
|
# output::
|
||||||
# output an object which supports '<< string'; this is where the
|
# output an object which supports '<< string'; this is where the
|
||||||
# document will be written.
|
# document will be written.
|
||||||
# indent::
|
# indent::
|
||||||
# An integer. If -1, no indenting will be used; otherwise, the
|
# An integer. If -1, no indenting will be used; otherwise, the
|
||||||
@ -690,15 +690,15 @@ module REXML
|
|||||||
def write(output=$stdout, indent=-1, transitive=false, ie_hack=false)
|
def write(output=$stdout, indent=-1, transitive=false, ie_hack=false)
|
||||||
Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters")
|
Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters")
|
||||||
formatter = if indent > -1
|
formatter = if indent > -1
|
||||||
if transitive
|
if transitive
|
||||||
require "rexml/formatters/transitive"
|
require "rexml/formatters/transitive"
|
||||||
REXML::Formatters::Transitive.new( indent, ie_hack )
|
REXML::Formatters::Transitive.new( indent, ie_hack )
|
||||||
else
|
else
|
||||||
REXML::Formatters::Pretty.new( indent, ie_hack )
|
REXML::Formatters::Pretty.new( indent, ie_hack )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
REXML::Formatters::Default.new( ie_hack )
|
REXML::Formatters::Default.new( ie_hack )
|
||||||
end
|
end
|
||||||
formatter.write( self, output )
|
formatter.write( self, output )
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -778,7 +778,7 @@ module REXML
|
|||||||
else
|
else
|
||||||
return XPath::first( @element, index )
|
return XPath::first( @element, index )
|
||||||
#{ |element|
|
#{ |element|
|
||||||
# return element if element.kind_of? Element
|
# return element if element.kind_of? Element
|
||||||
#}
|
#}
|
||||||
#return nil
|
#return nil
|
||||||
end
|
end
|
||||||
@ -1086,7 +1086,7 @@ module REXML
|
|||||||
# doc.root.attributes['foo'] = '4'
|
# doc.root.attributes['foo'] = '4'
|
||||||
# doc.root.attributes['x:foo'] = nil
|
# doc.root.attributes['x:foo'] = nil
|
||||||
def []=( name, value )
|
def []=( name, value )
|
||||||
if value.nil? # Delete the named attribute
|
if value.nil? # Delete the named attribute
|
||||||
attr = get_attribute(name)
|
attr = get_attribute(name)
|
||||||
delete attr
|
delete attr
|
||||||
return
|
return
|
||||||
@ -1116,8 +1116,8 @@ module REXML
|
|||||||
value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
|
value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
|
||||||
@element.namespace( old_attr.prefix ) ==
|
@element.namespace( old_attr.prefix ) ==
|
||||||
@element.namespace( value.prefix )
|
@element.namespace( value.prefix )
|
||||||
store value.name, { old_attr.prefix => old_attr,
|
store value.name, { old_attr.prefix => old_attr,
|
||||||
value.prefix => value }
|
value.prefix => value }
|
||||||
else
|
else
|
||||||
store value.name, value
|
store value.name, value
|
||||||
end
|
end
|
||||||
@ -1236,7 +1236,7 @@ module REXML
|
|||||||
( !namespace.empty? || !attribute.fully_expanded_name.index(':') )
|
( !namespace.empty? || !attribute.fully_expanded_name.index(':') )
|
||||||
# foo will match xmlns:foo, but only if foo isn't also an attribute
|
# foo will match xmlns:foo, but only if foo isn't also an attribute
|
||||||
result = attribute if !result or !namespace.empty? or
|
result = attribute if !result or !namespace.empty? or
|
||||||
!attribute.fully_expanded_name.index(':')
|
!attribute.fully_expanded_name.index(':')
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
require 'rexml/xmltokens'
|
require 'rexml/xmltokens'
|
||||||
|
|
||||||
# [ :element, parent, name, attributes, children* ]
|
# [ :element, parent, name, attributes, children* ]
|
||||||
# a = Node.new
|
# a = Node.new
|
||||||
# a << "B" # => <a>B</a>
|
# a << "B" # => <a>B</a>
|
||||||
# a.b # => <a>B<b/></a>
|
# a.b # => <a>B<b/></a>
|
||||||
# a.b[1] # => <a>B<b/><b/><a>
|
# a.b[1] # => <a>B<b/><b/><a>
|
||||||
# a.b[1]["x"] = "y" # => <a>B<b/><b x="y"/></a>
|
# a.b[1]["x"] = "y" # => <a>B<b/><b x="y"/></a>
|
||||||
# a.b[0].c # => <a>B<b><c/></b><b x="y"/></a>
|
# a.b[0].c # => <a>B<b><c/></b><b x="y"/></a>
|
||||||
# a.b.c << "D" # => <a>B<b><c>D</c></b><b x="y"/></a>
|
# a.b.c << "D" # => <a>B<b><c>D</c></b><b x="y"/></a>
|
||||||
module REXML
|
module REXML
|
||||||
module Light
|
module Light
|
||||||
# Represents a tagged XML element. Elements are characterized by
|
# Represents a tagged XML element. Elements are characterized by
|
||||||
|
@ -36,12 +36,12 @@ module REXML
|
|||||||
end
|
end
|
||||||
|
|
||||||
def indent to, ind
|
def indent to, ind
|
||||||
if @parent and @parent.context and not @parent.context[:indentstyle].nil? then
|
if @parent and @parent.context and not @parent.context[:indentstyle].nil? then
|
||||||
indentstyle = @parent.context[:indentstyle]
|
indentstyle = @parent.context[:indentstyle]
|
||||||
else
|
else
|
||||||
indentstyle = ' '
|
indentstyle = ' '
|
||||||
end
|
end
|
||||||
to << indentstyle*ind unless ind<1
|
to << indentstyle*ind unless ind<1
|
||||||
end
|
end
|
||||||
|
|
||||||
def parent?
|
def parent?
|
||||||
|
@ -44,10 +44,10 @@ module REXML
|
|||||||
end
|
end
|
||||||
|
|
||||||
# An element is an array. The array contains:
|
# An element is an array. The array contains:
|
||||||
# 0 The parent element
|
# 0 The parent element
|
||||||
# 1 The tag name
|
# 1 The tag name
|
||||||
# 2 A hash of attributes
|
# 2 A hash of attributes
|
||||||
# 3..-1 The child elements
|
# 3..-1 The child elements
|
||||||
# An element is an array of size > 3
|
# An element is an array of size > 3
|
||||||
# Text is a String
|
# Text is a String
|
||||||
# PIs are [ :processing_instruction, target, data ]
|
# PIs are [ :processing_instruction, target, data ]
|
||||||
|
@ -28,15 +28,15 @@ module REXML
|
|||||||
# Listen arguments:
|
# Listen arguments:
|
||||||
#
|
#
|
||||||
# Symbol, Array, Block
|
# Symbol, Array, Block
|
||||||
# Listen to Symbol events on Array elements
|
# Listen to Symbol events on Array elements
|
||||||
# Symbol, Block
|
# Symbol, Block
|
||||||
# Listen to Symbol events
|
# Listen to Symbol events
|
||||||
# Array, Listener
|
# Array, Listener
|
||||||
# Listen to all events on Array elements
|
# Listen to all events on Array elements
|
||||||
# Array, Block
|
# Array, Block
|
||||||
# Listen to :start_element events on Array elements
|
# Listen to :start_element events on Array elements
|
||||||
# Listener
|
# Listener
|
||||||
# Listen to All events
|
# Listen to All events
|
||||||
#
|
#
|
||||||
# Symbol can be one of: :start_element, :end_element,
|
# Symbol can be one of: :start_element, :end_element,
|
||||||
# :start_prefix_mapping, :end_prefix_mapping, :characters,
|
# :start_prefix_mapping, :end_prefix_mapping, :characters,
|
||||||
@ -209,7 +209,7 @@ module REXML
|
|||||||
((name.nil? and match.nil?) or match.nil? or (
|
((name.nil? and match.nil?) or match.nil? or (
|
||||||
(name == match) or
|
(name == match) or
|
||||||
(match.kind_of? Regexp and name =~ match)
|
(match.kind_of? Regexp and name =~ match)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end.collect{|x| x[-1]}
|
end.collect{|x| x[-1]}
|
||||||
@ -222,7 +222,7 @@ module REXML
|
|||||||
((name.nil? and match.nil?) or match.nil? or (
|
((name.nil? and match.nil?) or match.nil? or (
|
||||||
(name == match) or
|
(name == match) or
|
||||||
(match.kind_of? Regexp and name =~ match)
|
(match.kind_of? Regexp and name =~ match)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end.collect{|x| x[-1]}
|
end.collect{|x| x[-1]}
|
||||||
|
@ -42,10 +42,10 @@ module REXML
|
|||||||
end
|
end
|
||||||
|
|
||||||
# An element is an array. The array contains:
|
# An element is an array. The array contains:
|
||||||
# 0 The parent element
|
# 0 The parent element
|
||||||
# 1 The tag name
|
# 1 The tag name
|
||||||
# 2 A hash of attributes
|
# 2 A hash of attributes
|
||||||
# 3..-1 The child elements
|
# 3..-1 The child elements
|
||||||
# An element is an array of size > 3
|
# An element is an array of size > 3
|
||||||
# Text is a String
|
# Text is a String
|
||||||
# PIs are [ :processing_instruction, target, data ]
|
# PIs are [ :processing_instruction, target, data ]
|
||||||
|
@ -49,20 +49,20 @@ module REXML
|
|||||||
def QuickPath::filter elements, path
|
def QuickPath::filter elements, path
|
||||||
return elements if path.nil? or path == '' or elements.size == 0
|
return elements if path.nil? or path == '' or elements.size == 0
|
||||||
case path
|
case path
|
||||||
when /^\/\//u # Descendant
|
when /^\/\//u # Descendant
|
||||||
return axe( elements, "descendant-or-self", $' )
|
return axe( elements, "descendant-or-self", $' )
|
||||||
when /^\/?\b(\w[-\w]*)\b::/u # Axe
|
when /^\/?\b(\w[-\w]*)\b::/u # Axe
|
||||||
return axe( elements, $1, $' )
|
return axe( elements, $1, $' )
|
||||||
when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child
|
when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child
|
||||||
rest = $'
|
rest = $'
|
||||||
results = []
|
results = []
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
results |= filter( element.to_a, rest )
|
results |= filter( element.to_a, rest )
|
||||||
end
|
end
|
||||||
return results
|
return results
|
||||||
when /^\/?(\w[-\w]*)\(/u # / Function
|
when /^\/?(\w[-\w]*)\(/u # / Function
|
||||||
return function( elements, $1, $' )
|
return function( elements, $1, $' )
|
||||||
when Namespace::NAMESPLIT # Element name
|
when Namespace::NAMESPLIT # Element name
|
||||||
name = $2
|
name = $2
|
||||||
ns = $1
|
ns = $1
|
||||||
rest = $'
|
rest = $'
|
||||||
@ -79,22 +79,22 @@ module REXML
|
|||||||
matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element
|
matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element
|
||||||
end
|
end
|
||||||
return matches
|
return matches
|
||||||
when /^\[/u # Predicate
|
when /^\[/u # Predicate
|
||||||
return predicate( elements, path )
|
return predicate( elements, path )
|
||||||
when /^\/?\.\.\./u # Ancestor
|
when /^\/?\.\.\./u # Ancestor
|
||||||
return axe( elements, "ancestor", $' )
|
return axe( elements, "ancestor", $' )
|
||||||
when /^\/?\.\./u # Parent
|
when /^\/?\.\./u # Parent
|
||||||
return filter( elements.collect{|e|e.parent}, $' )
|
return filter( elements.collect{|e|e.parent}, $' )
|
||||||
when /^\/?\./u # Self
|
when /^\/?\./u # Self
|
||||||
return filter( elements, $' )
|
return filter( elements, $' )
|
||||||
when /^\*/u # Any
|
when /^\*/u # Any
|
||||||
results = []
|
results = []
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
results |= filter( [element], $' ) if element.kind_of? Element
|
results |= filter( [element], $' ) if element.kind_of? Element
|
||||||
#if element.kind_of? Element
|
#if element.kind_of? Element
|
||||||
# children = element.to_a
|
# children = element.to_a
|
||||||
# children.delete_if { |child| !child.kind_of?(Element) }
|
# children.delete_if { |child| !child.kind_of?(Element) }
|
||||||
# results |= filter( children, $' )
|
# results |= filter( children, $' )
|
||||||
#end
|
#end
|
||||||
end
|
end
|
||||||
return results
|
return results
|
||||||
@ -132,7 +132,7 @@ module REXML
|
|||||||
matches = filter(elements.collect{|element| element.parent}.uniq, rest)
|
matches = filter(elements.collect{|element| element.parent}.uniq, rest)
|
||||||
when "following-sibling"
|
when "following-sibling"
|
||||||
matches = filter(elements.collect{|element| element.next_sibling}.uniq,
|
matches = filter(elements.collect{|element| element.next_sibling}.uniq,
|
||||||
rest)
|
rest)
|
||||||
when "previous-sibling"
|
when "previous-sibling"
|
||||||
matches = filter(elements.collect{|element|
|
matches = filter(elements.collect{|element|
|
||||||
element.previous_sibling}.uniq, rest )
|
element.previous_sibling}.uniq, rest )
|
||||||
@ -174,32 +174,32 @@ module REXML
|
|||||||
predicate.gsub!(
|
predicate.gsub!(
|
||||||
/#{OPERAND_}\s*([<>=])\s*#{OPERAND_}\s*([<>=])\s*#{OPERAND_}/u,
|
/#{OPERAND_}\s*([<>=])\s*#{OPERAND_}\s*([<>=])\s*#{OPERAND_}/u,
|
||||||
'\1 \2 \3 and \3 \4 \5' )
|
'\1 \2 \3 and \3 \4 \5' )
|
||||||
# Let's do some Ruby trickery to avoid some work:
|
# Let's do some Ruby trickery to avoid some work:
|
||||||
predicate.gsub!( /&/u, "&&" )
|
predicate.gsub!( /&/u, "&&" )
|
||||||
predicate.gsub!( /=/u, "==" )
|
predicate.gsub!( /=/u, "==" )
|
||||||
predicate.gsub!( /@(\w[-\w.]*)/u, 'attribute("\1")' )
|
predicate.gsub!( /@(\w[-\w.]*)/u, 'attribute("\1")' )
|
||||||
predicate.gsub!( /\bmod\b/u, "%" )
|
predicate.gsub!( /\bmod\b/u, "%" )
|
||||||
predicate.gsub!( /\b(\w[-\w.]*\()/u ) {
|
predicate.gsub!( /\b(\w[-\w.]*\()/u ) {
|
||||||
fname = $1
|
fname = $1
|
||||||
fname.gsub( /-/u, "_" )
|
fname.gsub( /-/u, "_" )
|
||||||
}
|
}
|
||||||
|
|
||||||
Functions.pair = [ 0, elements.size ]
|
Functions.pair = [ 0, elements.size ]
|
||||||
results = []
|
results = []
|
||||||
elements.each do |element|
|
elements.each do |element|
|
||||||
Functions.pair[0] += 1
|
Functions.pair[0] += 1
|
||||||
Functions.node = element
|
Functions.node = element
|
||||||
res = eval( predicate )
|
res = eval( predicate )
|
||||||
case res
|
case res
|
||||||
when true
|
when true
|
||||||
results << element
|
results << element
|
||||||
when Fixnum
|
when Fixnum
|
||||||
results << element if Functions.pair[0] == res
|
results << element if Functions.pair[0] == res
|
||||||
when String
|
when String
|
||||||
results << element
|
results << element
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
return filter( results, rest )
|
||||||
return filter( results, rest )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def QuickPath::attribute( name )
|
def QuickPath::attribute( name )
|
||||||
|
@ -12,12 +12,12 @@ module REXML
|
|||||||
|
|
||||||
# Finds and returns the first node that matches the supplied xpath.
|
# Finds and returns the first node that matches the supplied xpath.
|
||||||
# element::
|
# element::
|
||||||
# The context element
|
# The context element
|
||||||
# path::
|
# path::
|
||||||
# The xpath to search for. If not supplied or nil, returns the first
|
# The xpath to search for. If not supplied or nil, returns the first
|
||||||
# node matching '*'.
|
# node matching '*'.
|
||||||
# namespaces::
|
# namespaces::
|
||||||
# If supplied, a Hash which defines a namespace mapping.
|
# If supplied, a Hash which defines a namespace mapping.
|
||||||
# variables::
|
# variables::
|
||||||
# If supplied, a Hash which maps $variables in the query
|
# If supplied, a Hash which maps $variables in the query
|
||||||
# to values. This can be used to avoid XPath injection attacks
|
# to values. This can be used to avoid XPath injection attacks
|
||||||
@ -45,7 +45,7 @@ module REXML
|
|||||||
# path::
|
# path::
|
||||||
# The xpath to search for. If not supplied or nil, defaults to '*'
|
# The xpath to search for. If not supplied or nil, defaults to '*'
|
||||||
# namespaces::
|
# namespaces::
|
||||||
# If supplied, a Hash which defines a namespace mapping
|
# If supplied, a Hash which defines a namespace mapping
|
||||||
# variables::
|
# variables::
|
||||||
# If supplied, a Hash which maps $variables in the query
|
# If supplied, a Hash which maps $variables in the query
|
||||||
# to values. This can be used to avoid XPath injection attacks
|
# to values. This can be used to avoid XPath injection attacks
|
||||||
|
@ -43,10 +43,10 @@ module Rinda
|
|||||||
|
|
||||||
def write_service
|
def write_service
|
||||||
Thread.new do
|
Thread.new do
|
||||||
loop do
|
loop do
|
||||||
msg = @soc.recv(1024)
|
msg = @soc.recv(1024)
|
||||||
do_write(msg)
|
do_write(msg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -56,11 +56,11 @@ module Rinda
|
|||||||
|
|
||||||
def do_write(msg)
|
def do_write(msg)
|
||||||
Thread.new do
|
Thread.new do
|
||||||
begin
|
begin
|
||||||
tuple, sec = Marshal.load(msg)
|
tuple, sec = Marshal.load(msg)
|
||||||
@ts.write(tuple, sec)
|
@ts.write(tuple, sec)
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -69,9 +69,9 @@ module Rinda
|
|||||||
|
|
||||||
def reply_service
|
def reply_service
|
||||||
Thread.new do
|
Thread.new do
|
||||||
loop do
|
loop do
|
||||||
do_reply
|
do_reply
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -105,8 +105,8 @@ module Rinda
|
|||||||
|
|
||||||
def self.finger
|
def self.finger
|
||||||
unless @@finger
|
unless @@finger
|
||||||
@@finger = self.new
|
@@finger = self.new
|
||||||
@@finger.lookup_ring_any
|
@@finger.lookup_ring_any
|
||||||
end
|
end
|
||||||
@@finger
|
@@finger
|
||||||
end
|
end
|
||||||
@ -178,15 +178,15 @@ module Rinda
|
|||||||
|
|
||||||
msg = Marshal.dump([[:lookup_ring, DRbObject.new(block)], timeout])
|
msg = Marshal.dump([[:lookup_ring, DRbObject.new(block)], timeout])
|
||||||
@broadcast_list.each do |it|
|
@broadcast_list.each do |it|
|
||||||
soc = UDPSocket.open
|
soc = UDPSocket.open
|
||||||
begin
|
begin
|
||||||
soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
|
soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
|
||||||
soc.send(msg, 0, it, @port)
|
soc.send(msg, 0, it, @port)
|
||||||
rescue
|
rescue
|
||||||
nil
|
nil
|
||||||
ensure
|
ensure
|
||||||
soc.close
|
soc.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
sleep(timeout)
|
sleep(timeout)
|
||||||
end
|
end
|
||||||
@ -199,13 +199,13 @@ module Rinda
|
|||||||
queue = Queue.new
|
queue = Queue.new
|
||||||
|
|
||||||
Thread.new do
|
Thread.new do
|
||||||
self.lookup_ring(timeout) do |ts|
|
self.lookup_ring(timeout) do |ts|
|
||||||
queue.push(ts)
|
queue.push(ts)
|
||||||
end
|
end
|
||||||
queue.push(nil)
|
queue.push(nil)
|
||||||
while it = queue.pop
|
while it = queue.pop
|
||||||
@rings.push(it)
|
@rings.push(it)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@primary = queue.pop
|
@primary = queue.pop
|
||||||
|
@ -51,7 +51,7 @@ module RSS
|
|||||||
|
|
||||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||||
def new_#{name}
|
def new_#{name}
|
||||||
#{name} = self.class::#{klass_name}.new(@maker)
|
#{name} = self.class::#{klass_name}.new(@maker)
|
||||||
@#{plural} << #{name}
|
@#{plural} << #{name}
|
||||||
if block_given?
|
if block_given?
|
||||||
yield #{name}
|
yield #{name}
|
||||||
@ -63,14 +63,14 @@ module RSS
|
|||||||
|
|
||||||
def to_feed(*args)
|
def to_feed(*args)
|
||||||
@#{plural}.each do |#{name}|
|
@#{plural}.each do |#{name}|
|
||||||
#{name}.to_feed(*args)
|
#{name}.to_feed(*args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace(elements)
|
def replace(elements)
|
||||||
@#{plural}.replace(elements.to_a)
|
@#{plural}.replace(elements.to_a)
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def def_classed_element_without_accessor(name, class_name=nil)
|
def def_classed_element_without_accessor(name, class_name=nil)
|
||||||
@ -88,7 +88,7 @@ module RSS
|
|||||||
def make_#{name}
|
def make_#{name}
|
||||||
self.class::#{class_name}.new(@maker)
|
self.class::#{class_name}.new(@maker)
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def def_classed_element(name, class_name=nil, attribute_name=nil)
|
def def_classed_element(name, class_name=nil, attribute_name=nil)
|
||||||
@ -106,7 +106,7 @@ module RSS
|
|||||||
def #{name}=(new_value)
|
def #{name}=(new_value)
|
||||||
@#{name}.#{attribute_name} = new_value
|
@#{name}.#{attribute_name} = new_value
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
else
|
else
|
||||||
attr_reader name
|
attr_reader name
|
||||||
end
|
end
|
||||||
@ -126,17 +126,17 @@ module RSS
|
|||||||
end
|
end
|
||||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||||
def #{name}
|
def #{name}
|
||||||
#{local_variable_name} = #{plural_name}.first
|
#{local_variable_name} = #{plural_name}.first
|
||||||
#{local_variable_name} ? #{local_variable_name}.#{attribute} : nil
|
#{local_variable_name} ? #{local_variable_name}.#{attribute} : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def #{name}=(#{new_value_variable_name})
|
def #{name}=(#{new_value_variable_name})
|
||||||
#{local_variable_name} =
|
#{local_variable_name} =
|
||||||
#{plural_name}.first || #{plural_name}.new_#{new_name}
|
#{plural_name}.first || #{plural_name}.new_#{new_name}
|
||||||
#{additional_setup_code}
|
#{additional_setup_code}
|
||||||
#{local_variable_name}.#{attribute} = #{new_value_variable_name}
|
#{local_variable_name}.#{attribute} = #{new_value_variable_name}
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def def_other_element(name)
|
def def_other_element(name)
|
||||||
@ -153,7 +153,7 @@ module RSS
|
|||||||
current.#{name} = @#{name}
|
current.#{name} = @#{name}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def def_csv_element(name, type=nil)
|
def def_csv_element(name, type=nil)
|
||||||
@ -167,7 +167,7 @@ module RSS
|
|||||||
def #{name}=(value)
|
def #{name}=(value)
|
||||||
@#{name} = Utils::CSV.parse(value)#{converter}
|
@#{name} = Utils::CSV.parse(value)#{converter}
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ module RSS
|
|||||||
def ensure_xml_content(content)
|
def ensure_xml_content(content)
|
||||||
xhtml_uri = ::RSS::Atom::XHTML_URI
|
xhtml_uri = ::RSS::Atom::XHTML_URI
|
||||||
unless content.is_a?(RSS::XML::Element) and
|
unless content.is_a?(RSS::XML::Element) and
|
||||||
["div", xhtml_uri] == [content.name, content.uri]
|
["div", xhtml_uri] == [content.name, content.uri]
|
||||||
children = content
|
children = content
|
||||||
children = [children] unless content.is_a?(Array)
|
children = [children] unless content.is_a?(Array)
|
||||||
children = set_xhtml_uri_as_default_uri(children)
|
children = set_xhtml_uri_as_default_uri(children)
|
||||||
@ -331,7 +331,7 @@ module RSS
|
|||||||
def set_xhtml_uri_as_default_uri(children)
|
def set_xhtml_uri_as_default_uri(children)
|
||||||
children.collect do |child|
|
children.collect do |child|
|
||||||
if child.is_a?(RSS::XML::Element) and
|
if child.is_a?(RSS::XML::Element) and
|
||||||
child.prefix.nil? and child.uri.nil?
|
child.prefix.nil? and child.uri.nil?
|
||||||
RSS::XML::Element.new(child.name, nil, ::RSS::Atom::XHTML_URI,
|
RSS::XML::Element.new(child.name, nil, ::RSS::Atom::XHTML_URI,
|
||||||
child.attributes.dup,
|
child.attributes.dup,
|
||||||
set_xhtml_uri_as_default_uri(child.children))
|
set_xhtml_uri_as_default_uri(child.children))
|
||||||
@ -385,7 +385,7 @@ module RSS
|
|||||||
}
|
}
|
||||||
_language = language
|
_language = language
|
||||||
if _language and
|
if _language and
|
||||||
!dc_languages.any? {|dc_language| dc_language.value == _language}
|
!dc_languages.any? {|dc_language| dc_language.value == _language}
|
||||||
dc_language = self.class::DublinCoreLanguages::DublinCoreLanguage.new(self)
|
dc_language = self.class::DublinCoreLanguages::DublinCoreLanguage.new(self)
|
||||||
dc_language.value = _language.dup
|
dc_language.value = _language.dup
|
||||||
dc_languages.unshift(dc_language)
|
dc_languages.unshift(dc_language)
|
||||||
@ -417,7 +417,7 @@ module RSS
|
|||||||
def make_#{element}
|
def make_#{element}
|
||||||
self.class::#{Utils.to_class_name(element)}.new(self)
|
self.class::#{Utils.to_class_name(element)}.new(self)
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :feed_version
|
attr_reader :feed_version
|
||||||
@ -500,9 +500,9 @@ module RSS
|
|||||||
end
|
end
|
||||||
|
|
||||||
[
|
[
|
||||||
["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}],
|
["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}],
|
||||||
["author", "name"],
|
["author", "name"],
|
||||||
["contributor", "name"],
|
["contributor", "name"],
|
||||||
].each do |name, attribute, additional_setup_maker|
|
].each do |name, attribute, additional_setup_maker|
|
||||||
def_classed_elements(name, attribute, &additional_setup_maker)
|
def_classed_elements(name, attribute, &additional_setup_maker)
|
||||||
end
|
end
|
||||||
@ -511,7 +511,7 @@ module RSS
|
|||||||
managingEditor webMaster rating docs ttl).each do |element|
|
managingEditor webMaster rating docs ttl).each do |element|
|
||||||
attr_accessor element
|
attr_accessor element
|
||||||
add_need_initialize_variable(element)
|
add_need_initialize_variable(element)
|
||||||
end
|
end
|
||||||
|
|
||||||
%w(date lastBuildDate).each do |date_element|
|
%w(date lastBuildDate).each do |date_element|
|
||||||
attr_reader date_element
|
attr_reader date_element
|
||||||
@ -713,12 +713,12 @@ module RSS
|
|||||||
end
|
end
|
||||||
|
|
||||||
[
|
[
|
||||||
["author", "name"],
|
["author", "name"],
|
||||||
["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}],
|
["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}],
|
||||||
["contributor", "name"],
|
["contributor", "name"],
|
||||||
].each do |name, attribute|
|
].each do |name, attribute|
|
||||||
def_classed_elements(name, attribute)
|
def_classed_elements(name, attribute)
|
||||||
end
|
end
|
||||||
|
|
||||||
%w(comments id published).each do |element|
|
%w(comments id published).each do |element|
|
||||||
attr_accessor element
|
attr_accessor element
|
||||||
@ -795,10 +795,10 @@ module RSS
|
|||||||
%w(authors categories contributors generator icon
|
%w(authors categories contributors generator icon
|
||||||
logo rights subtitle title).each do |name|
|
logo rights subtitle title).each do |name|
|
||||||
def_classed_element(name)
|
def_classed_element(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
[
|
[
|
||||||
["link", "href"],
|
["link", "href"],
|
||||||
].each do |name, attribute|
|
].each do |name, attribute|
|
||||||
def_classed_elements(name, attribute)
|
def_classed_elements(name, attribute)
|
||||||
end
|
end
|
||||||
|
@ -13,11 +13,11 @@ module RSS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.install_image_item(klass)
|
def self.install_image_item(klass)
|
||||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||||
class ImageItem < ImageItemBase
|
class ImageItem < ImageItemBase
|
||||||
DublinCoreModel.install_dublin_core(self)
|
DublinCoreModel.install_dublin_core(self)
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
class ImageItemBase < Base
|
class ImageItemBase < Base
|
||||||
@ -29,9 +29,9 @@ EOC
|
|||||||
add_need_initialize_variable("image_width")
|
add_need_initialize_variable("image_width")
|
||||||
add_need_initialize_variable("image_height")
|
add_need_initialize_variable("image_height")
|
||||||
alias width= image_width=
|
alias width= image_width=
|
||||||
alias width image_width
|
alias width image_width
|
||||||
alias height= image_height=
|
alias height= image_height=
|
||||||
alias height image_height
|
alias height image_height
|
||||||
|
|
||||||
def have_required_values?
|
def have_required_values?
|
||||||
@about
|
@about
|
||||||
@ -57,7 +57,7 @@ EOC
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.install_image_favicon(klass)
|
def self.install_image_favicon(klass)
|
||||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||||
class ImageFavicon < ImageFaviconBase
|
class ImageFavicon < ImageFaviconBase
|
||||||
DublinCoreModel.install_dublin_core(self)
|
DublinCoreModel.install_dublin_core(self)
|
||||||
end
|
end
|
||||||
@ -73,9 +73,9 @@ EOC
|
|||||||
alias size image_size
|
alias size image_size
|
||||||
alias size= image_size=
|
alias size= image_size=
|
||||||
|
|
||||||
def have_required_values?
|
def have_required_values?
|
||||||
@about and @image_size
|
@about and @image_size
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_feed(feed, current)
|
def to_feed(feed, current)
|
||||||
if current.respond_to?(:image_favicon=) and have_required_values?
|
if current.respond_to?(:image_favicon=) and have_required_values?
|
||||||
|
@ -5,27 +5,27 @@ class Time
|
|||||||
unless respond_to?(:w3cdtf)
|
unless respond_to?(:w3cdtf)
|
||||||
def w3cdtf(date)
|
def w3cdtf(date)
|
||||||
if /\A\s*
|
if /\A\s*
|
||||||
(-?\d+)-(\d\d)-(\d\d)
|
(-?\d+)-(\d\d)-(\d\d)
|
||||||
(?:T
|
(?:T
|
||||||
(\d\d):(\d\d)(?::(\d\d))?
|
(\d\d):(\d\d)(?::(\d\d))?
|
||||||
(\.\d+)?
|
(\.\d+)?
|
||||||
(Z|[+-]\d\d:\d\d)?)?
|
(Z|[+-]\d\d:\d\d)?)?
|
||||||
\s*\z/ix =~ date and (($5 and $8) or (!$5 and !$8))
|
\s*\z/ix =~ date and (($5 and $8) or (!$5 and !$8))
|
||||||
datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i]
|
datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i]
|
||||||
usec = 0
|
usec = 0
|
||||||
usec = $7.to_f * 1000000 if $7
|
usec = $7.to_f * 1000000 if $7
|
||||||
zone = $8
|
zone = $8
|
||||||
if zone
|
if zone
|
||||||
off = zone_offset(zone, datetime[0])
|
off = zone_offset(zone, datetime[0])
|
||||||
datetime = apply_offset(*(datetime + [off]))
|
datetime = apply_offset(*(datetime + [off]))
|
||||||
datetime << usec
|
datetime << usec
|
||||||
time = Time.utc(*datetime)
|
time = Time.utc(*datetime)
|
||||||
time.localtime unless zone_utc?(zone)
|
time.localtime unless zone_utc?(zone)
|
||||||
time
|
time
|
||||||
else
|
else
|
||||||
datetime << usec
|
datetime << usec
|
||||||
Time.local(*datetime)
|
Time.local(*datetime)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise ArgumentError.new("invalid date: #{date.inspect}")
|
raise ArgumentError.new("invalid date: #{date.inspect}")
|
||||||
end
|
end
|
||||||
@ -209,7 +209,7 @@ module RSS
|
|||||||
else
|
else
|
||||||
''
|
''
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias_method(:install_have_attribute_element, :install_have_child_element)
|
alias_method(:install_have_attribute_element, :install_have_child_element)
|
||||||
@ -230,7 +230,7 @@ EOC
|
|||||||
rv << value if /\\A\\s*\\z/ !~ value
|
rv << value if /\\A\\s*\\z/ !~ value
|
||||||
end
|
end
|
||||||
rv.join("\n")
|
rv.join("\n")
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -259,12 +259,12 @@ EOC
|
|||||||
else
|
else
|
||||||
rv << value
|
rv << value
|
||||||
end
|
end
|
||||||
rv << "</#{elem_name}>"
|
rv << "</#{elem_name}>"
|
||||||
rv
|
rv
|
||||||
else
|
else
|
||||||
''
|
''
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -290,12 +290,12 @@ EOC
|
|||||||
else
|
else
|
||||||
rv << value
|
rv << value
|
||||||
end
|
end
|
||||||
rv << "</#{elem_name}>"
|
rv << "</#{elem_name}>"
|
||||||
rv
|
rv
|
||||||
else
|
else
|
||||||
''
|
''
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -307,10 +307,10 @@ EOC
|
|||||||
add_to_element_method(method_name)
|
add_to_element_method(method_name)
|
||||||
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
|
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
|
||||||
def #{method_name}(need_convert=true, indent='')
|
def #{method_name}(need_convert=true, indent='')
|
||||||
#{yield(name, elem_name)}
|
#{yield(name, elem_name)}
|
||||||
end
|
end
|
||||||
private :#{method_name}
|
private :#{method_name}
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def inherit_convert_attr_reader(*attrs)
|
def inherit_convert_attr_reader(*attrs)
|
||||||
@ -323,14 +323,14 @@ EOC
|
|||||||
|
|
||||||
def #{attr}
|
def #{attr}
|
||||||
if @#{attr}
|
if @#{attr}
|
||||||
#{attr}_without_inherit
|
#{attr}_without_inherit
|
||||||
elsif @parent
|
elsif @parent
|
||||||
@parent.#{attr}
|
@parent.#{attr}
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ EOC
|
|||||||
"\#{base}\#{value}"
|
"\#{base}\#{value}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -362,7 +362,7 @@ EOC
|
|||||||
def #{attr}
|
def #{attr}
|
||||||
convert(@#{attr})
|
convert(@#{attr})
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -408,7 +408,7 @@ EOC
|
|||||||
@#{attr}.join(#{separator.dump})
|
@#{attr}.join(#{separator.dump})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -448,7 +448,7 @@ EOC
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def integer_writer(name, disp_name=name)
|
def integer_writer(name, disp_name=name)
|
||||||
@ -468,7 +468,7 @@ EOC
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def positive_integer_writer(name, disp_name=name)
|
def positive_integer_writer(name, disp_name=name)
|
||||||
@ -490,7 +490,7 @@ EOC
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def boolean_writer(name, disp_name=name)
|
def boolean_writer(name, disp_name=name)
|
||||||
@ -510,7 +510,7 @@ EOC
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def text_type_writer(name, disp_name=name)
|
def text_type_writer(name, disp_name=name)
|
||||||
@ -522,7 +522,7 @@ EOC
|
|||||||
end
|
end
|
||||||
@#{name} = new_value
|
@#{name} = new_value
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def content_writer(name, disp_name=name)
|
def content_writer(name, disp_name=name)
|
||||||
@ -536,7 +536,7 @@ EOC
|
|||||||
@#{name}.content = new_value
|
@#{name}.content = new_value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
|
|
||||||
def yes_clean_other_writer(name, disp_name=name)
|
def yes_clean_other_writer(name, disp_name=name)
|
||||||
@ -603,7 +603,7 @@ EOC
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias_method(:set_#{accessor_name}, :#{accessor_name}=)
|
alias_method(:set_#{accessor_name}, :#{accessor_name}=)
|
||||||
EOC
|
EOC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -630,7 +630,7 @@ EOC
|
|||||||
value = __send__(var)
|
value = __send__(var)
|
||||||
next if value.nil?
|
next if value.nil?
|
||||||
if value.respond_to?("setup_maker") and
|
if value.respond_to?("setup_maker") and
|
||||||
!not_need_to_call_setup_maker_variables.include?(var)
|
!not_need_to_call_setup_maker_variables.include?(var)
|
||||||
value.setup_maker(target)
|
value.setup_maker(target)
|
||||||
else
|
else
|
||||||
setter = "#{var}="
|
setter = "#{var}="
|
||||||
@ -1173,7 +1173,7 @@ EOC
|
|||||||
else
|
else
|
||||||
if name == tag
|
if name == tag
|
||||||
if models[i+1] and models[i+1][0] != name and
|
if models[i+1] and models[i+1][0] != name and
|
||||||
tags and tags.first == name
|
tags and tags.first == name
|
||||||
raise TooMuchTagError.new(name, tag_name)
|
raise TooMuchTagError.new(name, tag_name)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
96
lib/scanf.rb
96
lib/scanf.rb
@ -506,28 +506,28 @@ module Scanf
|
|||||||
class FormatString
|
class FormatString
|
||||||
|
|
||||||
attr_reader :string_left, :last_spec_tried,
|
attr_reader :string_left, :last_spec_tried,
|
||||||
:last_match_tried, :matched_count, :space
|
:last_match_tried, :matched_count, :space
|
||||||
|
|
||||||
SPECIFIERS = 'diuXxofFeEgGscaA'
|
SPECIFIERS = 'diuXxofFeEgGscaA'
|
||||||
REGEX = /
|
REGEX = /
|
||||||
# possible space, followed by...
|
# possible space, followed by...
|
||||||
(?:\s*
|
(?:\s*
|
||||||
# percent sign, followed by...
|
# percent sign, followed by...
|
||||||
%
|
%
|
||||||
# another percent sign, or...
|
# another percent sign, or...
|
||||||
(?:%|
|
(?:%|
|
||||||
# optional assignment suppression flag
|
# optional assignment suppression flag
|
||||||
\*?
|
\*?
|
||||||
# optional maximum field width
|
# optional maximum field width
|
||||||
\d*
|
\d*
|
||||||
# named character class, ...
|
# named character class, ...
|
||||||
(?:\[\[:\w+:\]\]|
|
(?:\[\[:\w+:\]\]|
|
||||||
# traditional character class, or...
|
# traditional character class, or...
|
||||||
\[[^\]]*\]|
|
\[[^\]]*\]|
|
||||||
# specifier letter.
|
# specifier letter.
|
||||||
[#{SPECIFIERS}])))|
|
[#{SPECIFIERS}])))|
|
||||||
# or miscellaneous characters
|
# or miscellaneous characters
|
||||||
[^%\s]+/ix
|
[^%\s]+/ix
|
||||||
|
|
||||||
def initialize(str)
|
def initialize(str)
|
||||||
@specs = []
|
@specs = []
|
||||||
@ -578,33 +578,33 @@ end
|
|||||||
|
|
||||||
class IO
|
class IO
|
||||||
|
|
||||||
# The trick here is doing a match where you grab one *line*
|
# The trick here is doing a match where you grab one *line*
|
||||||
# of input at a time. The linebreak may or may not occur
|
# of input at a time. The linebreak may or may not occur
|
||||||
# at the boundary where the string matches a format specifier.
|
# at the boundary where the string matches a format specifier.
|
||||||
# And if it does, some rule about whitespace may or may not
|
# And if it does, some rule about whitespace may or may not
|
||||||
# be in effect...
|
# be in effect...
|
||||||
#
|
#
|
||||||
# That's why this is much more elaborate than the string
|
# That's why this is much more elaborate than the string
|
||||||
# version.
|
# version.
|
||||||
#
|
#
|
||||||
# For each line:
|
# For each line:
|
||||||
# Match succeeds (non-emptily)
|
# Match succeeds (non-emptily)
|
||||||
# and the last attempted spec/string sub-match succeeded:
|
# and the last attempted spec/string sub-match succeeded:
|
||||||
#
|
#
|
||||||
# could the last spec keep matching?
|
# could the last spec keep matching?
|
||||||
# yes: save interim results and continue (next line)
|
# yes: save interim results and continue (next line)
|
||||||
#
|
#
|
||||||
# The last attempted spec/string did not match:
|
# The last attempted spec/string did not match:
|
||||||
#
|
#
|
||||||
# are we on the next-to-last spec in the string?
|
# are we on the next-to-last spec in the string?
|
||||||
# yes:
|
# yes:
|
||||||
# is fmt_string.string_left all spaces?
|
# is fmt_string.string_left all spaces?
|
||||||
# yes: does current spec care about input space?
|
# yes: does current spec care about input space?
|
||||||
# yes: fatal failure
|
# yes: fatal failure
|
||||||
# no: save interim results and continue
|
# no: save interim results and continue
|
||||||
# no: continue [this state could be analyzed further]
|
# no: continue [this state could be analyzed further]
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
def scanf(str,&b)
|
def scanf(str,&b)
|
||||||
return block_scanf(str,&b) if b
|
return block_scanf(str,&b) if b
|
||||||
@ -671,8 +671,8 @@ class IO
|
|||||||
|
|
||||||
def block_scanf(str)
|
def block_scanf(str)
|
||||||
final = []
|
final = []
|
||||||
# Sub-ideal, since another FS gets created in scanf.
|
# Sub-ideal, since another FS gets created in scanf.
|
||||||
# But used here to determine the number of specifiers.
|
# But used here to determine the number of specifiers.
|
||||||
fstr = Scanf::FormatString.new(str)
|
fstr = Scanf::FormatString.new(str)
|
||||||
last_spec = fstr.last_spec
|
last_spec = fstr.last_spec
|
||||||
begin
|
begin
|
||||||
|
534
lib/set.rb
534
lib/set.rb
@ -92,19 +92,19 @@ class Set
|
|||||||
@hash = orig.instance_eval{@hash}.dup
|
@hash = orig.instance_eval{@hash}.dup
|
||||||
end
|
end
|
||||||
|
|
||||||
def freeze # :nodoc:
|
def freeze # :nodoc:
|
||||||
super
|
super
|
||||||
@hash.freeze
|
@hash.freeze
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def taint # :nodoc:
|
def taint # :nodoc:
|
||||||
super
|
super
|
||||||
@hash.taint
|
@hash.taint
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def untaint # :nodoc:
|
def untaint # :nodoc:
|
||||||
super
|
super
|
||||||
@hash.untaint
|
@hash.untaint
|
||||||
self
|
self
|
||||||
@ -148,15 +148,15 @@ class Set
|
|||||||
def flatten_merge(set, seen = Set.new) # :nodoc:
|
def flatten_merge(set, seen = Set.new) # :nodoc:
|
||||||
set.each { |e|
|
set.each { |e|
|
||||||
if e.is_a?(Set)
|
if e.is_a?(Set)
|
||||||
if seen.include?(e_id = e.object_id)
|
if seen.include?(e_id = e.object_id)
|
||||||
raise ArgumentError, "tried to flatten recursive Set"
|
raise ArgumentError, "tried to flatten recursive Set"
|
||||||
end
|
end
|
||||||
|
|
||||||
seen.add(e_id)
|
seen.add(e_id)
|
||||||
flatten_merge(e, seen)
|
flatten_merge(e, seen)
|
||||||
seen.delete(e_id)
|
seen.delete(e_id)
|
||||||
else
|
else
|
||||||
add(e)
|
add(e)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,163 +325,163 @@ class Set
|
|||||||
def |(enum)
|
def |(enum)
|
||||||
dup.merge(enum)
|
dup.merge(enum)
|
||||||
end
|
end
|
||||||
alias + | ##
|
alias + | ##
|
||||||
alias union | ##
|
alias union | ##
|
||||||
|
|
||||||
# Returns a new set built by duplicating the set, removing every
|
# Returns a new set built by duplicating the set, removing every
|
||||||
# element that appears in the given enumerable object.
|
# element that appears in the given enumerable object.
|
||||||
def -(enum)
|
def -(enum)
|
||||||
dup.subtract(enum)
|
dup.subtract(enum)
|
||||||
end
|
|
||||||
alias difference - ##
|
|
||||||
|
|
||||||
# Returns a new set containing elements common to the set and the
|
|
||||||
# given enumerable object.
|
|
||||||
def &(enum)
|
|
||||||
n = self.class.new
|
|
||||||
do_with_enum(enum) { |o| n.add(o) if include?(o) }
|
|
||||||
n
|
|
||||||
end
|
|
||||||
alias intersection & ##
|
|
||||||
|
|
||||||
# Returns a new set containing elements exclusive between the set
|
|
||||||
# and the given enumerable object. (set ^ enum) is equivalent to
|
|
||||||
# ((set | enum) - (set & enum)).
|
|
||||||
def ^(enum)
|
|
||||||
n = Set.new(enum)
|
|
||||||
each { |o| if n.include?(o) then n.delete(o) else n.add(o) end }
|
|
||||||
n
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns true if two sets are equal. The equality of each couple
|
|
||||||
# of elements is defined according to Object#eql?.
|
|
||||||
def ==(other)
|
|
||||||
if self.equal?(other)
|
|
||||||
true
|
|
||||||
elsif other.instance_of?(self.class)
|
|
||||||
@hash == other.instance_variable_get(:@hash)
|
|
||||||
elsif other.is_a?(Set) && self.size == other.size
|
|
||||||
other.all? { |o| @hash.include?(o) }
|
|
||||||
else
|
|
||||||
false
|
|
||||||
end
|
end
|
||||||
|
alias difference - ##
|
||||||
|
|
||||||
|
# Returns a new set containing elements common to the set and the
|
||||||
|
# given enumerable object.
|
||||||
|
def &(enum)
|
||||||
|
n = self.class.new
|
||||||
|
do_with_enum(enum) { |o| n.add(o) if include?(o) }
|
||||||
|
n
|
||||||
|
end
|
||||||
|
alias intersection & ##
|
||||||
|
|
||||||
|
# Returns a new set containing elements exclusive between the set
|
||||||
|
# and the given enumerable object. (set ^ enum) is equivalent to
|
||||||
|
# ((set | enum) - (set & enum)).
|
||||||
|
def ^(enum)
|
||||||
|
n = Set.new(enum)
|
||||||
|
each { |o| if n.include?(o) then n.delete(o) else n.add(o) end }
|
||||||
|
n
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns true if two sets are equal. The equality of each couple
|
||||||
|
# of elements is defined according to Object#eql?.
|
||||||
|
def ==(other)
|
||||||
|
if self.equal?(other)
|
||||||
|
true
|
||||||
|
elsif other.instance_of?(self.class)
|
||||||
|
@hash == other.instance_variable_get(:@hash)
|
||||||
|
elsif other.is_a?(Set) && self.size == other.size
|
||||||
|
other.all? { |o| @hash.include?(o) }
|
||||||
|
else
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def hash # :nodoc:
|
def hash # :nodoc:
|
||||||
@hash.hash
|
@hash.hash
|
||||||
end
|
end
|
||||||
|
|
||||||
def eql?(o) # :nodoc:
|
def eql?(o) # :nodoc:
|
||||||
return false unless o.is_a?(Set)
|
return false unless o.is_a?(Set)
|
||||||
@hash.eql?(o.instance_eval{@hash})
|
@hash.eql?(o.instance_eval{@hash})
|
||||||
end
|
end
|
||||||
|
|
||||||
# Classifies the set by the return value of the given block and
|
# Classifies the set by the return value of the given block and
|
||||||
# returns a hash of {value => set of elements} pairs. The block is
|
# returns a hash of {value => set of elements} pairs. The block is
|
||||||
# called once for each element of the set, passing the element as
|
# called once for each element of the set, passing the element as
|
||||||
# parameter.
|
# parameter.
|
||||||
#
|
#
|
||||||
# e.g.:
|
# e.g.:
|
||||||
#
|
#
|
||||||
# require 'set'
|
# require 'set'
|
||||||
# files = Set.new(Dir.glob("*.rb"))
|
# files = Set.new(Dir.glob("*.rb"))
|
||||||
# hash = files.classify { |f| File.mtime(f).year }
|
# hash = files.classify { |f| File.mtime(f).year }
|
||||||
# p hash # => {2000=>#<Set: {"a.rb", "b.rb"}>,
|
# p hash # => {2000=>#<Set: {"a.rb", "b.rb"}>,
|
||||||
# # 2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
|
# # 2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
|
||||||
# # 2002=>#<Set: {"f.rb"}>}
|
# # 2002=>#<Set: {"f.rb"}>}
|
||||||
def classify # :yields: o
|
def classify # :yields: o
|
||||||
block_given? or return enum_for(__method__)
|
block_given? or return enum_for(__method__)
|
||||||
|
|
||||||
h = {}
|
h = {}
|
||||||
|
|
||||||
each { |i|
|
each { |i|
|
||||||
x = yield(i)
|
x = yield(i)
|
||||||
(h[x] ||= self.class.new).add(i)
|
(h[x] ||= self.class.new).add(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
h
|
h
|
||||||
end
|
end
|
||||||
|
|
||||||
# Divides the set into a set of subsets according to the commonality
|
# Divides the set into a set of subsets according to the commonality
|
||||||
# defined by the given block.
|
# defined by the given block.
|
||||||
#
|
#
|
||||||
# If the arity of the block is 2, elements o1 and o2 are in common
|
# If the arity of the block is 2, elements o1 and o2 are in common
|
||||||
# if block.call(o1, o2) is true. Otherwise, elements o1 and o2 are
|
# if block.call(o1, o2) is true. Otherwise, elements o1 and o2 are
|
||||||
# in common if block.call(o1) == block.call(o2).
|
# in common if block.call(o1) == block.call(o2).
|
||||||
#
|
#
|
||||||
# e.g.:
|
# e.g.:
|
||||||
#
|
#
|
||||||
# require 'set'
|
# require 'set'
|
||||||
# numbers = Set[1, 3, 4, 6, 9, 10, 11]
|
# numbers = Set[1, 3, 4, 6, 9, 10, 11]
|
||||||
# set = numbers.divide { |i,j| (i - j).abs == 1 }
|
# set = numbers.divide { |i,j| (i - j).abs == 1 }
|
||||||
# p set # => #<Set: {#<Set: {1}>,
|
# p set # => #<Set: {#<Set: {1}>,
|
||||||
# # #<Set: {11, 9, 10}>,
|
# # #<Set: {11, 9, 10}>,
|
||||||
# # #<Set: {3, 4}>,
|
# # #<Set: {3, 4}>,
|
||||||
# # #<Set: {6}>}>
|
# # #<Set: {6}>}>
|
||||||
def divide(&func)
|
def divide(&func)
|
||||||
func or return enum_for(__method__)
|
func or return enum_for(__method__)
|
||||||
|
|
||||||
if func.arity == 2
|
if func.arity == 2
|
||||||
require 'tsort'
|
require 'tsort'
|
||||||
|
|
||||||
class << dig = {} # :nodoc:
|
class << dig = {} # :nodoc:
|
||||||
include TSort
|
include TSort
|
||||||
|
|
||||||
alias tsort_each_node each_key
|
alias tsort_each_node each_key
|
||||||
def tsort_each_child(node, &block)
|
def tsort_each_child(node, &block)
|
||||||
fetch(node).each(&block)
|
fetch(node).each(&block)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
each { |u|
|
|
||||||
dig[u] = a = []
|
|
||||||
each{ |v| func.call(u, v) and a << v }
|
|
||||||
}
|
|
||||||
|
|
||||||
set = Set.new()
|
|
||||||
dig.each_strongly_connected_component { |css|
|
|
||||||
set.add(self.class.new(css))
|
|
||||||
}
|
|
||||||
set
|
|
||||||
else
|
|
||||||
Set.new(classify(&func).values)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
InspectKey = :__inspect_key__ # :nodoc:
|
|
||||||
|
|
||||||
# Returns a string containing a human-readable representation of the
|
|
||||||
# set. ("#<Set: {element1, element2, ...}>")
|
|
||||||
def inspect
|
|
||||||
ids = (Thread.current[InspectKey] ||= [])
|
|
||||||
|
|
||||||
if ids.include?(object_id)
|
|
||||||
return sprintf('#<%s: {...}>', self.class.name)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
each { |u|
|
||||||
ids << object_id
|
dig[u] = a = []
|
||||||
return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])
|
each{ |v| func.call(u, v) and a << v }
|
||||||
ensure
|
|
||||||
ids.pop
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def pretty_print(pp) # :nodoc:
|
|
||||||
pp.text sprintf('#<%s: {', self.class.name)
|
|
||||||
pp.nest(1) {
|
|
||||||
pp.seplist(self) { |o|
|
|
||||||
pp.pp o
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pp.text "}>"
|
|
||||||
|
set = Set.new()
|
||||||
|
dig.each_strongly_connected_component { |css|
|
||||||
|
set.add(self.class.new(css))
|
||||||
|
}
|
||||||
|
set
|
||||||
|
else
|
||||||
|
Set.new(classify(&func).values)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
InspectKey = :__inspect_key__ # :nodoc:
|
||||||
|
|
||||||
|
# Returns a string containing a human-readable representation of the
|
||||||
|
# set. ("#<Set: {element1, element2, ...}>")
|
||||||
|
def inspect
|
||||||
|
ids = (Thread.current[InspectKey] ||= [])
|
||||||
|
|
||||||
|
if ids.include?(object_id)
|
||||||
|
return sprintf('#<%s: {...}>', self.class.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pretty_print_cycle(pp) # :nodoc:
|
begin
|
||||||
pp.text sprintf('#<%s: {%s}>', self.class.name, empty? ? '' : '...')
|
ids << object_id
|
||||||
|
return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])
|
||||||
|
ensure
|
||||||
|
ids.pop
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def pretty_print(pp) # :nodoc:
|
||||||
|
pp.text sprintf('#<%s: {', self.class.name)
|
||||||
|
pp.nest(1) {
|
||||||
|
pp.seplist(self) { |o|
|
||||||
|
pp.pp o
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pp.text "}>"
|
||||||
|
end
|
||||||
|
|
||||||
|
def pretty_print_cycle(pp) # :nodoc:
|
||||||
|
pp.text sprintf('#<%s: {%s}>', self.class.name, empty? ? '' : '...')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# SortedSet implements a Set that guarantees that it's element are
|
# SortedSet implements a Set that guarantees that it's element are
|
||||||
# yielded in sorted order (according to the return values of their
|
# yielded in sorted order (according to the return values of their
|
||||||
@ -515,11 +515,11 @@ class SortedSet < Set
|
|||||||
@@setup = false
|
@@setup = false
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def [](*ary) # :nodoc:
|
def [](*ary) # :nodoc:
|
||||||
new(ary)
|
new(ary)
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup # :nodoc:
|
def setup # :nodoc:
|
||||||
@@setup and return
|
@@setup and return
|
||||||
|
|
||||||
module_eval {
|
module_eval {
|
||||||
@ -528,89 +528,89 @@ class SortedSet < Set
|
|||||||
remove_method :old_init
|
remove_method :old_init
|
||||||
}
|
}
|
||||||
begin
|
begin
|
||||||
require 'rbtree'
|
require 'rbtree'
|
||||||
|
|
||||||
module_eval %{
|
module_eval %{
|
||||||
def initialize(*args, &block)
|
def initialize(*args, &block)
|
||||||
@hash = RBTree.new
|
@hash = RBTree.new
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def add(o)
|
def add(o)
|
||||||
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
|
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
alias << add
|
alias << add
|
||||||
}
|
}
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
module_eval %{
|
module_eval %{
|
||||||
def initialize(*args, &block)
|
def initialize(*args, &block)
|
||||||
@keys = nil
|
@keys = nil
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def clear
|
def clear
|
||||||
@keys = nil
|
@keys = nil
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace(enum)
|
def replace(enum)
|
||||||
@keys = nil
|
@keys = nil
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def add(o)
|
def add(o)
|
||||||
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
|
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
|
||||||
@keys = nil
|
@keys = nil
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
alias << add
|
alias << add
|
||||||
|
|
||||||
def delete(o)
|
def delete(o)
|
||||||
@keys = nil
|
@keys = nil
|
||||||
@hash.delete(o)
|
@hash.delete(o)
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_if
|
def delete_if
|
||||||
block_given? or return enum_for(__method__)
|
block_given? or return enum_for(__method__)
|
||||||
n = @hash.size
|
n = @hash.size
|
||||||
super
|
super
|
||||||
@keys = nil if @hash.size != n
|
@keys = nil if @hash.size != n
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def keep_if
|
def keep_if
|
||||||
block_given? or return enum_for(__method__)
|
block_given? or return enum_for(__method__)
|
||||||
n = @hash.size
|
n = @hash.size
|
||||||
super
|
super
|
||||||
@keys = nil if @hash.size != n
|
@keys = nil if @hash.size != n
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def merge(enum)
|
def merge(enum)
|
||||||
@keys = nil
|
@keys = nil
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def each
|
def each
|
||||||
block_given? or return enum_for(__method__)
|
block_given? or return enum_for(__method__)
|
||||||
to_a.each { |o| yield(o) }
|
to_a.each { |o| yield(o) }
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_a
|
def to_a
|
||||||
(@keys = @hash.keys).sort! unless @keys
|
(@keys = @hash.keys).sort! unless @keys
|
||||||
@keys
|
@keys
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@setup = true
|
@@setup = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(*args, &block) # :nodoc:
|
def initialize(*args, &block) # :nodoc:
|
||||||
SortedSet.setup
|
SortedSet.setup
|
||||||
initialize(*args, &block)
|
initialize(*args, &block)
|
||||||
end
|
end
|
||||||
@ -657,54 +657,54 @@ end
|
|||||||
#
|
#
|
||||||
# if @proc.arity == 2
|
# if @proc.arity == 2
|
||||||
# instance_eval %{
|
# instance_eval %{
|
||||||
# def add(o)
|
# def add(o)
|
||||||
# @hash[o] = true if @proc.call(self, o)
|
# @hash[o] = true if @proc.call(self, o)
|
||||||
# self
|
# self
|
||||||
# end
|
# end
|
||||||
# alias << add
|
# alias << add
|
||||||
#
|
#
|
||||||
# def add?(o)
|
# def add?(o)
|
||||||
# if include?(o) || !@proc.call(self, o)
|
# if include?(o) || !@proc.call(self, o)
|
||||||
# nil
|
# nil
|
||||||
# else
|
# else
|
||||||
# @hash[o] = true
|
# @hash[o] = true
|
||||||
# self
|
# self
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# def replace(enum)
|
# def replace(enum)
|
||||||
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
|
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
|
||||||
# clear
|
# clear
|
||||||
# enum.each_entry { |o| add(o) }
|
# enum.each_entry { |o| add(o) }
|
||||||
#
|
#
|
||||||
# self
|
# self
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# def merge(enum)
|
# def merge(enum)
|
||||||
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
|
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
|
||||||
# enum.each_entry { |o| add(o) }
|
# enum.each_entry { |o| add(o) }
|
||||||
#
|
#
|
||||||
# self
|
# self
|
||||||
# end
|
# end
|
||||||
# }
|
# }
|
||||||
# else
|
# else
|
||||||
# instance_eval %{
|
# instance_eval %{
|
||||||
# def add(o)
|
# def add(o)
|
||||||
# if @proc.call(o)
|
# if @proc.call(o)
|
||||||
# @hash[o] = true
|
# @hash[o] = true
|
||||||
# end
|
# end
|
||||||
# self
|
# self
|
||||||
# end
|
# end
|
||||||
# alias << add
|
# alias << add
|
||||||
#
|
#
|
||||||
# def add?(o)
|
# def add?(o)
|
||||||
# if include?(o) || !@proc.call(o)
|
# if include?(o) || !@proc.call(o)
|
||||||
# nil
|
# nil
|
||||||
# else
|
# else
|
||||||
# @hash[o] = true
|
# @hash[o] = true
|
||||||
# self
|
# self
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
# }
|
# }
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
@ -835,13 +835,13 @@ class TC_Set < Test::Unit::TestCase
|
|||||||
set1 = Set[
|
set1 = Set[
|
||||||
1,
|
1,
|
||||||
Set[
|
Set[
|
||||||
5,
|
5,
|
||||||
Set[7,
|
Set[7,
|
||||||
Set[0]
|
Set[0]
|
||||||
],
|
],
|
||||||
Set[6,2],
|
Set[6,2],
|
||||||
1
|
1
|
||||||
],
|
],
|
||||||
3,
|
3,
|
||||||
Set[3,4]
|
Set[3,4]
|
||||||
]
|
]
|
||||||
@ -1020,8 +1020,8 @@ class TC_Set < Test::Unit::TestCase
|
|||||||
|
|
||||||
assert_nothing_raised {
|
assert_nothing_raised {
|
||||||
set.each { |o|
|
set.each { |o|
|
||||||
ary.delete(o) or raise "unexpected element: #{o}"
|
ary.delete(o) or raise "unexpected element: #{o}"
|
||||||
}
|
}
|
||||||
|
|
||||||
ary.empty? or raise "forgotten elements: #{ary.join(', ')}"
|
ary.empty? or raise "forgotten elements: #{ary.join(', ')}"
|
||||||
}
|
}
|
||||||
@ -1085,11 +1085,11 @@ class TC_Set < Test::Unit::TestCase
|
|||||||
ret = set.collect! { |i|
|
ret = set.collect! { |i|
|
||||||
case i
|
case i
|
||||||
when Numeric
|
when Numeric
|
||||||
i * 2
|
i * 2
|
||||||
when String
|
when String
|
||||||
i.upcase
|
i.upcase
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,8 +1168,8 @@ class TC_Set < Test::Unit::TestCase
|
|||||||
set2 = Set["a", "b", set1]
|
set2 = Set["a", "b", set1]
|
||||||
set1 = set1.add(set1.clone)
|
set1 = set1.add(set1.clone)
|
||||||
|
|
||||||
# assert_equal(set1, set2)
|
# assert_equal(set1, set2)
|
||||||
# assert_equal(set2, set1)
|
# assert_equal(set2, set1)
|
||||||
assert_equal(set2, set2.clone)
|
assert_equal(set2, set2.clone)
|
||||||
assert_equal(set1.clone, set1)
|
assert_equal(set1.clone, set1)
|
||||||
|
|
||||||
@ -1214,15 +1214,15 @@ class TC_Set < Test::Unit::TestCase
|
|||||||
assert_equal(set, ret.flatten)
|
assert_equal(set, ret.flatten)
|
||||||
ret.each { |s|
|
ret.each { |s|
|
||||||
if s.include?(0)
|
if s.include?(0)
|
||||||
assert_equal(Set[0,1], s)
|
assert_equal(Set[0,1], s)
|
||||||
elsif s.include?(3)
|
elsif s.include?(3)
|
||||||
assert_equal(Set[3,4,5], s)
|
assert_equal(Set[3,4,5], s)
|
||||||
elsif s.include?(7)
|
elsif s.include?(7)
|
||||||
assert_equal(Set[7], s)
|
assert_equal(Set[7], s)
|
||||||
elsif s.include?(9)
|
elsif s.include?(9)
|
||||||
assert_equal(Set[9,10,11], s)
|
assert_equal(Set[9,10,11], s)
|
||||||
else
|
else
|
||||||
raise "unexpected group: #{s.inspect}"
|
raise "unexpected group: #{s.inspect}"
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
72
lib/shell.rb
72
lib/shell.rb
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# shell.rb -
|
# shell.rb -
|
||||||
# $Release Version: 0.7 $
|
# $Release Version: 0.7 $
|
||||||
# $Revision: 1.9 $
|
# $Revision: 1.9 $
|
||||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
#
|
#
|
||||||
@ -25,7 +25,7 @@ class Shell
|
|||||||
include Error
|
include Error
|
||||||
extend Exception2MessageMapper
|
extend Exception2MessageMapper
|
||||||
|
|
||||||
# @cascade = true
|
# @cascade = true
|
||||||
# debug: true -> normal debug
|
# debug: true -> normal debug
|
||||||
# debug: 1 -> eval definition debug
|
# debug: 1 -> eval definition debug
|
||||||
# debug: 2 -> detail inspect debug
|
# debug: 2 -> detail inspect debug
|
||||||
@ -41,7 +41,7 @@ class Shell
|
|||||||
|
|
||||||
attr_accessor :cascade, :debug, :verbose
|
attr_accessor :cascade, :debug, :verbose
|
||||||
|
|
||||||
# alias cascade? cascade
|
# alias cascade? cascade
|
||||||
alias debug? debug
|
alias debug? debug
|
||||||
alias verbose? verbose
|
alias verbose? verbose
|
||||||
@verbose = true
|
@verbose = true
|
||||||
@ -57,9 +57,9 @@ class Shell
|
|||||||
|
|
||||||
def default_system_path
|
def default_system_path
|
||||||
if @default_system_path
|
if @default_system_path
|
||||||
@default_system_path
|
@default_system_path
|
||||||
else
|
else
|
||||||
ENV["PATH"].split(":")
|
ENV["PATH"].split(":")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -69,9 +69,9 @@ class Shell
|
|||||||
|
|
||||||
def default_record_separator
|
def default_record_separator
|
||||||
if @default_record_separator
|
if @default_record_separator
|
||||||
@default_record_separator
|
@default_record_separator
|
||||||
else
|
else
|
||||||
$/
|
$/
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -156,10 +156,10 @@ class Shell
|
|||||||
notify("chdir(with block) #{path}") if verbose
|
notify("chdir(with block) #{path}") if verbose
|
||||||
cwd_old = @cwd
|
cwd_old = @cwd
|
||||||
begin
|
begin
|
||||||
chdir(path, nil)
|
chdir(path, nil)
|
||||||
yield
|
yield
|
||||||
ensure
|
ensure
|
||||||
chdir(cwd_old, nil)
|
chdir(cwd_old, nil)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
notify("chdir #{path}") if verbose
|
notify("chdir #{path}") if verbose
|
||||||
@ -179,9 +179,9 @@ class Shell
|
|||||||
notify("pushdir(with block) #{path}") if verbose
|
notify("pushdir(with block) #{path}") if verbose
|
||||||
pushdir(path, nil)
|
pushdir(path, nil)
|
||||||
begin
|
begin
|
||||||
yield
|
yield
|
||||||
ensure
|
ensure
|
||||||
popdir
|
popdir
|
||||||
end
|
end
|
||||||
elsif path
|
elsif path
|
||||||
notify("pushdir #{path}") if verbose
|
notify("pushdir #{path}") if verbose
|
||||||
@ -192,12 +192,12 @@ class Shell
|
|||||||
else
|
else
|
||||||
notify("pushdir") if verbose
|
notify("pushdir") if verbose
|
||||||
if pop = @dir_stack.pop
|
if pop = @dir_stack.pop
|
||||||
@dir_stack.push @cwd
|
@dir_stack.push @cwd
|
||||||
chdir pop
|
chdir pop
|
||||||
notify "dir stack: [#{@dir_stack.join ', '}]"
|
notify "dir stack: [#{@dir_stack.join ', '}]"
|
||||||
self
|
self
|
||||||
else
|
else
|
||||||
Shell.Fail DirStackEmpty
|
Shell.Fail DirStackEmpty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Void.new(self)
|
Void.new(self)
|
||||||
@ -265,32 +265,32 @@ class Shell
|
|||||||
def self.notify(*opts, &block)
|
def self.notify(*opts, &block)
|
||||||
Shell::debug_output_synchronize do
|
Shell::debug_output_synchronize do
|
||||||
if opts[-1].kind_of?(String)
|
if opts[-1].kind_of?(String)
|
||||||
yorn = verbose?
|
yorn = verbose?
|
||||||
else
|
else
|
||||||
yorn = opts.pop
|
yorn = opts.pop
|
||||||
end
|
end
|
||||||
return unless yorn
|
return unless yorn
|
||||||
|
|
||||||
if @debug_display_thread_id
|
if @debug_display_thread_id
|
||||||
if @debug_display_process_id
|
if @debug_display_process_id
|
||||||
prefix = "shell(##{Process.pid}:#{Thread.current.to_s.sub("Thread", "Th")}): "
|
prefix = "shell(##{Process.pid}:#{Thread.current.to_s.sub("Thread", "Th")}): "
|
||||||
else
|
else
|
||||||
prefix = "shell(#{Thread.current.to_s.sub("Thread", "Th")}): "
|
prefix = "shell(#{Thread.current.to_s.sub("Thread", "Th")}): "
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
prefix = "shell: "
|
prefix = "shell: "
|
||||||
end
|
end
|
||||||
_head = true
|
_head = true
|
||||||
STDERR.print opts.collect{|mes|
|
STDERR.print opts.collect{|mes|
|
||||||
mes = mes.dup
|
mes = mes.dup
|
||||||
yield mes if iterator?
|
yield mes if iterator?
|
||||||
if _head
|
if _head
|
||||||
_head = false
|
_head = false
|
||||||
# "shell" " + mes
|
# "shell" " + mes
|
||||||
prefix + mes
|
prefix + mes
|
||||||
else
|
else
|
||||||
" "* prefix.size + mes
|
" "* prefix.size + mes
|
||||||
end
|
end
|
||||||
}.join("\n")+"\n"
|
}.join("\n")+"\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# shell/builtin-command.rb -
|
# shell/builtin-command.rb -
|
||||||
# $Release Version: 0.7 $
|
# $Release Version: 0.7 $
|
||||||
# $Revision$
|
# $Revision$
|
||||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
#
|
#
|
||||||
@ -40,7 +40,7 @@ class Shell
|
|||||||
def each(rs = nil)
|
def each(rs = nil)
|
||||||
rs = @shell.record_separator unless rs
|
rs = @shell.record_separator unless rs
|
||||||
for str in @strings
|
for str in @strings
|
||||||
yield str + rs
|
yield str + rs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -53,11 +53,11 @@ class Shell
|
|||||||
|
|
||||||
def each(rs = nil)
|
def each(rs = nil)
|
||||||
if @cat_files.empty?
|
if @cat_files.empty?
|
||||||
super
|
super
|
||||||
else
|
else
|
||||||
for src in @cat_files
|
for src in @cat_files
|
||||||
@shell.foreach(src, rs){|l| yield l}
|
@shell.foreach(src, rs){|l| yield l}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -71,31 +71,31 @@ class Shell
|
|||||||
|
|
||||||
def each(rs = nil)
|
def each(rs = nil)
|
||||||
if @pattern[0] == ?/
|
if @pattern[0] == ?/
|
||||||
@files = Dir[@pattern]
|
@files = Dir[@pattern]
|
||||||
else
|
else
|
||||||
prefix = @shell.pwd+"/"
|
prefix = @shell.pwd+"/"
|
||||||
@files = Dir[prefix+@pattern].collect{|p| p.sub(prefix, "")}
|
@files = Dir[prefix+@pattern].collect{|p| p.sub(prefix, "")}
|
||||||
end
|
end
|
||||||
rs = @shell.record_separator unless rs
|
rs = @shell.record_separator unless rs
|
||||||
for f in @files
|
for f in @files
|
||||||
yield f+rs
|
yield f+rs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# class Sort < Cat
|
# class Sort < Cat
|
||||||
# def initialize(sh, *filenames)
|
# def initialize(sh, *filenames)
|
||||||
# super
|
# super
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# def each(rs = nil)
|
# def each(rs = nil)
|
||||||
# ary = []
|
# ary = []
|
||||||
# super{|l| ary.push l}
|
# super{|l| ary.push l}
|
||||||
# for l in ary.sort!
|
# for l in ary.sort!
|
||||||
# yield l
|
# yield l
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
|
|
||||||
class AppendIO < BuiltInCommand
|
class AppendIO < BuiltInCommand
|
||||||
def initialize(sh, io, filter)
|
def initialize(sh, io, filter)
|
||||||
@ -107,7 +107,7 @@ class Shell
|
|||||||
def input=(filter)
|
def input=(filter)
|
||||||
@input.input=filter
|
@input.input=filter
|
||||||
for l in @input
|
for l in @input
|
||||||
@io << l
|
@io << l
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -122,9 +122,9 @@ class Shell
|
|||||||
|
|
||||||
def input=(filter)
|
def input=(filter)
|
||||||
begin
|
begin
|
||||||
super
|
super
|
||||||
ensure
|
ensure
|
||||||
@io.close
|
@io.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -138,9 +138,9 @@ class Shell
|
|||||||
def each(rs = nil)
|
def each(rs = nil)
|
||||||
to = @shell.open(@to_filename, "w")
|
to = @shell.open(@to_filename, "w")
|
||||||
begin
|
begin
|
||||||
super{|l| to << l; yield l}
|
super{|l| to << l; yield l}
|
||||||
ensure
|
ensure
|
||||||
to.close
|
to.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -153,7 +153,7 @@ class Shell
|
|||||||
|
|
||||||
def each(rs = nil)
|
def each(rs = nil)
|
||||||
while job = @jobs.shift
|
while job = @jobs.shift
|
||||||
job.each{|l| yield l}
|
job.each{|l| yield l}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# shell/command-controller.rb -
|
# shell/command-controller.rb -
|
||||||
# $Release Version: 0.7 $
|
# $Release Version: 0.7 $
|
||||||
# $Revision$
|
# $Revision$
|
||||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
#
|
#
|
||||||
@ -19,7 +19,7 @@ require "shell/builtin-command"
|
|||||||
|
|
||||||
class Shell
|
class Shell
|
||||||
class CommandProcessor
|
class CommandProcessor
|
||||||
# include Error
|
# include Error
|
||||||
|
|
||||||
#
|
#
|
||||||
# initialize of Shell and related classes.
|
# initialize of Shell and related classes.
|
||||||
@ -37,11 +37,11 @@ class Shell
|
|||||||
|
|
||||||
# define CommandProcessor#methods to Shell#methods and Filter#methods
|
# define CommandProcessor#methods to Shell#methods and Filter#methods
|
||||||
for m in CommandProcessor.instance_methods(false) - NoDelegateMethods
|
for m in CommandProcessor.instance_methods(false) - NoDelegateMethods
|
||||||
add_delegate_command_to_shell(m)
|
add_delegate_command_to_shell(m)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.method_added(id)
|
def self.method_added(id)
|
||||||
add_delegate_command_to_shell(id)
|
add_delegate_command_to_shell(id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -50,14 +50,14 @@ class Shell
|
|||||||
#
|
#
|
||||||
def self.run_config
|
def self.run_config
|
||||||
begin
|
begin
|
||||||
load File.expand_path("~/.rb_shell") if ENV.key?("HOME")
|
load File.expand_path("~/.rb_shell") if ENV.key?("HOME")
|
||||||
rescue LoadError, Errno::ENOENT
|
rescue LoadError, Errno::ENOENT
|
||||||
rescue
|
rescue
|
||||||
print "load error: #{rc}\n"
|
print "load error: #{rc}\n"
|
||||||
print $!.class, ": ", $!, "\n"
|
print $!.class, ": ", $!, "\n"
|
||||||
for err in $@[0, $@.size - 2]
|
for err in $@[0, $@.size - 2]
|
||||||
print "\t", err, "\n"
|
print "\t", err, "\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -68,9 +68,9 @@ class Shell
|
|||||||
|
|
||||||
#
|
#
|
||||||
# CommandProcessor#expand_path(path)
|
# CommandProcessor#expand_path(path)
|
||||||
# path: String
|
# path: String
|
||||||
# return: String
|
# return: String
|
||||||
# returns the absolute path for <path>
|
# returns the absolute path for <path>
|
||||||
#
|
#
|
||||||
def expand_path(path)
|
def expand_path(path)
|
||||||
@shell.expand_path(path)
|
@shell.expand_path(path)
|
||||||
@ -86,68 +86,68 @@ class Shell
|
|||||||
# -
|
# -
|
||||||
#
|
#
|
||||||
# CommandProcessor#foreach(path, rs)
|
# CommandProcessor#foreach(path, rs)
|
||||||
# path: String
|
# path: String
|
||||||
# rs: String - record separator
|
# rs: String - record separator
|
||||||
# iterator
|
# iterator
|
||||||
# Same as:
|
# Same as:
|
||||||
# File#foreach (when path is file)
|
# File#foreach (when path is file)
|
||||||
# Dir#foreach (when path is directory)
|
# Dir#foreach (when path is directory)
|
||||||
# path is relative to pwd
|
# path is relative to pwd
|
||||||
#
|
#
|
||||||
def foreach(path = nil, *rs)
|
def foreach(path = nil, *rs)
|
||||||
path = "." unless path
|
path = "." unless path
|
||||||
path = expand_path(path)
|
path = expand_path(path)
|
||||||
|
|
||||||
if File.directory?(path)
|
if File.directory?(path)
|
||||||
Dir.foreach(path){|fn| yield fn}
|
Dir.foreach(path){|fn| yield fn}
|
||||||
else
|
else
|
||||||
IO.foreach(path, *rs){|l| yield l}
|
IO.foreach(path, *rs){|l| yield l}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# CommandProcessor#open(path, mode)
|
# CommandProcessor#open(path, mode)
|
||||||
# path: String
|
# path: String
|
||||||
# mode: String
|
# mode: String
|
||||||
# return: File or Dir
|
# return: File or Dir
|
||||||
# Same as:
|
# Same as:
|
||||||
# File#open (when path is file)
|
# File#open (when path is file)
|
||||||
# Dir#open (when path is directory)
|
# Dir#open (when path is directory)
|
||||||
# mode has an effect only when path is a file
|
# mode has an effect only when path is a file
|
||||||
#
|
#
|
||||||
def open(path, mode = nil, perm = 0666, &b)
|
def open(path, mode = nil, perm = 0666, &b)
|
||||||
path = expand_path(path)
|
path = expand_path(path)
|
||||||
if File.directory?(path)
|
if File.directory?(path)
|
||||||
Dir.open(path, &b)
|
Dir.open(path, &b)
|
||||||
else
|
else
|
||||||
if @shell.umask
|
if @shell.umask
|
||||||
f = File.open(path, mode, perm)
|
f = File.open(path, mode, perm)
|
||||||
File.chmod(perm & ~@shell.umask, path)
|
File.chmod(perm & ~@shell.umask, path)
|
||||||
if block_given?
|
if block_given?
|
||||||
f.each(&b)
|
f.each(&b)
|
||||||
end
|
end
|
||||||
f
|
f
|
||||||
else
|
else
|
||||||
f = File.open(path, mode, perm, &b)
|
f = File.open(path, mode, perm, &b)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# public :open
|
# public :open
|
||||||
|
|
||||||
#
|
#
|
||||||
# CommandProcessor#unlink(path)
|
# CommandProcessor#unlink(path)
|
||||||
# same as:
|
# same as:
|
||||||
# Dir#unlink (when path is directory)
|
# Dir#unlink (when path is directory)
|
||||||
# File#unlink (when path is file)
|
# File#unlink (when path is file)
|
||||||
#
|
#
|
||||||
def unlink(path)
|
def unlink(path)
|
||||||
@shell.check_point
|
@shell.check_point
|
||||||
|
|
||||||
path = expand_path(path)
|
path = expand_path(path)
|
||||||
if File.directory?(path)
|
if File.directory?(path)
|
||||||
Dir.unlink(path)
|
Dir.unlink(path)
|
||||||
else
|
else
|
||||||
IO.unlink(path)
|
IO.unlink(path)
|
||||||
end
|
end
|
||||||
Void.new(@shell)
|
Void.new(@shell)
|
||||||
end
|
end
|
||||||
@ -155,19 +155,19 @@ class Shell
|
|||||||
#
|
#
|
||||||
# CommandProcessor#test(command, file1, file2)
|
# CommandProcessor#test(command, file1, file2)
|
||||||
# CommandProcessor#[command, file1, file2]
|
# CommandProcessor#[command, file1, file2]
|
||||||
# command: char or String or Symbol
|
# command: char or String or Symbol
|
||||||
# file1: String
|
# file1: String
|
||||||
# file2: String(optional)
|
# file2: String(optional)
|
||||||
# return: Boolean
|
# return: Boolean
|
||||||
# same as:
|
# same as:
|
||||||
# test() (when command is char or length 1 string or symbol)
|
# test() (when command is char or length 1 string or symbol)
|
||||||
# FileTest.command (others)
|
# FileTest.command (others)
|
||||||
# example:
|
# example:
|
||||||
# sh[?e, "foo"]
|
# sh[?e, "foo"]
|
||||||
# sh[:e, "foo"]
|
# sh[:e, "foo"]
|
||||||
# sh["e", "foo"]
|
# sh["e", "foo"]
|
||||||
# sh[:exists?, "foo"]
|
# sh[:exists?, "foo"]
|
||||||
# sh["exists?", "foo"]
|
# sh["exists?", "foo"]
|
||||||
#
|
#
|
||||||
alias top_level_test test
|
alias top_level_test test
|
||||||
def test(command, file1, file2=nil)
|
def test(command, file1, file2=nil)
|
||||||
@ -177,25 +177,25 @@ class Shell
|
|||||||
|
|
||||||
case command
|
case command
|
||||||
when Integer
|
when Integer
|
||||||
if file2
|
if file2
|
||||||
top_level_test(command, file1, file2)
|
top_level_test(command, file1, file2)
|
||||||
else
|
else
|
||||||
top_level_test(command, file1)
|
top_level_test(command, file1)
|
||||||
end
|
end
|
||||||
when String
|
when String
|
||||||
if command.size == 1
|
if command.size == 1
|
||||||
if file2
|
if file2
|
||||||
top_level_test(command, file1, file2)
|
top_level_test(command, file1, file2)
|
||||||
else
|
else
|
||||||
top_level_test(command, file1)
|
top_level_test(command, file1)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if file2
|
if file2
|
||||||
FileTest.send(command, file1, file2)
|
FileTest.send(command, file1, file2)
|
||||||
else
|
else
|
||||||
FileTest.send(command, file1)
|
FileTest.send(command, file1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias [] test
|
alias [] test
|
||||||
@ -209,8 +209,8 @@ class Shell
|
|||||||
#--
|
#--
|
||||||
#
|
#
|
||||||
# CommandProcessor#mkdir(*path)
|
# CommandProcessor#mkdir(*path)
|
||||||
# path: String
|
# path: String
|
||||||
# same as Dir.mkdir()
|
# same as Dir.mkdir()
|
||||||
#
|
#
|
||||||
def mkdir(*path)
|
def mkdir(*path)
|
||||||
@shell.check_point
|
@shell.check_point
|
||||||
@ -218,59 +218,59 @@ class Shell
|
|||||||
|
|
||||||
perm = nil
|
perm = nil
|
||||||
if path.last.kind_of?(Integer)
|
if path.last.kind_of?(Integer)
|
||||||
perm = path.pop
|
perm = path.pop
|
||||||
end
|
end
|
||||||
for dir in path
|
for dir in path
|
||||||
d = expand_path(dir)
|
d = expand_path(dir)
|
||||||
if perm
|
if perm
|
||||||
Dir.mkdir(d, perm)
|
Dir.mkdir(d, perm)
|
||||||
else
|
else
|
||||||
Dir.mkdir(d)
|
Dir.mkdir(d)
|
||||||
end
|
end
|
||||||
File.chmod(d, 0666 & ~@shell.umask) if @shell.umask
|
File.chmod(d, 0666 & ~@shell.umask) if @shell.umask
|
||||||
end
|
end
|
||||||
Void.new(@shell)
|
Void.new(@shell)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# CommandProcessor#rmdir(*path)
|
# CommandProcessor#rmdir(*path)
|
||||||
# path: String
|
# path: String
|
||||||
# same as Dir.rmdir()
|
# same as Dir.rmdir()
|
||||||
#
|
#
|
||||||
def rmdir(*path)
|
def rmdir(*path)
|
||||||
@shell.check_point
|
@shell.check_point
|
||||||
notify("rmdir #{path.join(' ')}")
|
notify("rmdir #{path.join(' ')}")
|
||||||
|
|
||||||
for dir in path
|
for dir in path
|
||||||
Dir.rmdir(expand_path(dir))
|
Dir.rmdir(expand_path(dir))
|
||||||
end
|
end
|
||||||
Void.new(@shell)
|
Void.new(@shell)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# CommandProcessor#system(command, *opts)
|
# CommandProcessor#system(command, *opts)
|
||||||
# command: String
|
# command: String
|
||||||
# opts: String
|
# opts: String
|
||||||
# return: SystemCommand
|
# return: SystemCommand
|
||||||
# Same as system() function
|
# Same as system() function
|
||||||
# example:
|
# example:
|
||||||
# print sh.system("ls", "-l")
|
# print sh.system("ls", "-l")
|
||||||
# sh.system("ls", "-l") | sh.head > STDOUT
|
# sh.system("ls", "-l") | sh.head > STDOUT
|
||||||
#
|
#
|
||||||
def system(command, *opts)
|
def system(command, *opts)
|
||||||
if opts.empty?
|
if opts.empty?
|
||||||
if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
|
if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
|
||||||
return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
|
return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
|
||||||
else
|
else
|
||||||
command, *opts = command.split(/\s+/)
|
command, *opts = command.split(/\s+/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
SystemCommand.new(@shell, find_system_command(command), *opts)
|
SystemCommand.new(@shell, find_system_command(command), *opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# ProcessCommand#rehash
|
# ProcessCommand#rehash
|
||||||
# clear command hash table.
|
# clear command hash table.
|
||||||
#
|
#
|
||||||
def rehash
|
def rehash
|
||||||
@system_commands = {}
|
@system_commands = {}
|
||||||
@ -286,9 +286,9 @@ class Shell
|
|||||||
|
|
||||||
def transact(&block)
|
def transact(&block)
|
||||||
begin
|
begin
|
||||||
@shell.instance_eval(&block)
|
@shell.instance_eval(&block)
|
||||||
ensure
|
ensure
|
||||||
check_point
|
check_point
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -318,11 +318,11 @@ class Shell
|
|||||||
def append(to, filter)
|
def append(to, filter)
|
||||||
case to
|
case to
|
||||||
when String
|
when String
|
||||||
AppendFile.new(@shell, to, filter)
|
AppendFile.new(@shell, to, filter)
|
||||||
when IO
|
when IO
|
||||||
AppendIO.new(@shell, to, filter)
|
AppendIO.new(@shell, to, filter)
|
||||||
else
|
else
|
||||||
Shell.Fail Error::CantApplyMethod, "append", to.class
|
Shell.Fail Error::CantApplyMethod, "append", to.class
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -337,10 +337,10 @@ class Shell
|
|||||||
# %pwd, %cwd -> @pwd
|
# %pwd, %cwd -> @pwd
|
||||||
def notify(*opts, &block)
|
def notify(*opts, &block)
|
||||||
Shell.notify(*opts) {|mes|
|
Shell.notify(*opts) {|mes|
|
||||||
yield mes if iterator?
|
yield mes if iterator?
|
||||||
|
|
||||||
mes.gsub!("%pwd", "#{@cwd}")
|
mes.gsub!("%pwd", "#{@cwd}")
|
||||||
mes.gsub!("%cwd", "#{@cwd}")
|
mes.gsub!("%cwd", "#{@cwd}")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -351,21 +351,21 @@ class Shell
|
|||||||
return command if /^\// =~ command
|
return command if /^\// =~ command
|
||||||
case path = @system_commands[command]
|
case path = @system_commands[command]
|
||||||
when String
|
when String
|
||||||
if exists?(path)
|
if exists?(path)
|
||||||
return path
|
return path
|
||||||
else
|
else
|
||||||
Shell.Fail Error::CommandNotFound, command
|
Shell.Fail Error::CommandNotFound, command
|
||||||
end
|
end
|
||||||
when false
|
when false
|
||||||
Shell.Fail Error::CommandNotFound, command
|
Shell.Fail Error::CommandNotFound, command
|
||||||
end
|
end
|
||||||
|
|
||||||
for p in @shell.system_path
|
for p in @shell.system_path
|
||||||
path = join(p, command)
|
path = join(p, command)
|
||||||
if FileTest.exist?(path)
|
if FileTest.exist?(path)
|
||||||
@system_commands[command] = path
|
@system_commands[command] = path
|
||||||
return path
|
return path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@system_commands[command] = false
|
@system_commands[command] = false
|
||||||
Shell.Fail Error::CommandNotFound, command
|
Shell.Fail Error::CommandNotFound, command
|
||||||
@ -373,21 +373,21 @@ class Shell
|
|||||||
|
|
||||||
#
|
#
|
||||||
# CommandProcessor.def_system_command(command, path)
|
# CommandProcessor.def_system_command(command, path)
|
||||||
# command: String
|
# command: String
|
||||||
# path: String
|
# path: String
|
||||||
# define 'command()' method as method.
|
# define 'command()' method as method.
|
||||||
#
|
#
|
||||||
def self.def_system_command(command, path = command)
|
def self.def_system_command(command, path = command)
|
||||||
begin
|
begin
|
||||||
eval((d = %Q[def #{command}(*opts)
|
eval((d = %Q[def #{command}(*opts)
|
||||||
SystemCommand.new(@shell, '#{path}', *opts)
|
SystemCommand.new(@shell, '#{path}', *opts)
|
||||||
end]), nil, __FILE__, __LINE__ - 1)
|
end]), nil, __FILE__, __LINE__ - 1)
|
||||||
rescue SyntaxError
|
rescue SyntaxError
|
||||||
Shell.notify "warn: Can't define #{command} path: #{path}."
|
Shell.notify "warn: Can't define #{command} path: #{path}."
|
||||||
end
|
end
|
||||||
Shell.notify "Define #{command} path: #{path}.", Shell.debug?
|
Shell.notify "Define #{command} path: #{path}.", Shell.debug?
|
||||||
Shell.notify("Definition of #{command}: ", d,
|
Shell.notify("Definition of #{command}: ", d,
|
||||||
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.undef_system_command(command)
|
def self.undef_system_command(command)
|
||||||
@ -411,28 +411,28 @@ class Shell
|
|||||||
ali = ali.id2name if ali.kind_of?(Symbol)
|
ali = ali.id2name if ali.kind_of?(Symbol)
|
||||||
command = command.id2name if command.kind_of?(Symbol)
|
command = command.id2name if command.kind_of?(Symbol)
|
||||||
begin
|
begin
|
||||||
if iterator?
|
if iterator?
|
||||||
@alias_map[ali.intern] = proc
|
@alias_map[ali.intern] = proc
|
||||||
|
|
||||||
eval((d = %Q[def #{ali}(*opts)
|
eval((d = %Q[def #{ali}(*opts)
|
||||||
@shell.__send__(:#{command},
|
@shell.__send__(:#{command},
|
||||||
*(CommandProcessor.alias_map[:#{ali}].call *opts))
|
*(CommandProcessor.alias_map[:#{ali}].call *opts))
|
||||||
end]), nil, __FILE__, __LINE__ - 1)
|
end]), nil, __FILE__, __LINE__ - 1)
|
||||||
|
|
||||||
else
|
else
|
||||||
args = opts.collect{|opt| '"' + opt + '"'}.join(",")
|
args = opts.collect{|opt| '"' + opt + '"'}.join(",")
|
||||||
eval((d = %Q[def #{ali}(*opts)
|
eval((d = %Q[def #{ali}(*opts)
|
||||||
@shell.__send__(:#{command}, #{args}, *opts)
|
@shell.__send__(:#{command}, #{args}, *opts)
|
||||||
end]), nil, __FILE__, __LINE__ - 1)
|
end]), nil, __FILE__, __LINE__ - 1)
|
||||||
end
|
end
|
||||||
rescue SyntaxError
|
rescue SyntaxError
|
||||||
Shell.notify "warn: Can't alias #{ali} command: #{command}."
|
Shell.notify "warn: Can't alias #{ali} command: #{command}."
|
||||||
Shell.notify("Definition of #{ali}: ", d)
|
Shell.notify("Definition of #{ali}: ", d)
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
|
Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
|
||||||
Shell.notify("Definition of #{ali}: ", d,
|
Shell.notify("Definition of #{ali}: ", d,
|
||||||
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -444,43 +444,43 @@ class Shell
|
|||||||
|
|
||||||
#
|
#
|
||||||
# CommandProcessor.def_builtin_commands(delegation_class, command_specs)
|
# CommandProcessor.def_builtin_commands(delegation_class, command_specs)
|
||||||
# delegation_class: Class or Module
|
# delegation_class: Class or Module
|
||||||
# command_specs: [[command_name, [argument,...]],...]
|
# command_specs: [[command_name, [argument,...]],...]
|
||||||
# command_name: String
|
# command_name: String
|
||||||
# arguments: String
|
# arguments: String
|
||||||
# FILENAME?? -> expand_path(filename??)
|
# FILENAME?? -> expand_path(filename??)
|
||||||
# *FILENAME?? -> filename??.collect{|f|expand_path(f)}.join(", ")
|
# *FILENAME?? -> filename??.collect{|f|expand_path(f)}.join(", ")
|
||||||
# define command_name(argument,...) as
|
# define command_name(argument,...) as
|
||||||
# delegation_class.command_name(argument,...)
|
# delegation_class.command_name(argument,...)
|
||||||
#
|
#
|
||||||
def self.def_builtin_commands(delegation_class, command_specs)
|
def self.def_builtin_commands(delegation_class, command_specs)
|
||||||
for meth, args in command_specs
|
for meth, args in command_specs
|
||||||
arg_str = args.collect{|arg| arg.downcase}.join(", ")
|
arg_str = args.collect{|arg| arg.downcase}.join(", ")
|
||||||
call_arg_str = args.collect{
|
call_arg_str = args.collect{
|
||||||
|arg|
|
|arg|
|
||||||
case arg
|
case arg
|
||||||
when /^(FILENAME.*)$/
|
when /^(FILENAME.*)$/
|
||||||
format("expand_path(%s)", $1.downcase)
|
format("expand_path(%s)", $1.downcase)
|
||||||
when /^(\*FILENAME.*)$/
|
when /^(\*FILENAME.*)$/
|
||||||
# \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ")
|
# \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ")
|
||||||
$1.downcase + '.collect{|fn| expand_path(fn)}'
|
$1.downcase + '.collect{|fn| expand_path(fn)}'
|
||||||
else
|
else
|
||||||
arg
|
arg
|
||||||
end
|
end
|
||||||
}.join(", ")
|
}.join(", ")
|
||||||
d = %Q[def #{meth}(#{arg_str})
|
d = %Q[def #{meth}(#{arg_str})
|
||||||
#{delegation_class}.#{meth}(#{call_arg_str})
|
#{delegation_class}.#{meth}(#{call_arg_str})
|
||||||
end]
|
end]
|
||||||
Shell.notify "Define #{meth}(#{arg_str})", Shell.debug?
|
Shell.notify "Define #{meth}(#{arg_str})", Shell.debug?
|
||||||
Shell.notify("Definition of #{meth}: ", d,
|
Shell.notify("Definition of #{meth}: ", d,
|
||||||
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
||||||
eval d
|
eval d
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# CommandProcessor.install_system_commands(pre)
|
# CommandProcessor.install_system_commands(pre)
|
||||||
# pre: String - command name prefix
|
# pre: String - command name prefix
|
||||||
# defines every command which belongs in default_system_path via
|
# defines every command which belongs in default_system_path via
|
||||||
# CommandProcessor.command(). It doesn't define already defined
|
# CommandProcessor.command(). It doesn't define already defined
|
||||||
# methods twice. By default, "pre_" is prefixes to each method
|
# methods twice. By default, "pre_" is prefixes to each method
|
||||||
@ -490,24 +490,24 @@ class Shell
|
|||||||
def self.install_system_commands(pre = "sys_")
|
def self.install_system_commands(pre = "sys_")
|
||||||
defined_meth = {}
|
defined_meth = {}
|
||||||
for m in Shell.methods
|
for m in Shell.methods
|
||||||
defined_meth[m] = true
|
defined_meth[m] = true
|
||||||
end
|
end
|
||||||
sh = Shell.new
|
sh = Shell.new
|
||||||
for path in Shell.default_system_path
|
for path in Shell.default_system_path
|
||||||
next unless sh.directory? path
|
next unless sh.directory? path
|
||||||
sh.cd path
|
sh.cd path
|
||||||
sh.foreach do
|
sh.foreach do
|
||||||
|cn|
|
|cn|
|
||||||
if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn)
|
if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn)
|
||||||
command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1')
|
command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1')
|
||||||
begin
|
begin
|
||||||
def_system_command(command, sh.expand_path(cn))
|
def_system_command(command, sh.expand_path(cn))
|
||||||
rescue
|
rescue
|
||||||
Shell.notify "warn: Can't define #{command} path: #{cn}"
|
Shell.notify "warn: Can't define #{command} path: #{cn}"
|
||||||
end
|
end
|
||||||
defined_meth[command] = command
|
defined_meth[command] = command
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -520,35 +520,35 @@ class Shell
|
|||||||
id = id.intern if id.kind_of?(String)
|
id = id.intern if id.kind_of?(String)
|
||||||
name = id.id2name
|
name = id.id2name
|
||||||
if Shell.method_defined?(id)
|
if Shell.method_defined?(id)
|
||||||
Shell.notify "warn: override definition of Shell##{name}."
|
Shell.notify "warn: override definition of Shell##{name}."
|
||||||
Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n"
|
Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n"
|
||||||
Shell.module_eval "alias #{name}_org #{name}"
|
Shell.module_eval "alias #{name}_org #{name}"
|
||||||
end
|
end
|
||||||
Shell.notify "method added: Shell##{name}.", Shell.debug?
|
Shell.notify "method added: Shell##{name}.", Shell.debug?
|
||||||
Shell.module_eval(%Q[def #{name}(*args, &block)
|
Shell.module_eval(%Q[def #{name}(*args, &block)
|
||||||
begin
|
begin
|
||||||
@command_processor.__send__(:#{name}, *args, &block)
|
@command_processor.__send__(:#{name}, *args, &block)
|
||||||
rescue Exception
|
rescue Exception
|
||||||
$@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
|
$@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
|
||||||
$@.delete_if{|s| /^\\(eval\\):/ =~ s}
|
$@.delete_if{|s| /^\\(eval\\):/ =~ s}
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
end], __FILE__, __LINE__)
|
end], __FILE__, __LINE__)
|
||||||
|
|
||||||
if Shell::Filter.method_defined?(id)
|
if Shell::Filter.method_defined?(id)
|
||||||
Shell.notify "warn: override definition of Shell::Filter##{name}."
|
Shell.notify "warn: override definition of Shell::Filter##{name}."
|
||||||
Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org."
|
Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org."
|
||||||
Filter.module_eval "alias #{name}_org #{name}"
|
Filter.module_eval "alias #{name}_org #{name}"
|
||||||
end
|
end
|
||||||
Shell.notify "method added: Shell::Filter##{name}.", Shell.debug?
|
Shell.notify "method added: Shell::Filter##{name}.", Shell.debug?
|
||||||
Filter.module_eval(%Q[def #{name}(*args, &block)
|
Filter.module_eval(%Q[def #{name}(*args, &block)
|
||||||
begin
|
begin
|
||||||
self | @shell.__send__(:#{name}, *args, &block)
|
self | @shell.__send__(:#{name}, *args, &block)
|
||||||
rescue Exception
|
rescue Exception
|
||||||
$@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
|
$@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
|
||||||
$@.delete_if{|s| /^\\(eval\\):/ =~ s}
|
$@.delete_if{|s| /^\\(eval\\):/ =~ s}
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
end], __FILE__, __LINE__)
|
end], __FILE__, __LINE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -557,35 +557,35 @@ class Shell
|
|||||||
#
|
#
|
||||||
def self.install_builtin_commands
|
def self.install_builtin_commands
|
||||||
# method related File.
|
# method related File.
|
||||||
# (exclude open/foreach/unlink)
|
# (exclude open/foreach/unlink)
|
||||||
normal_delegation_file_methods = [
|
normal_delegation_file_methods = [
|
||||||
["atime", ["FILENAME"]],
|
["atime", ["FILENAME"]],
|
||||||
["basename", ["fn", "*opts"]],
|
["basename", ["fn", "*opts"]],
|
||||||
["chmod", ["mode", "*FILENAMES"]],
|
["chmod", ["mode", "*FILENAMES"]],
|
||||||
["chown", ["owner", "group", "*FILENAME"]],
|
["chown", ["owner", "group", "*FILENAME"]],
|
||||||
["ctime", ["FILENAMES"]],
|
["ctime", ["FILENAMES"]],
|
||||||
["delete", ["*FILENAMES"]],
|
["delete", ["*FILENAMES"]],
|
||||||
["dirname", ["FILENAME"]],
|
["dirname", ["FILENAME"]],
|
||||||
["ftype", ["FILENAME"]],
|
["ftype", ["FILENAME"]],
|
||||||
["join", ["*items"]],
|
["join", ["*items"]],
|
||||||
["link", ["FILENAME_O", "FILENAME_N"]],
|
["link", ["FILENAME_O", "FILENAME_N"]],
|
||||||
["lstat", ["FILENAME"]],
|
["lstat", ["FILENAME"]],
|
||||||
["mtime", ["FILENAME"]],
|
["mtime", ["FILENAME"]],
|
||||||
["readlink", ["FILENAME"]],
|
["readlink", ["FILENAME"]],
|
||||||
["rename", ["FILENAME_FROM", "FILENAME_TO"]],
|
["rename", ["FILENAME_FROM", "FILENAME_TO"]],
|
||||||
# ["size", ["FILENAME"]],
|
# ["size", ["FILENAME"]],
|
||||||
["split", ["pathname"]],
|
["split", ["pathname"]],
|
||||||
["stat", ["FILENAME"]],
|
["stat", ["FILENAME"]],
|
||||||
["symlink", ["FILENAME_O", "FILENAME_N"]],
|
["symlink", ["FILENAME_O", "FILENAME_N"]],
|
||||||
["truncate", ["FILENAME", "length"]],
|
["truncate", ["FILENAME", "length"]],
|
||||||
["utime", ["atime", "mtime", "*FILENAMES"]]]
|
["utime", ["atime", "mtime", "*FILENAMES"]]]
|
||||||
|
|
||||||
def_builtin_commands(File, normal_delegation_file_methods)
|
def_builtin_commands(File, normal_delegation_file_methods)
|
||||||
alias_method :rm, :delete
|
alias_method :rm, :delete
|
||||||
|
|
||||||
# method related FileTest
|
# method related FileTest
|
||||||
def_builtin_commands(FileTest,
|
def_builtin_commands(FileTest,
|
||||||
FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]})
|
FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]})
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# shell/error.rb -
|
# shell/error.rb -
|
||||||
# $Release Version: 0.7 $
|
# $Release Version: 0.7 $
|
||||||
# $Revision$
|
# $Revision$
|
||||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
#
|
#
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# shell/filter.rb -
|
# shell/filter.rb -
|
||||||
# $Release Version: 0.7 $
|
# $Release Version: 0.7 $
|
||||||
# $Revision$
|
# $Revision$
|
||||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
#
|
#
|
||||||
@ -19,8 +19,8 @@ class Shell
|
|||||||
include Enumerable
|
include Enumerable
|
||||||
|
|
||||||
def initialize(sh)
|
def initialize(sh)
|
||||||
@shell = sh # parent shell
|
@shell = sh # parent shell
|
||||||
@input = nil # input filter
|
@input = nil # input filter
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :input
|
attr_reader :input
|
||||||
@ -32,52 +32,52 @@ class Shell
|
|||||||
def each(rs = nil)
|
def each(rs = nil)
|
||||||
rs = @shell.record_separator unless rs
|
rs = @shell.record_separator unless rs
|
||||||
if @input
|
if @input
|
||||||
@input.each(rs){|l| yield l}
|
@input.each(rs){|l| yield l}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def < (src)
|
def < (src)
|
||||||
case src
|
case src
|
||||||
when String
|
when String
|
||||||
cat = Cat.new(@shell, src)
|
cat = Cat.new(@shell, src)
|
||||||
cat | self
|
cat | self
|
||||||
when IO
|
when IO
|
||||||
self.input = src
|
self.input = src
|
||||||
self
|
self
|
||||||
else
|
else
|
||||||
Shell.Fail Error::CantApplyMethod, "<", to.class
|
Shell.Fail Error::CantApplyMethod, "<", to.class
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def > (to)
|
def > (to)
|
||||||
case to
|
case to
|
||||||
when String
|
when String
|
||||||
dst = @shell.open(to, "w")
|
dst = @shell.open(to, "w")
|
||||||
begin
|
begin
|
||||||
each(){|l| dst << l}
|
each(){|l| dst << l}
|
||||||
ensure
|
ensure
|
||||||
dst.close
|
dst.close
|
||||||
end
|
end
|
||||||
when IO
|
when IO
|
||||||
each(){|l| to << l}
|
each(){|l| to << l}
|
||||||
else
|
else
|
||||||
Shell.Fail Error::CantApplyMethod, ">", to.class
|
Shell.Fail Error::CantApplyMethod, ">", to.class
|
||||||
end
|
end
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def >> (to)
|
def >> (to)
|
||||||
begin
|
begin
|
||||||
Shell.cd(@shell.pwd).append(to, self)
|
Shell.cd(@shell.pwd).append(to, self)
|
||||||
rescue CantApplyMethod
|
rescue CantApplyMethod
|
||||||
Shell.Fail Error::CantApplyMethod, ">>", to.class
|
Shell.Fail Error::CantApplyMethod, ">>", to.class
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def | (filter)
|
def | (filter)
|
||||||
filter.input = self
|
filter.input = self
|
||||||
if active?
|
if active?
|
||||||
@shell.process_controller.start_job filter
|
@shell.process_controller.start_job filter
|
||||||
end
|
end
|
||||||
filter
|
filter
|
||||||
end
|
end
|
||||||
@ -100,9 +100,9 @@ class Shell
|
|||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
if @shell.debug.kind_of?(Integer) && @shell.debug > 2
|
if @shell.debug.kind_of?(Integer) && @shell.debug > 2
|
||||||
super
|
super
|
||||||
else
|
else
|
||||||
to_s
|
to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# shell/process-controller.rb -
|
# shell/process-controller.rb -
|
||||||
# $Release Version: 0.7 $
|
# $Release Version: 0.7 $
|
||||||
# $Revision$
|
# $Revision$
|
||||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
#
|
#
|
||||||
@ -27,60 +27,60 @@ class Shell
|
|||||||
extend Forwardable
|
extend Forwardable
|
||||||
|
|
||||||
def_delegator("@ProcessControllersMonitor",
|
def_delegator("@ProcessControllersMonitor",
|
||||||
"synchronize", "process_controllers_exclusive")
|
"synchronize", "process_controllers_exclusive")
|
||||||
|
|
||||||
def active_process_controllers
|
def active_process_controllers
|
||||||
process_controllers_exclusive do
|
process_controllers_exclusive do
|
||||||
@ProcessControllers.dup
|
@ProcessControllers.dup
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def activate(pc)
|
def activate(pc)
|
||||||
process_controllers_exclusive do
|
process_controllers_exclusive do
|
||||||
@ProcessControllers[pc] ||= 0
|
@ProcessControllers[pc] ||= 0
|
||||||
@ProcessControllers[pc] += 1
|
@ProcessControllers[pc] += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def inactivate(pc)
|
def inactivate(pc)
|
||||||
process_controllers_exclusive do
|
process_controllers_exclusive do
|
||||||
if @ProcessControllers[pc]
|
if @ProcessControllers[pc]
|
||||||
if (@ProcessControllers[pc] -= 1) == 0
|
if (@ProcessControllers[pc] -= 1) == 0
|
||||||
@ProcessControllers.delete(pc)
|
@ProcessControllers.delete(pc)
|
||||||
@ProcessControllersCV.signal
|
@ProcessControllersCV.signal
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def each_active_object
|
def each_active_object
|
||||||
process_controllers_exclusive do
|
process_controllers_exclusive do
|
||||||
for ref in @ProcessControllers.keys
|
for ref in @ProcessControllers.keys
|
||||||
yield ref
|
yield ref
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def block_output_synchronize(&b)
|
def block_output_synchronize(&b)
|
||||||
@BlockOutputMonitor.synchronize(&b)
|
@BlockOutputMonitor.synchronize(&b)
|
||||||
end
|
end
|
||||||
|
|
||||||
def wait_to_finish_all_process_controllers
|
def wait_to_finish_all_process_controllers
|
||||||
process_controllers_exclusive do
|
process_controllers_exclusive do
|
||||||
while !@ProcessControllers.empty?
|
while !@ProcessControllers.empty?
|
||||||
Shell::notify("Process finishing, but active shell exists",
|
Shell::notify("Process finishing, but active shell exists",
|
||||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||||
if Shell.debug?
|
if Shell.debug?
|
||||||
for pc in @ProcessControllers.keys
|
for pc in @ProcessControllers.keys
|
||||||
Shell::notify(" Not finished jobs in "+pc.shell.to_s)
|
Shell::notify(" Not finished jobs in "+pc.shell.to_s)
|
||||||
for com in pc.jobs
|
for com in pc.jobs
|
||||||
com.notify(" Jobs: %id")
|
com.notify(" Jobs: %id")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ProcessControllersCV.wait(@ProcessControllersMonitor)
|
@ProcessControllersCV.wait(@ProcessControllersMonitor)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -105,8 +105,8 @@ class Shell
|
|||||||
def jobs
|
def jobs
|
||||||
jobs = []
|
jobs = []
|
||||||
@jobs_sync.synchronize(:SH) do
|
@jobs_sync.synchronize(:SH) do
|
||||||
jobs.concat @waiting_jobs
|
jobs.concat @waiting_jobs
|
||||||
jobs.concat @active_jobs
|
jobs.concat @active_jobs
|
||||||
end
|
end
|
||||||
jobs
|
jobs
|
||||||
end
|
end
|
||||||
@ -121,115 +121,115 @@ class Shell
|
|||||||
|
|
||||||
def jobs_exist?
|
def jobs_exist?
|
||||||
@jobs_sync.synchronize(:SH) do
|
@jobs_sync.synchronize(:SH) do
|
||||||
@active_jobs.empty? or @waiting_jobs.empty?
|
@active_jobs.empty? or @waiting_jobs.empty?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def active_jobs_exist?
|
def active_jobs_exist?
|
||||||
@jobs_sync.synchronize(:SH) do
|
@jobs_sync.synchronize(:SH) do
|
||||||
@active_jobs.empty?
|
@active_jobs.empty?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def waiting_jobs_exist?
|
def waiting_jobs_exist?
|
||||||
@jobs_sync.synchronize(:SH) do
|
@jobs_sync.synchronize(:SH) do
|
||||||
@waiting_jobs.empty?
|
@waiting_jobs.empty?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# schedule a command
|
# schedule a command
|
||||||
def add_schedule(command)
|
def add_schedule(command)
|
||||||
@jobs_sync.synchronize(:EX) do
|
@jobs_sync.synchronize(:EX) do
|
||||||
ProcessController.activate(self)
|
ProcessController.activate(self)
|
||||||
if @active_jobs.empty?
|
if @active_jobs.empty?
|
||||||
start_job command
|
start_job command
|
||||||
else
|
else
|
||||||
@waiting_jobs.push(command)
|
@waiting_jobs.push(command)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# start a job
|
# start a job
|
||||||
def start_job(command = nil)
|
def start_job(command = nil)
|
||||||
@jobs_sync.synchronize(:EX) do
|
@jobs_sync.synchronize(:EX) do
|
||||||
if command
|
if command
|
||||||
return if command.active?
|
return if command.active?
|
||||||
@waiting_jobs.delete command
|
@waiting_jobs.delete command
|
||||||
else
|
else
|
||||||
command = @waiting_jobs.shift
|
command = @waiting_jobs.shift
|
||||||
# command.notify "job(%id) pre-start.", @shell.debug?
|
# command.notify "job(%id) pre-start.", @shell.debug?
|
||||||
|
|
||||||
return unless command
|
return unless command
|
||||||
end
|
end
|
||||||
@active_jobs.push command
|
@active_jobs.push command
|
||||||
command.start
|
command.start
|
||||||
# command.notify "job(%id) post-start.", @shell.debug?
|
# command.notify "job(%id) post-start.", @shell.debug?
|
||||||
|
|
||||||
# start all jobs that input from the job
|
# start all jobs that input from the job
|
||||||
for job in @waiting_jobs.dup
|
for job in @waiting_jobs.dup
|
||||||
start_job(job) if job.input == command
|
start_job(job) if job.input == command
|
||||||
end
|
end
|
||||||
# command.notify "job(%id) post2-start.", @shell.debug?
|
# command.notify "job(%id) post2-start.", @shell.debug?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def waiting_job?(job)
|
def waiting_job?(job)
|
||||||
@jobs_sync.synchronize(:SH) do
|
@jobs_sync.synchronize(:SH) do
|
||||||
@waiting_jobs.include?(job)
|
@waiting_jobs.include?(job)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def active_job?(job)
|
def active_job?(job)
|
||||||
@jobs_sync.synchronize(:SH) do
|
@jobs_sync.synchronize(:SH) do
|
||||||
@active_jobs.include?(job)
|
@active_jobs.include?(job)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# terminate a job
|
# terminate a job
|
||||||
def terminate_job(command)
|
def terminate_job(command)
|
||||||
@jobs_sync.synchronize(:EX) do
|
@jobs_sync.synchronize(:EX) do
|
||||||
@active_jobs.delete command
|
@active_jobs.delete command
|
||||||
ProcessController.inactivate(self)
|
ProcessController.inactivate(self)
|
||||||
if @active_jobs.empty?
|
if @active_jobs.empty?
|
||||||
command.notify("start_job in terminate_job(%id)", Shell::debug?)
|
command.notify("start_job in terminate_job(%id)", Shell::debug?)
|
||||||
start_job
|
start_job
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# kill a job
|
# kill a job
|
||||||
def kill_job(sig, command)
|
def kill_job(sig, command)
|
||||||
@jobs_sync.synchronize(:EX) do
|
@jobs_sync.synchronize(:EX) do
|
||||||
if @waiting_jobs.delete command
|
if @waiting_jobs.delete command
|
||||||
ProcessController.inactivate(self)
|
ProcessController.inactivate(self)
|
||||||
return
|
return
|
||||||
elsif @active_jobs.include?(command)
|
elsif @active_jobs.include?(command)
|
||||||
begin
|
begin
|
||||||
r = command.kill(sig)
|
r = command.kill(sig)
|
||||||
ProcessController.inactivate(self)
|
ProcessController.inactivate(self)
|
||||||
rescue
|
rescue
|
||||||
print "Shell: Warn: $!\n" if @shell.verbose?
|
print "Shell: Warn: $!\n" if @shell.verbose?
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@active_jobs.delete command
|
@active_jobs.delete command
|
||||||
r
|
r
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# wait for all jobs to terminate
|
# wait for all jobs to terminate
|
||||||
def wait_all_jobs_execution
|
def wait_all_jobs_execution
|
||||||
@job_monitor.synchronize do
|
@job_monitor.synchronize do
|
||||||
begin
|
begin
|
||||||
while !jobs.empty?
|
while !jobs.empty?
|
||||||
@job_condition.wait(@job_monitor)
|
@job_condition.wait(@job_monitor)
|
||||||
for job in jobs
|
for job in jobs
|
||||||
job.notify("waiting job(%id)", Shell::debug?)
|
job.notify("waiting job(%id)", Shell::debug?)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
redo unless jobs.empty?
|
redo unless jobs.empty?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -244,73 +244,73 @@ class Shell
|
|||||||
pid_cv = ConditionVariable.new
|
pid_cv = ConditionVariable.new
|
||||||
|
|
||||||
Thread.start do
|
Thread.start do
|
||||||
ProcessController.block_output_synchronize do
|
ProcessController.block_output_synchronize do
|
||||||
STDOUT.flush
|
STDOUT.flush
|
||||||
ProcessController.each_active_object do |pc|
|
ProcessController.each_active_object do |pc|
|
||||||
for jobs in pc.active_jobs
|
for jobs in pc.active_jobs
|
||||||
jobs.flush
|
jobs.flush
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pid = fork {
|
pid = fork {
|
||||||
Thread.list.each do |th|
|
Thread.list.each do |th|
|
||||||
# th.kill unless [Thread.main, Thread.current].include?(th)
|
# th.kill unless [Thread.main, Thread.current].include?(th)
|
||||||
th.kill unless Thread.current == th
|
th.kill unless Thread.current == th
|
||||||
end
|
end
|
||||||
|
|
||||||
STDIN.reopen(pipe_peer_in)
|
STDIN.reopen(pipe_peer_in)
|
||||||
STDOUT.reopen(pipe_peer_out)
|
STDOUT.reopen(pipe_peer_out)
|
||||||
|
|
||||||
ObjectSpace.each_object(IO) do |io|
|
ObjectSpace.each_object(IO) do |io|
|
||||||
if ![STDIN, STDOUT, STDERR].include?(io)
|
if ![STDIN, STDOUT, STDERR].include?(io)
|
||||||
io.close unless io.closed?
|
io.close unless io.closed?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
yield
|
yield
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
pid_cv.signal
|
pid_cv.signal
|
||||||
|
|
||||||
pipe_peer_in.close
|
pipe_peer_in.close
|
||||||
pipe_peer_out.close
|
pipe_peer_out.close
|
||||||
command.notify "job(%name:##{pid}) start", @shell.debug?
|
command.notify "job(%name:##{pid}) start", @shell.debug?
|
||||||
|
|
||||||
begin
|
begin
|
||||||
_pid = nil
|
_pid = nil
|
||||||
command.notify("job(%id) start to waiting finish.", @shell.debug?)
|
command.notify("job(%id) start to waiting finish.", @shell.debug?)
|
||||||
_pid = Process.waitpid(pid, nil)
|
_pid = Process.waitpid(pid, nil)
|
||||||
rescue Errno::ECHILD
|
rescue Errno::ECHILD
|
||||||
command.notify "warn: job(%id) was done already waitpid."
|
command.notify "warn: job(%id) was done already waitpid."
|
||||||
_pid = true
|
_pid = true
|
||||||
# rescue
|
# rescue
|
||||||
# STDERR.puts $!
|
# STDERR.puts $!
|
||||||
ensure
|
ensure
|
||||||
command.notify("Job(%id): Wait to finish when Process finished.", @shell.debug?)
|
command.notify("Job(%id): Wait to finish when Process finished.", @shell.debug?)
|
||||||
# when the process ends, wait until the command terminates
|
# when the process ends, wait until the command terminates
|
||||||
if USING_AT_EXIT_WHEN_PROCESS_EXIT or _pid
|
if USING_AT_EXIT_WHEN_PROCESS_EXIT or _pid
|
||||||
else
|
else
|
||||||
command.notify("notice: Process finishing...",
|
command.notify("notice: Process finishing...",
|
||||||
"wait for Job[%id] to finish.",
|
"wait for Job[%id] to finish.",
|
||||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||||
redo
|
redo
|
||||||
end
|
end
|
||||||
|
|
||||||
# command.notify "job(%id) pre-pre-finish.", @shell.debug?
|
# command.notify "job(%id) pre-pre-finish.", @shell.debug?
|
||||||
@job_monitor.synchronize do
|
@job_monitor.synchronize do
|
||||||
# command.notify "job(%id) pre-finish.", @shell.debug?
|
# command.notify "job(%id) pre-finish.", @shell.debug?
|
||||||
terminate_job(command)
|
terminate_job(command)
|
||||||
# command.notify "job(%id) pre-finish2.", @shell.debug?
|
# command.notify "job(%id) pre-finish2.", @shell.debug?
|
||||||
@job_condition.signal
|
@job_condition.signal
|
||||||
command.notify "job(%id) finish.", @shell.debug?
|
command.notify "job(%id) finish.", @shell.debug?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pid_mutex.synchronize do
|
pid_mutex.synchronize do
|
||||||
while !pid
|
while !pid
|
||||||
pid_cv.wait(pid_mutex)
|
pid_cv.wait(pid_mutex)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return pid, pipe_me_in, pipe_me_out
|
return pid, pipe_me_in, pipe_me_out
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# shell/system-command.rb -
|
# shell/system-command.rb -
|
||||||
# $Release Version: 0.7 $
|
# $Release Version: 0.7 $
|
||||||
# $Revision$
|
# $Revision$
|
||||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
#
|
#
|
||||||
@ -15,7 +15,7 @@ class Shell
|
|||||||
class SystemCommand < Filter
|
class SystemCommand < Filter
|
||||||
def initialize(sh, command, *opts)
|
def initialize(sh, command, *opts)
|
||||||
if t = opts.find{|opt| !opt.kind_of?(String) && opt.class}
|
if t = opts.find{|opt| !opt.kind_of?(String) && opt.class}
|
||||||
Shell.Fail Error::TypeError, t.class, "String"
|
Shell.Fail Error::TypeError, t.class, "String"
|
||||||
end
|
end
|
||||||
super(sh)
|
super(sh)
|
||||||
@command = command
|
@command = command
|
||||||
@ -41,7 +41,7 @@ class Shell
|
|||||||
def input=(inp)
|
def input=(inp)
|
||||||
super
|
super
|
||||||
if active?
|
if active?
|
||||||
start_export
|
start_export
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -49,12 +49,12 @@ class Shell
|
|||||||
notify([@command, *@opts].join(" "))
|
notify([@command, *@opts].join(" "))
|
||||||
|
|
||||||
@pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {
|
@pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {
|
||||||
Dir.chdir @shell.pwd
|
Dir.chdir @shell.pwd
|
||||||
$0 = @command
|
$0 = @command
|
||||||
exec(@command, *@opts)
|
exec(@command, *@opts)
|
||||||
}
|
}
|
||||||
if @input
|
if @input
|
||||||
start_export
|
start_export
|
||||||
end
|
end
|
||||||
start_import
|
start_import
|
||||||
end
|
end
|
||||||
@ -65,18 +65,18 @@ class Shell
|
|||||||
|
|
||||||
def terminate
|
def terminate
|
||||||
begin
|
begin
|
||||||
@pipe_in.close
|
@pipe_in.close
|
||||||
rescue IOError
|
rescue IOError
|
||||||
end
|
end
|
||||||
begin
|
begin
|
||||||
@pipe_out.close
|
@pipe_out.close
|
||||||
rescue IOError
|
rescue IOError
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def kill(sig)
|
def kill(sig)
|
||||||
if @pid
|
if @pid
|
||||||
Process.kill(sig, @pid)
|
Process.kill(sig, @pid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -85,24 +85,24 @@ class Shell
|
|||||||
rs = @shell.record_separator unless rs
|
rs = @shell.record_separator unless rs
|
||||||
_eop = true
|
_eop = true
|
||||||
Thread.start {
|
Thread.start {
|
||||||
begin
|
begin
|
||||||
while l = @pipe_in.gets
|
while l = @pipe_in.gets
|
||||||
@input_queue.push l
|
@input_queue.push l
|
||||||
end
|
end
|
||||||
_eop = false
|
_eop = false
|
||||||
rescue Errno::EPIPE
|
rescue Errno::EPIPE
|
||||||
_eop = false
|
_eop = false
|
||||||
ensure
|
ensure
|
||||||
if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
|
if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
|
||||||
notify("warn: Process finishing...",
|
notify("warn: Process finishing...",
|
||||||
"wait for Job[%id] to finish pipe importing.",
|
"wait for Job[%id] to finish pipe importing.",
|
||||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||||
redo
|
redo
|
||||||
end
|
end
|
||||||
notify "job(%id}) close imp-pipe.", @shell.debug?
|
notify "job(%id}) close imp-pipe.", @shell.debug?
|
||||||
@input_queue.push :EOF
|
@input_queue.push :EOF
|
||||||
@pipe_in.close
|
@pipe_in.close
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -110,49 +110,49 @@ class Shell
|
|||||||
notify "job(%id) start exp-pipe.", @shell.debug?
|
notify "job(%id) start exp-pipe.", @shell.debug?
|
||||||
_eop = true
|
_eop = true
|
||||||
Thread.start{
|
Thread.start{
|
||||||
begin
|
begin
|
||||||
@input.each do |l|
|
@input.each do |l|
|
||||||
ProcessController::block_output_synchronize do
|
ProcessController::block_output_synchronize do
|
||||||
@pipe_out.print l
|
@pipe_out.print l
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
_eop = false
|
_eop = false
|
||||||
rescue Errno::EPIPE, Errno::EIO
|
rescue Errno::EPIPE, Errno::EIO
|
||||||
_eop = false
|
_eop = false
|
||||||
ensure
|
ensure
|
||||||
if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
|
if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
|
||||||
notify("shell: warn: Process finishing...",
|
notify("shell: warn: Process finishing...",
|
||||||
"wait for Job(%id) to finish pipe exporting.",
|
"wait for Job(%id) to finish pipe exporting.",
|
||||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||||
redo
|
redo
|
||||||
end
|
end
|
||||||
notify "job(%id) close exp-pipe.", @shell.debug?
|
notify "job(%id) close exp-pipe.", @shell.debug?
|
||||||
@pipe_out.close
|
@pipe_out.close
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
alias super_each each
|
alias super_each each
|
||||||
def each(rs = nil)
|
def each(rs = nil)
|
||||||
while (l = @input_queue.pop) != :EOF
|
while (l = @input_queue.pop) != :EOF
|
||||||
yield l
|
yield l
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# ex)
|
# ex)
|
||||||
# if you wish to output:
|
# if you wish to output:
|
||||||
# "shell: job(#{@command}:#{@pid}) close pipe-out."
|
# "shell: job(#{@command}:#{@pid}) close pipe-out."
|
||||||
# then
|
# then
|
||||||
# mes: "job(%id) close pipe-out."
|
# mes: "job(%id) close pipe-out."
|
||||||
# yorn: Boolean(@shell.debug? or @shell.verbose?)
|
# yorn: Boolean(@shell.debug? or @shell.verbose?)
|
||||||
def notify(*opts, &block)
|
def notify(*opts, &block)
|
||||||
@shell.notify(*opts) do |mes|
|
@shell.notify(*opts) do |mes|
|
||||||
yield mes if iterator?
|
yield mes if iterator?
|
||||||
|
|
||||||
mes.gsub!("%id", "#{@command}:##{@pid}")
|
mes.gsub!("%id", "#{@command}:##{@pid}")
|
||||||
mes.gsub!("%name", "#{@command}")
|
mes.gsub!("%name", "#{@command}")
|
||||||
mes.gsub!("%pid", "#{@pid}")
|
mes.gsub!("%pid", "#{@pid}")
|
||||||
mes
|
mes
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# version.rb - shell version definition file
|
# version.rb - shell version definition file
|
||||||
# $Release Version: 0.7$
|
# $Release Version: 0.7$
|
||||||
# $Revision$
|
# $Revision$
|
||||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
#
|
#
|
||||||
|
174
lib/sync.rb
174
lib/sync.rb
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# sync.rb - 2 phase lock with counter
|
# sync.rb - 2 phase lock with counter
|
||||||
# $Release Version: 1.0$
|
# $Release Version: 1.0$
|
||||||
# $Revision$
|
# $Revision$
|
||||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||||
#
|
#
|
||||||
# --
|
# --
|
||||||
# Sync_m, Synchronizer_m
|
# Sync_m, Synchronizer_m
|
||||||
@ -10,8 +10,8 @@
|
|||||||
# obj.extend(Sync_m)
|
# obj.extend(Sync_m)
|
||||||
# or
|
# or
|
||||||
# class Foo
|
# class Foo
|
||||||
# include Sync_m
|
# include Sync_m
|
||||||
# :
|
# :
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# Sync_m#sync_mode
|
# Sync_m#sync_mode
|
||||||
@ -58,17 +58,17 @@ module Sync_m
|
|||||||
class UnknownLocker < Err
|
class UnknownLocker < Err
|
||||||
Message = "Thread(%s) not locked."
|
Message = "Thread(%s) not locked."
|
||||||
def UnknownLocker.Fail(th)
|
def UnknownLocker.Fail(th)
|
||||||
super(th.inspect)
|
super(th.inspect)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class LockModeFailer < Err
|
class LockModeFailer < Err
|
||||||
Message = "Unknown lock mode(%s)"
|
Message = "Unknown lock mode(%s)"
|
||||||
def LockModeFailer.Fail(mode)
|
def LockModeFailer.Fail(mode)
|
||||||
if mode.id2name
|
if mode.id2name
|
||||||
mode = id2name
|
mode = id2name
|
||||||
end
|
end
|
||||||
super(mode)
|
super(mode)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -100,12 +100,12 @@ module Sync_m
|
|||||||
|
|
||||||
def sync_extend
|
def sync_extend
|
||||||
unless (defined? locked? and
|
unless (defined? locked? and
|
||||||
defined? shared? and
|
defined? shared? and
|
||||||
defined? exclusive? and
|
defined? exclusive? and
|
||||||
defined? lock and
|
defined? lock and
|
||||||
defined? unlock and
|
defined? unlock and
|
||||||
defined? try_lock and
|
defined? try_lock and
|
||||||
defined? synchronize)
|
defined? synchronize)
|
||||||
Sync_m.define_aliases(singleton_class)
|
Sync_m.define_aliases(singleton_class)
|
||||||
end
|
end
|
||||||
sync_initialize
|
sync_initialize
|
||||||
@ -137,17 +137,17 @@ module Sync_m
|
|||||||
|
|
||||||
while true
|
while true
|
||||||
@sync_mutex.synchronize do
|
@sync_mutex.synchronize do
|
||||||
if sync_try_lock_sub(m)
|
if sync_try_lock_sub(m)
|
||||||
return self
|
return self
|
||||||
else
|
else
|
||||||
if sync_sh_locker[Thread.current]
|
if sync_sh_locker[Thread.current]
|
||||||
sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
|
sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
|
||||||
sync_sh_locker.delete(Thread.current)
|
sync_sh_locker.delete(Thread.current)
|
||||||
else
|
else
|
||||||
sync_waiting.push Thread.current
|
sync_waiting.push Thread.current
|
||||||
end
|
end
|
||||||
@sync_mutex.sleep
|
@sync_mutex.sleep
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self
|
self
|
||||||
@ -157,7 +157,7 @@ module Sync_m
|
|||||||
wakeup_threads = []
|
wakeup_threads = []
|
||||||
@sync_mutex.synchronize do
|
@sync_mutex.synchronize do
|
||||||
if sync_mode == UN
|
if sync_mode == UN
|
||||||
Err::UnknownLocker.Fail(Thread.current)
|
Err::UnknownLocker.Fail(Thread.current)
|
||||||
end
|
end
|
||||||
|
|
||||||
m = sync_mode if m == EX and sync_mode == SH
|
m = sync_mode if m == EX and sync_mode == SH
|
||||||
@ -165,51 +165,51 @@ module Sync_m
|
|||||||
runnable = false
|
runnable = false
|
||||||
case m
|
case m
|
||||||
when UN
|
when UN
|
||||||
Err::UnknownLocker.Fail(Thread.current)
|
Err::UnknownLocker.Fail(Thread.current)
|
||||||
|
|
||||||
when EX
|
when EX
|
||||||
if sync_ex_locker == Thread.current
|
if sync_ex_locker == Thread.current
|
||||||
if (self.sync_ex_count = sync_ex_count - 1) == 0
|
if (self.sync_ex_count = sync_ex_count - 1) == 0
|
||||||
self.sync_ex_locker = nil
|
self.sync_ex_locker = nil
|
||||||
if sync_sh_locker.include?(Thread.current)
|
if sync_sh_locker.include?(Thread.current)
|
||||||
self.sync_mode = SH
|
self.sync_mode = SH
|
||||||
else
|
else
|
||||||
self.sync_mode = UN
|
self.sync_mode = UN
|
||||||
end
|
end
|
||||||
runnable = true
|
runnable = true
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Err::UnknownLocker.Fail(Thread.current)
|
Err::UnknownLocker.Fail(Thread.current)
|
||||||
end
|
end
|
||||||
|
|
||||||
when SH
|
when SH
|
||||||
if (count = sync_sh_locker[Thread.current]).nil?
|
if (count = sync_sh_locker[Thread.current]).nil?
|
||||||
Err::UnknownLocker.Fail(Thread.current)
|
Err::UnknownLocker.Fail(Thread.current)
|
||||||
else
|
else
|
||||||
if (sync_sh_locker[Thread.current] = count - 1) == 0
|
if (sync_sh_locker[Thread.current] = count - 1) == 0
|
||||||
sync_sh_locker.delete(Thread.current)
|
sync_sh_locker.delete(Thread.current)
|
||||||
if sync_sh_locker.empty? and sync_ex_count == 0
|
if sync_sh_locker.empty? and sync_ex_count == 0
|
||||||
self.sync_mode = UN
|
self.sync_mode = UN
|
||||||
runnable = true
|
runnable = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if runnable
|
if runnable
|
||||||
if sync_upgrade_waiting.size > 0
|
if sync_upgrade_waiting.size > 0
|
||||||
th, count = sync_upgrade_waiting.shift
|
th, count = sync_upgrade_waiting.shift
|
||||||
sync_sh_locker[th] = count
|
sync_sh_locker[th] = count
|
||||||
th.wakeup
|
th.wakeup
|
||||||
wakeup_threads.push th
|
wakeup_threads.push th
|
||||||
else
|
else
|
||||||
wait = sync_waiting
|
wait = sync_waiting
|
||||||
self.sync_waiting = []
|
self.sync_waiting = []
|
||||||
for th in wait
|
for th in wait
|
||||||
th.wakeup
|
th.wakeup
|
||||||
wakeup_threads.push th
|
wakeup_threads.push th
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for th in wakeup_threads
|
for th in wakeup_threads
|
||||||
@ -263,34 +263,34 @@ module Sync_m
|
|||||||
when SH
|
when SH
|
||||||
case sync_mode
|
case sync_mode
|
||||||
when UN
|
when UN
|
||||||
self.sync_mode = m
|
self.sync_mode = m
|
||||||
sync_sh_locker[Thread.current] = 1
|
sync_sh_locker[Thread.current] = 1
|
||||||
ret = true
|
ret = true
|
||||||
when SH
|
when SH
|
||||||
count = 0 unless count = sync_sh_locker[Thread.current]
|
count = 0 unless count = sync_sh_locker[Thread.current]
|
||||||
sync_sh_locker[Thread.current] = count + 1
|
sync_sh_locker[Thread.current] = count + 1
|
||||||
ret = true
|
ret = true
|
||||||
when EX
|
when EX
|
||||||
# in EX mode, lock will upgrade to EX lock
|
# in EX mode, lock will upgrade to EX lock
|
||||||
if sync_ex_locker == Thread.current
|
if sync_ex_locker == Thread.current
|
||||||
self.sync_ex_count = sync_ex_count + 1
|
self.sync_ex_count = sync_ex_count + 1
|
||||||
ret = true
|
ret = true
|
||||||
else
|
else
|
||||||
ret = false
|
ret = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
when EX
|
when EX
|
||||||
if sync_mode == UN or
|
if sync_mode == UN or
|
||||||
sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current)
|
sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current)
|
||||||
self.sync_mode = m
|
self.sync_mode = m
|
||||||
self.sync_ex_locker = Thread.current
|
self.sync_ex_locker = Thread.current
|
||||||
self.sync_ex_count = 1
|
self.sync_ex_count = 1
|
||||||
ret = true
|
ret = true
|
||||||
elsif sync_mode == EX && sync_ex_locker == Thread.current
|
elsif sync_mode == EX && sync_ex_locker == Thread.current
|
||||||
self.sync_ex_count = sync_ex_count + 1
|
self.sync_ex_count = sync_ex_count + 1
|
||||||
ret = true
|
ret = true
|
||||||
else
|
else
|
||||||
ret = false
|
ret = false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Err::LockModeFailer.Fail mode
|
Err::LockModeFailer.Fail mode
|
||||||
|
@ -165,7 +165,7 @@ class Tempfile < DelegateClass(File)
|
|||||||
__setobj__(@tmpfile)
|
__setobj__(@tmpfile)
|
||||||
end
|
end
|
||||||
|
|
||||||
def _close # :nodoc:
|
def _close # :nodoc:
|
||||||
@tmpfile.close if @tmpfile
|
@tmpfile.close if @tmpfile
|
||||||
@tmpfile = nil
|
@tmpfile = nil
|
||||||
@data[1] = nil if @data
|
@data[1] = nil if @data
|
||||||
@ -316,13 +316,13 @@ class Tempfile < DelegateClass(File)
|
|||||||
tempfile = new(*args)
|
tempfile = new(*args)
|
||||||
|
|
||||||
if block_given?
|
if block_given?
|
||||||
begin
|
begin
|
||||||
yield(tempfile)
|
yield(tempfile)
|
||||||
ensure
|
ensure
|
||||||
tempfile.close
|
tempfile.close
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
tempfile
|
tempfile
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# thread.rb - thread support classes
|
# thread.rb - thread support classes
|
||||||
# by Yukihiro Matsumoto <matz@netlab.co.jp>
|
# by Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||||
#
|
#
|
||||||
# Copyright (C) 2001 Yukihiro Matsumoto
|
# Copyright (C) 2001 Yukihiro Matsumoto
|
||||||
# Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
|
# Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
|
||||||
@ -144,7 +144,7 @@ class Queue
|
|||||||
def initialize
|
def initialize
|
||||||
@que = []
|
@que = []
|
||||||
@waiting = []
|
@waiting = []
|
||||||
@que.taint # enable tainted comunication
|
@que.taint # enable tainted comunication
|
||||||
@waiting.taint
|
@waiting.taint
|
||||||
self.taint
|
self.taint
|
||||||
@mutex = Mutex.new
|
@mutex = Mutex.new
|
||||||
@ -252,7 +252,7 @@ class SizedQueue < Queue
|
|||||||
raise ArgumentError, "queue size must be positive" unless max > 0
|
raise ArgumentError, "queue size must be positive" unless max > 0
|
||||||
@max = max
|
@max = max
|
||||||
@queue_wait = []
|
@queue_wait = []
|
||||||
@queue_wait.taint # enable tainted comunication
|
@queue_wait.taint # enable tainted comunication
|
||||||
super()
|
super()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -278,12 +278,12 @@ class SizedQueue < Queue
|
|||||||
}
|
}
|
||||||
if diff
|
if diff
|
||||||
diff.times do
|
diff.times do
|
||||||
begin
|
begin
|
||||||
t = @queue_wait.shift
|
t = @queue_wait.shift
|
||||||
t.run if t
|
t.run if t
|
||||||
rescue ThreadError
|
rescue ThreadError
|
||||||
retry
|
retry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
max
|
max
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#
|
#
|
||||||
# thwait.rb - thread synchronization class
|
# thwait.rb - thread synchronization class
|
||||||
# $Release Version: 0.9 $
|
# $Release Version: 0.9 $
|
||||||
# $Revision: 1.3 $
|
# $Revision: 1.3 $
|
||||||
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd.)
|
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd.)
|
||||||
|
|
||||||
require "thread.rb"
|
require "thread.rb"
|
||||||
require "e2mmap.rb"
|
require "e2mmap.rb"
|
||||||
@ -39,7 +39,7 @@ class ThreadsWait
|
|||||||
tw = ThreadsWait.new(*threads)
|
tw = ThreadsWait.new(*threads)
|
||||||
if block_given?
|
if block_given?
|
||||||
tw.all_waits do |th|
|
tw.all_waits do |th|
|
||||||
yield th
|
yield th
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
tw.all_waits
|
tw.all_waits
|
||||||
@ -91,11 +91,11 @@ class ThreadsWait
|
|||||||
@threads.concat threads
|
@threads.concat threads
|
||||||
for th in threads
|
for th in threads
|
||||||
Thread.start(th) do |t|
|
Thread.start(th) do |t|
|
||||||
begin
|
begin
|
||||||
t.join
|
t.join
|
||||||
ensure
|
ensure
|
||||||
@wait_queue.push t
|
@wait_queue.push t
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -23,10 +23,10 @@ class Dir
|
|||||||
tmp = @@systmpdir
|
tmp = @@systmpdir
|
||||||
else
|
else
|
||||||
for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], @@systmpdir, '/tmp']
|
for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], @@systmpdir, '/tmp']
|
||||||
if dir and stat = File.stat(dir) and stat.directory? and stat.writable?
|
if dir and stat = File.stat(dir) and stat.directory? and stat.writable?
|
||||||
tmp = dir
|
tmp = dir
|
||||||
break
|
break
|
||||||
end rescue nil
|
end rescue nil
|
||||||
end
|
end
|
||||||
File.expand_path(tmp)
|
File.expand_path(tmp)
|
||||||
end
|
end
|
||||||
|
@ -130,9 +130,9 @@ class Tracer
|
|||||||
if block_given?
|
if block_given?
|
||||||
on
|
on
|
||||||
begin
|
begin
|
||||||
yield
|
yield
|
||||||
ensure
|
ensure
|
||||||
off
|
off
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
set_trace_func method(:trace_func).to_proc
|
set_trace_func method(:trace_func).to_proc
|
||||||
@ -160,14 +160,14 @@ class Tracer
|
|||||||
|
|
||||||
unless list = SCRIPT_LINES__[file]
|
unless list = SCRIPT_LINES__[file]
|
||||||
begin
|
begin
|
||||||
f = File::open(file)
|
f = File::open(file)
|
||||||
begin
|
begin
|
||||||
SCRIPT_LINES__[file] = list = f.readlines
|
SCRIPT_LINES__[file] = list = f.readlines
|
||||||
ensure
|
ensure
|
||||||
f.close
|
f.close
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
SCRIPT_LINES__[file] = list = []
|
SCRIPT_LINES__[file] = list = []
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -198,19 +198,19 @@ class Tracer
|
|||||||
|
|
||||||
Tracer::stdout_mutex.synchronize do
|
Tracer::stdout_mutex.synchronize do
|
||||||
if EVENT_SYMBOL[event]
|
if EVENT_SYMBOL[event]
|
||||||
stdout.printf("<%d>", $$) if Tracer::display_process_id?
|
stdout.printf("<%d>", $$) if Tracer::display_process_id?
|
||||||
stdout.printf("#%d:", get_thread_no) if Tracer::display_thread_id?
|
stdout.printf("#%d:", get_thread_no) if Tracer::display_thread_id?
|
||||||
if line == 0
|
if line == 0
|
||||||
source = "?\n"
|
source = "?\n"
|
||||||
else
|
else
|
||||||
source = get_line(file, line)
|
source = get_line(file, line)
|
||||||
end
|
end
|
||||||
printf("%s:%d:%s:%s: %s",
|
printf("%s:%d:%s:%s: %s",
|
||||||
file,
|
file,
|
||||||
line,
|
line,
|
||||||
klass || '',
|
klass || '',
|
||||||
EVENT_SYMBOL[event],
|
EVENT_SYMBOL[event],
|
||||||
source)
|
source)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
74
lib/un.rb
74
lib/un.rb
@ -69,9 +69,9 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e cp -- [OPTION] SOURCE DEST
|
# ruby -run -e cp -- [OPTION] SOURCE DEST
|
||||||
#
|
#
|
||||||
# -p preserve file attributes if possible
|
# -p preserve file attributes if possible
|
||||||
# -r copy recursively
|
# -r copy recursively
|
||||||
# -v verbose
|
# -v verbose
|
||||||
#
|
#
|
||||||
|
|
||||||
def cp
|
def cp
|
||||||
@ -90,9 +90,9 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e ln -- [OPTION] TARGET LINK_NAME
|
# ruby -run -e ln -- [OPTION] TARGET LINK_NAME
|
||||||
#
|
#
|
||||||
# -s make symbolic links instead of hard links
|
# -s make symbolic links instead of hard links
|
||||||
# -f remove existing destination files
|
# -f remove existing destination files
|
||||||
# -v verbose
|
# -v verbose
|
||||||
#
|
#
|
||||||
|
|
||||||
def ln
|
def ln
|
||||||
@ -111,7 +111,7 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e mv -- [OPTION] SOURCE DEST
|
# ruby -run -e mv -- [OPTION] SOURCE DEST
|
||||||
#
|
#
|
||||||
# -v verbose
|
# -v verbose
|
||||||
#
|
#
|
||||||
|
|
||||||
def mv
|
def mv
|
||||||
@ -127,9 +127,9 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e rm -- [OPTION] FILE
|
# ruby -run -e rm -- [OPTION] FILE
|
||||||
#
|
#
|
||||||
# -f ignore nonexistent files
|
# -f ignore nonexistent files
|
||||||
# -r remove the contents of directories recursively
|
# -r remove the contents of directories recursively
|
||||||
# -v verbose
|
# -v verbose
|
||||||
#
|
#
|
||||||
|
|
||||||
def rm
|
def rm
|
||||||
@ -146,8 +146,8 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e mkdir -- [OPTION] DIR
|
# ruby -run -e mkdir -- [OPTION] DIR
|
||||||
#
|
#
|
||||||
# -p no error if existing, make parent directories as needed
|
# -p no error if existing, make parent directories as needed
|
||||||
# -v verbose
|
# -v verbose
|
||||||
#
|
#
|
||||||
|
|
||||||
def mkdir
|
def mkdir
|
||||||
@ -163,8 +163,8 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e rmdir -- [OPTION] DIR
|
# ruby -run -e rmdir -- [OPTION] DIR
|
||||||
#
|
#
|
||||||
# -p remove DIRECTORY and its ancestors.
|
# -p remove DIRECTORY and its ancestors.
|
||||||
# -v verbose
|
# -v verbose
|
||||||
#
|
#
|
||||||
|
|
||||||
def rmdir
|
def rmdir
|
||||||
@ -179,10 +179,10 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e install -- [OPTION] SOURCE DEST
|
# ruby -run -e install -- [OPTION] SOURCE DEST
|
||||||
#
|
#
|
||||||
# -p apply access/modification times of SOURCE files to
|
# -p apply access/modification times of SOURCE files to
|
||||||
# corresponding destination files
|
# corresponding destination files
|
||||||
# -m set permission mode (as in chmod), instead of 0755
|
# -m set permission mode (as in chmod), instead of 0755
|
||||||
# -v verbose
|
# -v verbose
|
||||||
#
|
#
|
||||||
|
|
||||||
def install
|
def install
|
||||||
@ -200,7 +200,7 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e chmod -- [OPTION] OCTAL-MODE FILE
|
# ruby -run -e chmod -- [OPTION] OCTAL-MODE FILE
|
||||||
#
|
#
|
||||||
# -v verbose
|
# -v verbose
|
||||||
#
|
#
|
||||||
|
|
||||||
def chmod
|
def chmod
|
||||||
@ -215,7 +215,7 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e touch -- [OPTION] FILE
|
# ruby -run -e touch -- [OPTION] FILE
|
||||||
#
|
#
|
||||||
# -v verbose
|
# -v verbose
|
||||||
#
|
#
|
||||||
|
|
||||||
def touch
|
def touch
|
||||||
@ -229,9 +229,9 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e wait_writable -- [OPTION] FILE
|
# ruby -run -e wait_writable -- [OPTION] FILE
|
||||||
#
|
#
|
||||||
# -n RETRY count to retry
|
# -n RETRY count to retry
|
||||||
# -w SEC each wait time in seconds
|
# -w SEC each wait time in seconds
|
||||||
# -v verbose
|
# -v verbose
|
||||||
#
|
#
|
||||||
|
|
||||||
def wait_writable
|
def wait_writable
|
||||||
@ -260,15 +260,15 @@ end
|
|||||||
#
|
#
|
||||||
# ruby -run -e mkmf -- [OPTION] EXTNAME [OPTION]
|
# ruby -run -e mkmf -- [OPTION] EXTNAME [OPTION]
|
||||||
#
|
#
|
||||||
# -d ARGS run dir_config
|
# -d ARGS run dir_config
|
||||||
# -h ARGS run have_header
|
# -h ARGS run have_header
|
||||||
# -l ARGS run have_library
|
# -l ARGS run have_library
|
||||||
# -f ARGS run have_func
|
# -f ARGS run have_func
|
||||||
# -v ARGS run have_var
|
# -v ARGS run have_var
|
||||||
# -t ARGS run have_type
|
# -t ARGS run have_type
|
||||||
# -m ARGS run have_macro
|
# -m ARGS run have_macro
|
||||||
# -c ARGS run have_const
|
# -c ARGS run have_const
|
||||||
# --vendor install to vendor_ruby
|
# --vendor install to vendor_ruby
|
||||||
#
|
#
|
||||||
|
|
||||||
def mkmf
|
def mkmf
|
||||||
@ -337,11 +337,11 @@ def help
|
|||||||
all = argv.empty?
|
all = argv.empty?
|
||||||
open(__FILE__) do |me|
|
open(__FILE__) do |me|
|
||||||
while me.gets("##\n")
|
while me.gets("##\n")
|
||||||
if help = me.gets("\n\n")
|
if help = me.gets("\n\n")
|
||||||
if all or argv.delete help[/-e \w+/].sub(/-e /, "")
|
if all or argv.delete help[/-e \w+/].sub(/-e /, "")
|
||||||
print help.gsub(/^# ?/, "")
|
print help.gsub(/^# ?/, "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -120,71 +120,71 @@ module URI
|
|||||||
def split(uri)
|
def split(uri)
|
||||||
case uri
|
case uri
|
||||||
when ''
|
when ''
|
||||||
# null uri
|
# null uri
|
||||||
|
|
||||||
when @regexp[:ABS_URI]
|
when @regexp[:ABS_URI]
|
||||||
scheme, opaque, userinfo, host, port,
|
scheme, opaque, userinfo, host, port,
|
||||||
registry, path, query, fragment = $~[1..-1]
|
registry, path, query, fragment = $~[1..-1]
|
||||||
|
|
||||||
# URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
|
# URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
|
||||||
|
|
||||||
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
||||||
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
||||||
# opaque_part = uric_no_slash *uric
|
# opaque_part = uric_no_slash *uric
|
||||||
|
|
||||||
# abs_path = "/" path_segments
|
# abs_path = "/" path_segments
|
||||||
# net_path = "//" authority [ abs_path ]
|
# net_path = "//" authority [ abs_path ]
|
||||||
|
|
||||||
# authority = server | reg_name
|
# authority = server | reg_name
|
||||||
# server = [ [ userinfo "@" ] hostport ]
|
# server = [ [ userinfo "@" ] hostport ]
|
||||||
|
|
||||||
if !scheme
|
if !scheme
|
||||||
raise InvalidURIError,
|
raise InvalidURIError,
|
||||||
"bad URI(absolute but no scheme): #{uri}"
|
"bad URI(absolute but no scheme): #{uri}"
|
||||||
end
|
end
|
||||||
if !opaque && (!path && (!host && !registry))
|
if !opaque && (!path && (!host && !registry))
|
||||||
raise InvalidURIError,
|
raise InvalidURIError,
|
||||||
"bad URI(absolute but no path): #{uri}"
|
"bad URI(absolute but no path): #{uri}"
|
||||||
end
|
end
|
||||||
|
|
||||||
when @regexp[:REL_URI]
|
when @regexp[:REL_URI]
|
||||||
scheme = nil
|
scheme = nil
|
||||||
opaque = nil
|
opaque = nil
|
||||||
|
|
||||||
userinfo, host, port, registry,
|
userinfo, host, port, registry,
|
||||||
rel_segment, abs_path, query, fragment = $~[1..-1]
|
rel_segment, abs_path, query, fragment = $~[1..-1]
|
||||||
if rel_segment && abs_path
|
if rel_segment && abs_path
|
||||||
path = rel_segment + abs_path
|
path = rel_segment + abs_path
|
||||||
elsif rel_segment
|
elsif rel_segment
|
||||||
path = rel_segment
|
path = rel_segment
|
||||||
elsif abs_path
|
elsif abs_path
|
||||||
path = abs_path
|
path = abs_path
|
||||||
end
|
end
|
||||||
|
|
||||||
# URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
|
# URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
|
||||||
|
|
||||||
# relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
|
# relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
|
||||||
|
|
||||||
# net_path = "//" authority [ abs_path ]
|
# net_path = "//" authority [ abs_path ]
|
||||||
# abs_path = "/" path_segments
|
# abs_path = "/" path_segments
|
||||||
# rel_path = rel_segment [ abs_path ]
|
# rel_path = rel_segment [ abs_path ]
|
||||||
|
|
||||||
# authority = server | reg_name
|
# authority = server | reg_name
|
||||||
# server = [ [ userinfo "@" ] hostport ]
|
# server = [ [ userinfo "@" ] hostport ]
|
||||||
|
|
||||||
else
|
else
|
||||||
raise InvalidURIError, "bad URI(is not URI?): #{uri}"
|
raise InvalidURIError, "bad URI(is not URI?): #{uri}"
|
||||||
end
|
end
|
||||||
|
|
||||||
path = '' if !path && !opaque # (see RFC2396 Section 5.2)
|
path = '' if !path && !opaque # (see RFC2396 Section 5.2)
|
||||||
ret = [
|
ret = [
|
||||||
scheme,
|
scheme,
|
||||||
userinfo, host, port, # X
|
userinfo, host, port, # X
|
||||||
registry, # X
|
registry, # X
|
||||||
path, # Y
|
path, # Y
|
||||||
opaque, # Y
|
opaque, # Y
|
||||||
query,
|
query,
|
||||||
fragment
|
fragment
|
||||||
]
|
]
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
@ -202,22 +202,22 @@ module URI
|
|||||||
#
|
#
|
||||||
# == Usage
|
# == Usage
|
||||||
#
|
#
|
||||||
# p = URI::Parser.new
|
# p = URI::Parser.new
|
||||||
# p.parse("ldap://ldap.example.com/dc=example?user=john")
|
# p.parse("ldap://ldap.example.com/dc=example?user=john")
|
||||||
# #=> #<URI::LDAP:0x00000000b9e7e8 URL:ldap://ldap.example.com/dc=example?user=john>
|
# #=> #<URI::LDAP:0x00000000b9e7e8 URL:ldap://ldap.example.com/dc=example?user=john>
|
||||||
#
|
#
|
||||||
def parse(uri)
|
def parse(uri)
|
||||||
scheme, userinfo, host, port,
|
scheme, userinfo, host, port,
|
||||||
registry, path, opaque, query, fragment = self.split(uri)
|
registry, path, opaque, query, fragment = self.split(uri)
|
||||||
|
|
||||||
if scheme && URI.scheme_list.include?(scheme.upcase)
|
if scheme && URI.scheme_list.include?(scheme.upcase)
|
||||||
URI.scheme_list[scheme.upcase].new(scheme, userinfo, host, port,
|
URI.scheme_list[scheme.upcase].new(scheme, userinfo, host, port,
|
||||||
registry, path, opaque, query,
|
registry, path, opaque, query,
|
||||||
fragment, self)
|
fragment, self)
|
||||||
else
|
else
|
||||||
Generic.new(scheme, userinfo, host, port,
|
Generic.new(scheme, userinfo, host, port,
|
||||||
registry, path, opaque, query,
|
registry, path, opaque, query,
|
||||||
fragment, self)
|
fragment, self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -239,9 +239,9 @@ module URI
|
|||||||
|
|
||||||
#
|
#
|
||||||
# :call-seq:
|
# :call-seq:
|
||||||
# extract( str )
|
# extract( str )
|
||||||
# extract( str, schemes )
|
# extract( str, schemes )
|
||||||
# extract( str, schemes ) {|item| block }
|
# extract( str, schemes ) {|item| block }
|
||||||
#
|
#
|
||||||
# == Args
|
# == Args
|
||||||
#
|
#
|
||||||
@ -260,12 +260,12 @@ module URI
|
|||||||
#
|
#
|
||||||
def extract(str, schemes = nil, &block)
|
def extract(str, schemes = nil, &block)
|
||||||
if block_given?
|
if block_given?
|
||||||
str.scan(make_regexp(schemes)) { yield $& }
|
str.scan(make_regexp(schemes)) { yield $& }
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
result = []
|
result = []
|
||||||
str.scan(make_regexp(schemes)) { result.push $& }
|
str.scan(make_regexp(schemes)) { result.push $& }
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -273,16 +273,16 @@ module URI
|
|||||||
# unless +schemes+ is provided. Then it is a Regexp.union with self.pattern[:X_ABS_URI]
|
# unless +schemes+ is provided. Then it is a Regexp.union with self.pattern[:X_ABS_URI]
|
||||||
def make_regexp(schemes = nil)
|
def make_regexp(schemes = nil)
|
||||||
unless schemes
|
unless schemes
|
||||||
@regexp[:ABS_URI_REF]
|
@regexp[:ABS_URI_REF]
|
||||||
else
|
else
|
||||||
/(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/x
|
/(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# :call-seq:
|
# :call-seq:
|
||||||
# escape( str )
|
# escape( str )
|
||||||
# escape( str, unsafe )
|
# escape( str, unsafe )
|
||||||
#
|
#
|
||||||
# == Args
|
# == Args
|
||||||
#
|
#
|
||||||
@ -313,8 +313,8 @@ module URI
|
|||||||
|
|
||||||
#
|
#
|
||||||
# :call-seq:
|
# :call-seq:
|
||||||
# unescape( str )
|
# unescape( str )
|
||||||
# unescape( str, unsafe )
|
# unescape( str, unsafe )
|
||||||
#
|
#
|
||||||
# == Args
|
# == Args
|
||||||
#
|
#
|
||||||
@ -365,7 +365,7 @@ module URI
|
|||||||
# hostname = *( domainlabel "." ) toplabel [ "." ]
|
# hostname = *( domainlabel "." ) toplabel [ "." ]
|
||||||
# reg-name = *( unreserved / pct-encoded / sub-delims ) # RFC3986
|
# reg-name = *( unreserved / pct-encoded / sub-delims ) # RFC3986
|
||||||
unless hostname
|
unless hostname
|
||||||
ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-.]|%\\h\\h)+"
|
ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-.]|%\\h\\h)+"
|
||||||
end
|
end
|
||||||
|
|
||||||
# RFC 2373, APPENDIX B:
|
# RFC 2373, APPENDIX B:
|
||||||
|
@ -174,7 +174,7 @@ module URI
|
|||||||
path, opaque,
|
path, opaque,
|
||||||
query,
|
query,
|
||||||
fragment,
|
fragment,
|
||||||
parser = DEFAULT_PARSER,
|
parser = DEFAULT_PARSER,
|
||||||
arg_check = false)
|
arg_check = false)
|
||||||
@scheme = nil
|
@scheme = nil
|
||||||
@user = nil
|
@user = nil
|
||||||
@ -1321,11 +1321,13 @@ module URI
|
|||||||
self.query, self.fragment, parser)
|
self.query, self.fragment, parser)
|
||||||
|
|
||||||
if rel.userinfo != oth.userinfo ||
|
if rel.userinfo != oth.userinfo ||
|
||||||
rel.host.to_s.downcase != oth.host.to_s.downcase ||
|
rel.host.to_s.downcase != oth.host.to_s.downcase ||
|
||||||
rel.port != oth.port
|
rel.port != oth.port
|
||||||
if self.userinfo.nil? && self.host.nil?
|
|
||||||
return self, self.dup
|
if self.userinfo.nil? && self.host.nil?
|
||||||
end
|
return self, self.dup
|
||||||
|
end
|
||||||
|
|
||||||
rel.set_port(nil) if rel.port == oth.default_port
|
rel.set_port(nil) if rel.port == oth.default_port
|
||||||
return rel, rel
|
return rel, rel
|
||||||
end
|
end
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
# Usage:
|
# Usage:
|
||||||
# foo = Object.new
|
# foo = Object.new
|
||||||
# foo = Object.new
|
# foo = Object.new
|
||||||
# p foo.to_s # original's class
|
# p foo.to_s # original's class
|
||||||
# foo = WeakRef.new(foo)
|
# foo = WeakRef.new(foo)
|
||||||
# p foo.to_s # should be same class
|
# p foo.to_s # should be same class
|
||||||
# ObjectSpace.garbage_collect
|
# ObjectSpace.garbage_collect
|
||||||
# p foo.to_s # should raise exception (recycled)
|
# p foo.to_s # should raise exception (recycled)
|
||||||
|
|
||||||
require "delegate"
|
require "delegate"
|
||||||
require 'thread'
|
require 'thread'
|
||||||
@ -24,16 +24,16 @@ class WeakRef < Delegator
|
|||||||
@@mutex.synchronize {
|
@@mutex.synchronize {
|
||||||
rids = @@id_map[id]
|
rids = @@id_map[id]
|
||||||
if rids
|
if rids
|
||||||
for rid in rids
|
for rid in rids
|
||||||
@@id_rev_map.delete(rid)
|
@@id_rev_map.delete(rid)
|
||||||
end
|
end
|
||||||
@@id_map.delete(id)
|
@@id_map.delete(id)
|
||||||
end
|
end
|
||||||
rid = @@id_rev_map[id]
|
rid = @@id_rev_map[id]
|
||||||
if rid
|
if rid
|
||||||
@@id_rev_map.delete(id)
|
@@id_rev_map.delete(id)
|
||||||
@@id_map[rid].delete(id)
|
@@id_map[rid].delete(id)
|
||||||
@@id_map.delete(rid) if @@id_map[rid].empty?
|
@@id_map.delete(rid) if @@id_map[rid].empty?
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,10 +71,10 @@ end
|
|||||||
if __FILE__ == $0
|
if __FILE__ == $0
|
||||||
# require 'thread'
|
# require 'thread'
|
||||||
foo = Object.new
|
foo = Object.new
|
||||||
p foo.to_s # original's class
|
p foo.to_s # original's class
|
||||||
foo = WeakRef.new(foo)
|
foo = WeakRef.new(foo)
|
||||||
p foo.to_s # should be same class
|
p foo.to_s # should be same class
|
||||||
ObjectSpace.garbage_collect
|
ObjectSpace.garbage_collect
|
||||||
ObjectSpace.garbage_collect
|
ObjectSpace.garbage_collect
|
||||||
p foo.to_s # should raise exception (recycled)
|
p foo.to_s # should raise exception (recycled)
|
||||||
end
|
end
|
||||||
|
@ -743,7 +743,7 @@ module XMLRPC
|
|||||||
end
|
end
|
||||||
|
|
||||||
alias :on_stag :startElement
|
alias :on_stag :startElement
|
||||||
alias :on_etag :endElement
|
alias :on_etag :endElement
|
||||||
|
|
||||||
def on_stag_end(name); end
|
def on_stag_end(name); end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user