mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
67 changed files with 3823 additions and 3814 deletions
|
@ -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>
|
||||
|
||||
* lib/cgi/util.rb: Improve documentation. Patch by Clinton Nixon.
|
||||
|
|
|
@ -45,24 +45,24 @@ module Abbrev
|
|||
seen = Hash.new(0)
|
||||
|
||||
if pattern.is_a?(String)
|
||||
pattern = /^#{Regexp.quote(pattern)}/ # regard as a prefix
|
||||
pattern = /^#{Regexp.quote(pattern)}/ # regard as a prefix
|
||||
end
|
||||
|
||||
words.each do |word|
|
||||
next if (abbrev = word).empty?
|
||||
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
|
||||
when 1
|
||||
table[abbrev] = word
|
||||
when 2
|
||||
table.delete(abbrev)
|
||||
else
|
||||
break
|
||||
end
|
||||
case seen[abbrev] += 1
|
||||
when 1
|
||||
table[abbrev] = word
|
||||
when 2
|
||||
table.delete(abbrev)
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -254,9 +254,9 @@ module Benchmark
|
|||
puts 'Rehearsal '.ljust(width+CAPTION.length,'-')
|
||||
ets = job.list.inject(Tms.new) { |sum,(label,item)|
|
||||
print label.ljust(width)
|
||||
res = Benchmark.measure(&item)
|
||||
print res.format
|
||||
sum + res
|
||||
res = Benchmark.measure(&item)
|
||||
print res.format
|
||||
sum + res
|
||||
}.format("total: %tsec")
|
||||
print " #{ets}\n\n".rjust(width+CAPTION.length+2,'-')
|
||||
|
||||
|
@ -520,14 +520,14 @@ module Benchmark
|
|||
cutime.__send__(op, x.cutime),
|
||||
cstime.__send__(op, x.cstime),
|
||||
real.__send__(op, x.real)
|
||||
)
|
||||
)
|
||||
else
|
||||
Benchmark::Tms.new(utime.__send__(op, x),
|
||||
stime.__send__(op, x),
|
||||
cutime.__send__(op, x),
|
||||
cstime.__send__(op, x),
|
||||
real.__send__(op, x)
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -548,13 +548,13 @@ if __FILE__ == $0
|
|||
x.report("for:") {for _ in 1..n; _ = "1"; end} # Benchmark.measure
|
||||
x.report("times:") {n.times do ; _ = "1"; end}
|
||||
x.report("upto:") {1.upto(n) do ; _ = "1"; end}
|
||||
end
|
||||
end
|
||||
|
||||
benchmark do
|
||||
[
|
||||
measure{for _ in 1..n; _ = "1"; end}, # Benchmark.measure
|
||||
measure{n.times do ; _ = "1"; end},
|
||||
measure{1.upto(n) do ; _ = "1"; end}
|
||||
]
|
||||
benchmark do
|
||||
[
|
||||
measure{for _ in 1..n; _ = "1"; end}, # Benchmark.measure
|
||||
measure{n.times do ; _ = "1"; end},
|
||||
measure{1.upto(n) do ; _ = "1"; end}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
26
lib/cmath.rb
26
lib/cmath.rb
|
@ -55,7 +55,7 @@ module CMath
|
|||
else
|
||||
ere = exp!(z.real)
|
||||
Complex(ere * cos!(z.imag),
|
||||
ere * sin!(z.imag))
|
||||
ere * sin!(z.imag))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -71,7 +71,7 @@ module CMath
|
|||
else
|
||||
a = Complex(log!(z.abs), z.arg)
|
||||
if b
|
||||
a /= log(b)
|
||||
a /= log(b)
|
||||
end
|
||||
a
|
||||
end
|
||||
|
@ -105,18 +105,18 @@ module CMath
|
|||
def sqrt(z)
|
||||
if z.real?
|
||||
if z < 0
|
||||
Complex(0, sqrt!(-z))
|
||||
Complex(0, sqrt!(-z))
|
||||
else
|
||||
sqrt!(z)
|
||||
sqrt!(z)
|
||||
end
|
||||
else
|
||||
if z.imag < 0 ||
|
||||
(z.imag == 0 && z.imag.to_s[0] == '-')
|
||||
sqrt(z.conjugate).conjugate
|
||||
(z.imag == 0 && z.imag.to_s[0] == '-')
|
||||
sqrt(z.conjugate).conjugate
|
||||
else
|
||||
r = z.abs
|
||||
x = z.real
|
||||
Complex(sqrt!((r + x) / 2.0), sqrt!((r - x) / 2.0))
|
||||
r = z.abs
|
||||
x = z.real
|
||||
Complex(sqrt!((r + x) / 2.0), sqrt!((r - x) / 2.0))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -138,7 +138,7 @@ module CMath
|
|||
sin!(z)
|
||||
else
|
||||
Complex(sin!(z.real) * cosh!(z.imag),
|
||||
cos!(z.real) * sinh!(z.imag))
|
||||
cos!(z.real) * sinh!(z.imag))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -149,7 +149,7 @@ module CMath
|
|||
cos!(z)
|
||||
else
|
||||
Complex(cos!(z.real) * cosh!(z.imag),
|
||||
-sin!(z.real) * sinh!(z.imag))
|
||||
-sin!(z.real) * sinh!(z.imag))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -170,7 +170,7 @@ module CMath
|
|||
sinh!(z)
|
||||
else
|
||||
Complex(sinh!(z.real) * cos!(z.imag),
|
||||
cosh!(z.real) * sin!(z.imag))
|
||||
cosh!(z.real) * sin!(z.imag))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -181,7 +181,7 @@ module CMath
|
|||
cosh!(z)
|
||||
else
|
||||
Complex(cosh!(z.real) * cos!(z.imag),
|
||||
sinh!(z.real) * sin!(z.imag))
|
||||
sinh!(z.real) * sin!(z.imag))
|
||||
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:
|
||||
def Delegator.delegating_block(mid)
|
||||
lambda do |*args, &block|
|
||||
target = self.__getobj__
|
||||
begin
|
||||
target.__send__(mid, *args, &block)
|
||||
ensure
|
||||
$@.delete_if {|t| /\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:/o =~ t} if $@
|
||||
end
|
||||
target = self.__getobj__
|
||||
begin
|
||||
target.__send__(mid, *args, &block)
|
||||
ensure
|
||||
$@.delete_if {|t| /\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:/o =~ t} if $@
|
||||
end
|
||||
end
|
||||
end
|
||||
# :startdoc:
|
||||
|
@ -368,10 +368,10 @@ def DelegateClass(superclass)
|
|||
end
|
||||
end
|
||||
klass.define_singleton_method :public_instance_methods do |all=true|
|
||||
super(all) - superclass.protected_instance_methods
|
||||
super(all) - superclass.protected_instance_methods
|
||||
end
|
||||
klass.define_singleton_method :protected_instance_methods do |all=true|
|
||||
super(all) | superclass.protected_instance_methods
|
||||
super(all) | superclass.protected_instance_methods
|
||||
end
|
||||
return klass
|
||||
end
|
||||
|
@ -405,7 +405,7 @@ if __FILE__ == $0
|
|||
foo2 = SimpleDelegator.new(foo)
|
||||
p foo2
|
||||
foo2.instance_eval{print "foo\n"}
|
||||
p foo.test == foo2.test # => true
|
||||
p foo.test == foo2.test # => true
|
||||
p foo2.iter{[55,true]} # => true
|
||||
foo2.error # raise error!
|
||||
foo2.error # raise error!
|
||||
end
|
||||
|
|
|
@ -51,15 +51,15 @@ class ACL
|
|||
|
||||
def initialize(str)
|
||||
if str == '*' or str == 'all'
|
||||
@pat = [:all]
|
||||
@pat = [:all]
|
||||
elsif str.include?('*')
|
||||
@pat = [:name, dot_pat(str)]
|
||||
else
|
||||
begin
|
||||
@pat = [:ip, IPAddr.new(str)]
|
||||
rescue ArgumentError
|
||||
@pat = [:name, dot_pat(str)]
|
||||
end
|
||||
begin
|
||||
@pat = [:ip, IPAddr.new(str)]
|
||||
rescue ArgumentError
|
||||
@pat = [:name, dot_pat(str)]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,7 +70,7 @@ class ACL
|
|||
|
||||
def dot_pat_str(str)
|
||||
list = str.split('.').collect { |s|
|
||||
(s == '*') ? '.+' : s
|
||||
(s == '*') ? '.+' : s
|
||||
}
|
||||
list.join("\\.")
|
||||
end
|
||||
|
@ -93,19 +93,19 @@ class ACL
|
|||
def match(addr)
|
||||
case @pat[0]
|
||||
when :all
|
||||
true
|
||||
true
|
||||
when :ip
|
||||
begin
|
||||
ipaddr = IPAddr.new(addr[3])
|
||||
ipaddr = ipaddr.ipv4_mapped if @pat[1].ipv6? && ipaddr.ipv4?
|
||||
rescue ArgumentError
|
||||
return false
|
||||
end
|
||||
(@pat[1].include?(ipaddr)) ? true : false
|
||||
begin
|
||||
ipaddr = IPAddr.new(addr[3])
|
||||
ipaddr = ipaddr.ipv4_mapped if @pat[1].ipv6? && ipaddr.ipv4?
|
||||
rescue ArgumentError
|
||||
return false
|
||||
end
|
||||
(@pat[1].include?(ipaddr)) ? true : false
|
||||
when :name
|
||||
(@pat[1] =~ addr[2]) ? true : false
|
||||
(@pat[1] =~ addr[2]) ? true : false
|
||||
else
|
||||
false
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -130,7 +130,7 @@ class ACL
|
|||
|
||||
def match(addr)
|
||||
@list.each do |e|
|
||||
return true if e.match(addr)
|
||||
return true if e.match(addr)
|
||||
end
|
||||
false
|
||||
end
|
||||
|
@ -219,11 +219,11 @@ class ACL
|
|||
permission, domain = list.slice(i,2)
|
||||
case permission.downcase
|
||||
when 'allow'
|
||||
@allow.add(domain)
|
||||
@allow.add(domain)
|
||||
when 'deny'
|
||||
@deny.add(domain)
|
||||
@deny.add(domain)
|
||||
else
|
||||
raise "Invalid ACL entry #{list.to_s}"
|
||||
raise "Invalid ACL entry #{list.to_s}"
|
||||
end
|
||||
i += 2
|
||||
end
|
||||
|
@ -234,17 +234,17 @@ end
|
|||
if __FILE__ == $0
|
||||
# example
|
||||
list = %w(deny all
|
||||
allow 192.168.1.1
|
||||
allow 192.168.1.1
|
||||
allow ::ffff:192.168.1.2
|
||||
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
|
||||
p acl.allow_addr?(addr)
|
||||
acl = ACL.new
|
||||
p acl.allow_addr?(addr)
|
||||
|
||||
acl = ACL.new(list, ACL::DENY_ALLOW)
|
||||
p acl.allow_addr?(addr)
|
||||
acl = ACL.new(list, ACL::DENY_ALLOW)
|
||||
p acl.allow_addr?(addr)
|
||||
end
|
||||
|
||||
|
|
332
lib/drb/drb.rb
332
lib/drb/drb.rb
|
@ -466,11 +466,11 @@ module DRb
|
|||
def initialize(err, buf)
|
||||
case err.to_s
|
||||
when /uninitialized constant (\S+)/
|
||||
@name = $1
|
||||
@name = $1
|
||||
when /undefined class\/module (\S+)/
|
||||
@name = $1
|
||||
@name = $1
|
||||
else
|
||||
@name = nil
|
||||
@name = nil
|
||||
end
|
||||
@buf = buf
|
||||
end
|
||||
|
@ -486,9 +486,9 @@ module DRb
|
|||
|
||||
def self._load(s) # :nodoc:
|
||||
begin
|
||||
Marshal::load(s)
|
||||
Marshal::load(s)
|
||||
rescue NameError, ArgumentError
|
||||
DRbUnknown.new($!, s)
|
||||
DRbUnknown.new($!, s)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -514,16 +514,16 @@ module DRb
|
|||
class DRbArray
|
||||
def initialize(ary)
|
||||
@ary = ary.collect { |obj|
|
||||
if obj.kind_of? DRbUndumped
|
||||
DRbObject.new(obj)
|
||||
else
|
||||
begin
|
||||
Marshal.dump(obj)
|
||||
obj
|
||||
rescue
|
||||
DRbObject.new(obj)
|
||||
end
|
||||
end
|
||||
if obj.kind_of? DRbUndumped
|
||||
DRbObject.new(obj)
|
||||
else
|
||||
begin
|
||||
Marshal.dump(obj)
|
||||
obj
|
||||
rescue
|
||||
DRbObject.new(obj)
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -554,16 +554,16 @@ module DRb
|
|||
def dump(obj, error=false) # :nodoc:
|
||||
obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped
|
||||
begin
|
||||
str = Marshal::dump(obj)
|
||||
str = Marshal::dump(obj)
|
||||
rescue
|
||||
str = Marshal::dump(make_proxy(obj, error))
|
||||
str = Marshal::dump(make_proxy(obj, error))
|
||||
end
|
||||
[str.size].pack('N') + str
|
||||
end
|
||||
|
||||
def load(soc) # :nodoc:
|
||||
begin
|
||||
sz = soc.read(4) # sizeof (N)
|
||||
sz = soc.read(4) # sizeof (N)
|
||||
rescue
|
||||
raise(DRbConnError, $!.message, $!.backtrace)
|
||||
end
|
||||
|
@ -600,7 +600,7 @@ module DRb
|
|||
ary.push(dump(msg_id.id2name))
|
||||
ary.push(dump(arg.length))
|
||||
arg.each do |e|
|
||||
ary.push(dump(e))
|
||||
ary.push(dump(e))
|
||||
end
|
||||
ary.push(dump(b))
|
||||
stream.write(ary.join(''))
|
||||
|
@ -616,7 +616,7 @@ module DRb
|
|||
raise(DRbConnError, "too many arguments") if @argc_limit < argc
|
||||
argv = Array.new(argc, nil)
|
||||
argc.times do |n|
|
||||
argv[n] = load(stream)
|
||||
argv[n] = load(stream)
|
||||
end
|
||||
block = load(stream)
|
||||
return ro, msg, argv, block
|
||||
|
@ -727,18 +727,18 @@ module DRb
|
|||
# URI, but an error occurs in opening it, a DRbConnError is raised.
|
||||
def open(uri, config, first=true)
|
||||
@protocol.each do |prot|
|
||||
begin
|
||||
return prot.open(uri, config)
|
||||
rescue DRbBadScheme
|
||||
rescue DRbConnError
|
||||
raise($!)
|
||||
rescue
|
||||
raise(DRbConnError, "#{uri} - #{$!.inspect}")
|
||||
end
|
||||
begin
|
||||
return prot.open(uri, config)
|
||||
rescue DRbBadScheme
|
||||
rescue DRbConnError
|
||||
raise($!)
|
||||
rescue
|
||||
raise(DRbConnError, "#{uri} - #{$!.inspect}")
|
||||
end
|
||||
end
|
||||
if first && (config[:auto_load] != false)
|
||||
auto_load(uri, config)
|
||||
return open(uri, config, false)
|
||||
auto_load(uri, config)
|
||||
return open(uri, config, false)
|
||||
end
|
||||
raise DRbBadURI, 'can\'t parse uri:' + uri
|
||||
end
|
||||
|
@ -755,14 +755,14 @@ module DRb
|
|||
# error is passed on to the caller.
|
||||
def open_server(uri, config, first=true)
|
||||
@protocol.each do |prot|
|
||||
begin
|
||||
return prot.open_server(uri, config)
|
||||
rescue DRbBadScheme
|
||||
end
|
||||
begin
|
||||
return prot.open_server(uri, config)
|
||||
rescue DRbBadScheme
|
||||
end
|
||||
end
|
||||
if first && (config[:auto_load] != false)
|
||||
auto_load(uri, config)
|
||||
return open_server(uri, config, false)
|
||||
auto_load(uri, config)
|
||||
return open_server(uri, config, false)
|
||||
end
|
||||
raise DRbBadURI, 'can\'t parse uri:' + uri
|
||||
end
|
||||
|
@ -776,15 +776,15 @@ module DRb
|
|||
# URI, then a DRbBadURI error is raised.
|
||||
def uri_option(uri, config, first=true)
|
||||
@protocol.each do |prot|
|
||||
begin
|
||||
uri, opt = prot.uri_option(uri, config)
|
||||
# opt = nil if opt == ''
|
||||
return uri, opt
|
||||
rescue DRbBadScheme
|
||||
end
|
||||
begin
|
||||
uri, opt = prot.uri_option(uri, config)
|
||||
# opt = nil if opt == ''
|
||||
return uri, opt
|
||||
rescue DRbBadScheme
|
||||
end
|
||||
end
|
||||
if first && (config[:auto_load] != false)
|
||||
auto_load(uri, config)
|
||||
auto_load(uri, config)
|
||||
return uri_option(uri, config, false)
|
||||
end
|
||||
raise DRbBadURI, 'can\'t parse uri:' + uri
|
||||
|
@ -793,7 +793,7 @@ module DRb
|
|||
|
||||
def auto_load(uri, config) # :nodoc:
|
||||
if uri =~ /^drb([a-z0-9]+):/
|
||||
require("drb/#{$1}") rescue nil
|
||||
require("drb/#{$1}") rescue nil
|
||||
end
|
||||
end
|
||||
module_function :auto_load
|
||||
|
@ -806,13 +806,13 @@ module DRb
|
|||
private
|
||||
def self.parse_uri(uri)
|
||||
if uri =~ /^druby:\/\/(.*?):(\d+)(\?(.*))?$/
|
||||
host = $1
|
||||
port = $2.to_i
|
||||
option = $4
|
||||
[host, port, option]
|
||||
host = $1
|
||||
port = $2.to_i
|
||||
option = $4
|
||||
[host, port, option]
|
||||
else
|
||||
raise(DRbBadScheme, uri) unless uri =~ /^druby:/
|
||||
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
||||
raise(DRbBadScheme, uri) unless uri =~ /^druby:/
|
||||
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -858,7 +858,7 @@ module DRb
|
|||
host = getservername
|
||||
soc = open_server_inaddr_any(host, port)
|
||||
else
|
||||
soc = TCPServer.open(host, port)
|
||||
soc = TCPServer.open(host, port)
|
||||
end
|
||||
port = soc.addr[1] if port == 0
|
||||
config[:tcp_port] = port
|
||||
|
@ -928,8 +928,8 @@ module DRb
|
|||
# client-server session.
|
||||
def close
|
||||
if @socket
|
||||
@socket.close
|
||||
@socket = nil
|
||||
@socket.close
|
||||
@socket = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -938,9 +938,9 @@ module DRb
|
|||
# the server's side of this client-server session.
|
||||
def accept
|
||||
while true
|
||||
s = @socket.accept
|
||||
break if (@acl ? @acl.allow_socket?(s) : true)
|
||||
s.close
|
||||
s = @socket.accept
|
||||
break if (@acl ? @acl.allow_socket?(s) : true)
|
||||
s.close
|
||||
end
|
||||
if @config[:tcp_original_host].to_s.size == 0
|
||||
uri = "druby://#{s.addr[3]}:#{@config[:tcp_port]}"
|
||||
|
@ -954,8 +954,8 @@ module DRb
|
|||
def alive?
|
||||
return false unless @socket
|
||||
if IO.select([@socket], nil, nil, 0)
|
||||
close
|
||||
return false
|
||||
close
|
||||
return false
|
||||
end
|
||||
true
|
||||
end
|
||||
|
@ -1004,7 +1004,7 @@ module DRb
|
|||
uri, ref = Marshal.load(s)
|
||||
|
||||
if DRb.here?(uri)
|
||||
obj = DRb.to_obj(ref)
|
||||
obj = DRb.to_obj(ref)
|
||||
if ((! obj.tainted?) && Thread.current[:drb_untaint])
|
||||
Thread.current[:drb_untaint].push(obj)
|
||||
end
|
||||
|
@ -1042,12 +1042,12 @@ module DRb
|
|||
@uri = nil
|
||||
@ref = nil
|
||||
if obj.nil?
|
||||
return if uri.nil?
|
||||
@uri, option = DRbProtocol.uri_option(uri, DRb.config)
|
||||
@ref = DRbURIOption.new(option) unless option.nil?
|
||||
return if uri.nil?
|
||||
@uri, option = DRbProtocol.uri_option(uri, DRb.config)
|
||||
@ref = DRbURIOption.new(option) unless option.nil?
|
||||
else
|
||||
@uri = uri ? uri : (DRb.uri rescue nil)
|
||||
@ref = obj ? DRb.to_id(obj) : nil
|
||||
@uri = uri ? uri : (DRb.uri rescue nil)
|
||||
@ref = obj ? DRb.to_id(obj) : nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1078,9 +1078,9 @@ module DRb
|
|||
# Routes method calls to the referenced object.
|
||||
def method_missing(msg_id, *a, &b)
|
||||
if DRb.here?(@uri)
|
||||
obj = DRb.to_obj(@ref)
|
||||
DRb.current_server.check_insecure_method(obj, msg_id)
|
||||
return obj.__send__(msg_id, *a, &b)
|
||||
obj = DRb.to_obj(@ref)
|
||||
DRb.current_server.check_insecure_method(obj, msg_id)
|
||||
return obj.__send__(msg_id, *a, &b)
|
||||
end
|
||||
|
||||
succ, result = self.class.with_friend(@uri) do
|
||||
|
@ -1095,7 +1095,7 @@ module DRb
|
|||
raise result
|
||||
else
|
||||
bt = self.class.prepare_backtrace(@uri, result)
|
||||
result.set_backtrace(bt + caller)
|
||||
result.set_backtrace(bt + caller)
|
||||
raise result
|
||||
end
|
||||
end
|
||||
|
@ -1117,7 +1117,7 @@ module DRb
|
|||
result.backtrace.each do |x|
|
||||
break if /`__send__'$/ =~ x
|
||||
if /^\(druby:\/\// =~ x
|
||||
bt.push(x)
|
||||
bt.push(x)
|
||||
else
|
||||
bt.push(prefix + x)
|
||||
end
|
||||
|
@ -1153,36 +1153,36 @@ module DRb
|
|||
|
||||
def self.open(remote_uri) # :nodoc:
|
||||
begin
|
||||
conn = nil
|
||||
conn = nil
|
||||
|
||||
@mutex.synchronize do
|
||||
#FIXME
|
||||
new_pool = []
|
||||
@pool.each do |c|
|
||||
if conn.nil? and c.uri == remote_uri
|
||||
conn = c if c.alive?
|
||||
else
|
||||
new_pool.push c
|
||||
end
|
||||
end
|
||||
@pool = new_pool
|
||||
end
|
||||
@mutex.synchronize do
|
||||
#FIXME
|
||||
new_pool = []
|
||||
@pool.each do |c|
|
||||
if conn.nil? and c.uri == remote_uri
|
||||
conn = c if c.alive?
|
||||
else
|
||||
new_pool.push c
|
||||
end
|
||||
end
|
||||
@pool = new_pool
|
||||
end
|
||||
|
||||
conn = self.new(remote_uri) unless conn
|
||||
succ, result = yield(conn)
|
||||
return succ, result
|
||||
conn = self.new(remote_uri) unless conn
|
||||
succ, result = yield(conn)
|
||||
return succ, result
|
||||
|
||||
ensure
|
||||
if conn
|
||||
if succ
|
||||
@mutex.synchronize do
|
||||
@pool.unshift(conn)
|
||||
@pool.pop.close while @pool.size > POOL_SIZE
|
||||
end
|
||||
else
|
||||
conn.close
|
||||
end
|
||||
end
|
||||
if conn
|
||||
if succ
|
||||
@mutex.synchronize do
|
||||
@pool.unshift(conn)
|
||||
@pool.pop.close while @pool.size > POOL_SIZE
|
||||
end
|
||||
else
|
||||
conn.close
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1274,11 +1274,11 @@ module DRb
|
|||
|
||||
def self.make_config(hash={}) # :nodoc:
|
||||
default_config = {
|
||||
:idconv => @@idconv,
|
||||
:verbose => @@verbose,
|
||||
:tcp_acl => @@acl,
|
||||
:load_limit => @@load_limit,
|
||||
:argc_limit => @@argc_limit,
|
||||
:idconv => @@idconv,
|
||||
:verbose => @@verbose,
|
||||
:tcp_acl => @@acl,
|
||||
:load_limit => @@load_limit,
|
||||
:argc_limit => @@argc_limit,
|
||||
:safe_level => @@safe_level
|
||||
}
|
||||
default_config.update(hash)
|
||||
|
@ -1329,12 +1329,12 @@ module DRb
|
|||
# The server will immediately start running in its own thread.
|
||||
def initialize(uri=nil, front=nil, config_or_acl=nil)
|
||||
if Hash === config_or_acl
|
||||
config = config_or_acl.dup
|
||||
config = config_or_acl.dup
|
||||
else
|
||||
acl = config_or_acl || @@acl
|
||||
config = {
|
||||
:tcp_acl => acl
|
||||
}
|
||||
acl = config_or_acl || @@acl
|
||||
config = {
|
||||
:tcp_acl => acl
|
||||
}
|
||||
end
|
||||
|
||||
@config = self.class.make_config(config)
|
||||
|
@ -1414,28 +1414,28 @@ module DRb
|
|||
private
|
||||
def kill_sub_thread
|
||||
Thread.new do
|
||||
grp = ThreadGroup.new
|
||||
grp.add(Thread.current)
|
||||
list = @grp.list
|
||||
while list.size > 0
|
||||
list.each do |th|
|
||||
th.kill if th.alive?
|
||||
end
|
||||
list = @grp.list
|
||||
end
|
||||
grp = ThreadGroup.new
|
||||
grp.add(Thread.current)
|
||||
list = @grp.list
|
||||
while list.size > 0
|
||||
list.each do |th|
|
||||
th.kill if th.alive?
|
||||
end
|
||||
list = @grp.list
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run
|
||||
Thread.start do
|
||||
begin
|
||||
while true
|
||||
main_loop
|
||||
end
|
||||
ensure
|
||||
@protocol.close if @protocol
|
||||
kill_sub_thread
|
||||
end
|
||||
begin
|
||||
while true
|
||||
main_loop
|
||||
end
|
||||
ensure
|
||||
@protocol.close if @protocol
|
||||
kill_sub_thread
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1473,10 +1473,10 @@ module DRb
|
|||
raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(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}"
|
||||
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}"
|
||||
else
|
||||
true
|
||||
|
@ -1486,15 +1486,15 @@ module DRb
|
|||
|
||||
class InvokeMethod # :nodoc:
|
||||
def initialize(drb_server, client)
|
||||
@drb_server = drb_server
|
||||
@drb_server = drb_server
|
||||
@safe_level = drb_server.safe_level
|
||||
@client = client
|
||||
@client = client
|
||||
end
|
||||
|
||||
def perform
|
||||
@result = nil
|
||||
@succ = false
|
||||
setup_message
|
||||
@result = nil
|
||||
@succ = false
|
||||
setup_message
|
||||
|
||||
if $SAFE < @safe_level
|
||||
info = Thread.current['DRb']
|
||||
|
@ -1518,19 +1518,19 @@ module DRb
|
|||
@result = perform_without_block
|
||||
end
|
||||
end
|
||||
@succ = true
|
||||
if @msg_id == :to_ary && @result.class == Array
|
||||
@result = DRbArray.new(@result)
|
||||
end
|
||||
return @succ, @result
|
||||
@succ = true
|
||||
if @msg_id == :to_ary && @result.class == Array
|
||||
@result = DRbArray.new(@result)
|
||||
end
|
||||
return @succ, @result
|
||||
rescue StandardError, ScriptError, Interrupt
|
||||
@result = $!
|
||||
return @succ, @result
|
||||
@result = $!
|
||||
return @succ, @result
|
||||
end
|
||||
|
||||
private
|
||||
def init_with_client
|
||||
obj, msg, argv, block = @client.recv_request
|
||||
obj, msg, argv, block = @client.recv_request
|
||||
@obj = obj
|
||||
@msg_id = msg.intern
|
||||
@argv = argv
|
||||
|
@ -1542,21 +1542,21 @@ module DRb
|
|||
end
|
||||
|
||||
def setup_message
|
||||
init_with_client
|
||||
check_insecure_method
|
||||
init_with_client
|
||||
check_insecure_method
|
||||
end
|
||||
|
||||
def perform_without_block
|
||||
if Proc === @obj && @msg_id == :__drb_yield
|
||||
if Proc === @obj && @msg_id == :__drb_yield
|
||||
if @argv.size == 1
|
||||
ary = @argv
|
||||
else
|
||||
ary = [@argv]
|
||||
end
|
||||
ary.collect(&@obj)[0]
|
||||
else
|
||||
@obj.__send__(@msg_id, *@argv)
|
||||
end
|
||||
ary = @argv
|
||||
else
|
||||
ary = [@argv]
|
||||
end
|
||||
ary.collect(&@obj)[0]
|
||||
else
|
||||
@obj.__send__(@msg_id, *@argv)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1582,29 +1582,29 @@ module DRb
|
|||
# or a local method call fails.
|
||||
def main_loop
|
||||
Thread.start(@protocol.accept) do |client|
|
||||
@grp.add Thread.current
|
||||
Thread.current['DRb'] = { 'client' => client ,
|
||||
'server' => self }
|
||||
loop do
|
||||
begin
|
||||
succ = false
|
||||
invoke_method = InvokeMethod.new(self, client)
|
||||
succ, result = invoke_method.perform
|
||||
if !succ && verbose
|
||||
p result
|
||||
result.backtrace.each do |x|
|
||||
puts x
|
||||
end
|
||||
end
|
||||
client.send_reply(succ, result) rescue nil
|
||||
ensure
|
||||
@grp.add Thread.current
|
||||
Thread.current['DRb'] = { 'client' => client ,
|
||||
'server' => self }
|
||||
loop do
|
||||
begin
|
||||
succ = false
|
||||
invoke_method = InvokeMethod.new(self, client)
|
||||
succ, result = invoke_method.perform
|
||||
if !succ && verbose
|
||||
p result
|
||||
result.backtrace.each do |x|
|
||||
puts x
|
||||
end
|
||||
end
|
||||
client.send_reply(succ, result) rescue nil
|
||||
ensure
|
||||
client.close unless succ
|
||||
if Thread.current['DRb']['stop_service']
|
||||
Thread.new { stop_service }
|
||||
end
|
||||
break unless succ
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
=begin
|
||||
external service
|
||||
Copyright (c) 2000,2002 Masatoshi SEKI
|
||||
Copyright (c) 2000,2002 Masatoshi SEKI
|
||||
=end
|
||||
|
||||
require 'drb/drb'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
=begin
|
||||
external service manager
|
||||
Copyright (c) 2000 Masatoshi SEKI
|
||||
Copyright (c) 2000 Masatoshi SEKI
|
||||
=end
|
||||
|
||||
require 'drb/drb'
|
||||
|
@ -54,17 +54,17 @@ module DRb
|
|||
|
||||
def unregist(name)
|
||||
synchronize do
|
||||
@servers.delete(name)
|
||||
@servers.delete(name)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def invoke_thread
|
||||
Thread.new do
|
||||
while true
|
||||
name = @queue.pop
|
||||
invoke_service_command(name, @@command[name])
|
||||
end
|
||||
while true
|
||||
name = @queue.pop
|
||||
invoke_service_command(name, @@command[name])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -75,8 +75,8 @@ module DRb
|
|||
def invoke_service_command(name, command)
|
||||
raise "invalid command. name: #{name}" unless command
|
||||
synchronize do
|
||||
return if @servers.include?(name)
|
||||
@servers[name] = false
|
||||
return if @servers.include?(name)
|
||||
@servers[name] = false
|
||||
end
|
||||
uri = @uri || DRb.uri
|
||||
Process.detach spawn("#{command} #{uri} #{name}")
|
||||
|
|
|
@ -4,9 +4,9 @@ module DRb
|
|||
class DRbServer
|
||||
module InvokeMethod18Mixin
|
||||
def block_yield(x)
|
||||
if x.size == 1 && x[0].class == Array
|
||||
x[0] = DRbArray.new(x[0])
|
||||
end
|
||||
if x.size == 1 && x[0].class == Array
|
||||
x[0] = DRbArray.new(x[0])
|
||||
end
|
||||
@block.call(*x)
|
||||
end
|
||||
|
||||
|
|
160
lib/drb/ssl.rb
160
lib/drb/ssl.rb
|
@ -10,43 +10,43 @@ module DRb
|
|||
class SSLConfig
|
||||
|
||||
DEFAULT = {
|
||||
:SSLCertificate => nil,
|
||||
:SSLPrivateKey => nil,
|
||||
:SSLClientCA => nil,
|
||||
:SSLCACertificatePath => nil,
|
||||
:SSLCACertificateFile => nil,
|
||||
:SSLVerifyMode => ::OpenSSL::SSL::VERIFY_NONE,
|
||||
:SSLVerifyDepth => nil,
|
||||
:SSLVerifyCallback => nil, # custom verification
|
||||
:SSLCertificate => nil,
|
||||
:SSLPrivateKey => nil,
|
||||
:SSLClientCA => nil,
|
||||
:SSLCACertificatePath => nil,
|
||||
:SSLCACertificateFile => nil,
|
||||
:SSLVerifyMode => ::OpenSSL::SSL::VERIFY_NONE,
|
||||
:SSLVerifyDepth => nil,
|
||||
:SSLVerifyCallback => nil, # custom verification
|
||||
:SSLCertificateStore => nil,
|
||||
# Must specify if you use auto generated certificate.
|
||||
:SSLCertName => nil, # e.g. [["CN","fqdn.example.com"]]
|
||||
:SSLCertComment => "Generated by Ruby/OpenSSL"
|
||||
# Must specify if you use auto generated certificate.
|
||||
:SSLCertName => nil, # e.g. [["CN","fqdn.example.com"]]
|
||||
:SSLCertComment => "Generated by Ruby/OpenSSL"
|
||||
}
|
||||
|
||||
def initialize(config)
|
||||
@config = config
|
||||
@config = config
|
||||
@cert = config[:SSLCertificate]
|
||||
@pkey = config[:SSLPrivateKey]
|
||||
@ssl_ctx = nil
|
||||
end
|
||||
|
||||
def [](key);
|
||||
@config[key] || DEFAULT[key]
|
||||
@config[key] || DEFAULT[key]
|
||||
end
|
||||
|
||||
def connect(tcp)
|
||||
ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
|
||||
ssl.sync = true
|
||||
ssl.connect
|
||||
ssl
|
||||
ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
|
||||
ssl.sync = true
|
||||
ssl.connect
|
||||
ssl
|
||||
end
|
||||
|
||||
def accept(tcp)
|
||||
ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
|
||||
ssl.sync = true
|
||||
ssl.accept
|
||||
ssl
|
||||
ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
|
||||
ssl.sync = true
|
||||
ssl.accept
|
||||
ssl
|
||||
end
|
||||
|
||||
def setup_certificate
|
||||
|
@ -54,56 +54,56 @@ module DRb
|
|||
return
|
||||
end
|
||||
|
||||
rsa = OpenSSL::PKey::RSA.new(512){|p, n|
|
||||
next unless self[:verbose]
|
||||
case p
|
||||
when 0; $stderr.putc "." # BN_generate_prime
|
||||
when 1; $stderr.putc "+" # BN_generate_prime
|
||||
when 2; $stderr.putc "*" # searching good prime,
|
||||
# n = #of try,
|
||||
# but also data from BN_generate_prime
|
||||
when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
|
||||
# but also data from BN_generate_prime
|
||||
else; $stderr.putc "*" # BN_generate_prime
|
||||
end
|
||||
}
|
||||
rsa = OpenSSL::PKey::RSA.new(512){|p, n|
|
||||
next unless self[:verbose]
|
||||
case p
|
||||
when 0; $stderr.putc "." # BN_generate_prime
|
||||
when 1; $stderr.putc "+" # BN_generate_prime
|
||||
when 2; $stderr.putc "*" # searching good prime,
|
||||
# n = #of try,
|
||||
# but also data from BN_generate_prime
|
||||
when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
|
||||
# but also data from BN_generate_prime
|
||||
else; $stderr.putc "*" # BN_generate_prime
|
||||
end
|
||||
}
|
||||
|
||||
cert = OpenSSL::X509::Certificate.new
|
||||
cert.version = 3
|
||||
cert.serial = 0
|
||||
name = OpenSSL::X509::Name.new(self[:SSLCertName])
|
||||
cert.subject = name
|
||||
cert.issuer = name
|
||||
cert.not_before = Time.now
|
||||
cert.not_after = Time.now + (365*24*60*60)
|
||||
cert.public_key = rsa.public_key
|
||||
cert = OpenSSL::X509::Certificate.new
|
||||
cert.version = 3
|
||||
cert.serial = 0
|
||||
name = OpenSSL::X509::Name.new(self[:SSLCertName])
|
||||
cert.subject = name
|
||||
cert.issuer = name
|
||||
cert.not_before = Time.now
|
||||
cert.not_after = Time.now + (365*24*60*60)
|
||||
cert.public_key = rsa.public_key
|
||||
|
||||
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
|
||||
cert.extensions = [
|
||||
ef.create_extension("basicConstraints","CA:FALSE"),
|
||||
ef.create_extension("subjectKeyIdentifier", "hash") ]
|
||||
ef.issuer_certificate = cert
|
||||
cert.add_extension(ef.create_extension("authorityKeyIdentifier",
|
||||
"keyid:always,issuer:always"))
|
||||
if comment = self[:SSLCertComment]
|
||||
cert.add_extension(ef.create_extension("nsComment", comment))
|
||||
end
|
||||
cert.sign(rsa, OpenSSL::Digest::SHA1.new)
|
||||
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
|
||||
cert.extensions = [
|
||||
ef.create_extension("basicConstraints","CA:FALSE"),
|
||||
ef.create_extension("subjectKeyIdentifier", "hash") ]
|
||||
ef.issuer_certificate = cert
|
||||
cert.add_extension(ef.create_extension("authorityKeyIdentifier",
|
||||
"keyid:always,issuer:always"))
|
||||
if comment = self[:SSLCertComment]
|
||||
cert.add_extension(ef.create_extension("nsComment", comment))
|
||||
end
|
||||
cert.sign(rsa, OpenSSL::Digest::SHA1.new)
|
||||
|
||||
@cert = cert
|
||||
@pkey = rsa
|
||||
@cert = cert
|
||||
@pkey = rsa
|
||||
end
|
||||
|
||||
def setup_ssl_context
|
||||
ctx = ::OpenSSL::SSL::SSLContext.new
|
||||
ctx.cert = @cert
|
||||
ctx.key = @pkey
|
||||
ctx.client_ca = self[:SSLClientCA]
|
||||
ctx.ca_path = self[:SSLCACertificatePath]
|
||||
ctx.ca_file = self[:SSLCACertificateFile]
|
||||
ctx.verify_mode = self[:SSLVerifyMode]
|
||||
ctx.verify_depth = self[:SSLVerifyDepth]
|
||||
ctx.verify_callback = self[:SSLVerifyCallback]
|
||||
ctx.client_ca = self[:SSLClientCA]
|
||||
ctx.ca_path = self[:SSLCACertificatePath]
|
||||
ctx.ca_file = self[:SSLCACertificateFile]
|
||||
ctx.verify_mode = self[:SSLVerifyMode]
|
||||
ctx.verify_depth = self[:SSLVerifyDepth]
|
||||
ctx.verify_callback = self[:SSLVerifyCallback]
|
||||
ctx.cert_store = self[:SSLCertificateStore]
|
||||
@ssl_ctx = ctx
|
||||
end
|
||||
|
@ -111,13 +111,13 @@ module DRb
|
|||
|
||||
def self.parse_uri(uri)
|
||||
if uri =~ /^drbssl:\/\/(.*?):(\d+)(\?(.*))?$/
|
||||
host = $1
|
||||
port = $2.to_i
|
||||
option = $4
|
||||
[host, port, option]
|
||||
host = $1
|
||||
port = $2.to_i
|
||||
option = $4
|
||||
[host, port, option]
|
||||
else
|
||||
raise(DRbBadScheme, uri) unless uri =~ /^drbssl:/
|
||||
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
||||
raise(DRbBadScheme, uri) unless uri =~ /^drbssl:/
|
||||
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -139,7 +139,7 @@ module DRb
|
|||
host = getservername
|
||||
soc = open_server_inaddr_any(host, port)
|
||||
else
|
||||
soc = TCPServer.open(host, port)
|
||||
soc = TCPServer.open(host, port)
|
||||
end
|
||||
port = soc.addr[1] if port == 0
|
||||
@uri = "drbssl://#{host}:#{port}"
|
||||
|
@ -164,24 +164,24 @@ module DRb
|
|||
|
||||
def close
|
||||
if @ssl
|
||||
@ssl.close
|
||||
@ssl = nil
|
||||
@ssl.close
|
||||
@ssl = nil
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def accept
|
||||
begin
|
||||
while true
|
||||
soc = @socket.accept
|
||||
break if (@acl ? @acl.allow_socket?(soc) : true)
|
||||
soc.close
|
||||
end
|
||||
ssl = @config.accept(soc)
|
||||
self.class.new(uri, ssl, @config, true)
|
||||
while true
|
||||
soc = @socket.accept
|
||||
break if (@acl ? @acl.allow_socket?(soc) : true)
|
||||
soc.close
|
||||
end
|
||||
ssl = @config.accept(soc)
|
||||
self.class.new(uri, ssl, @config, true)
|
||||
rescue OpenSSL::SSL::SSLError
|
||||
warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose]
|
||||
retry
|
||||
warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose]
|
||||
retry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,65 +9,65 @@ module DRb
|
|||
class InvalidIndexError < RuntimeError; end
|
||||
|
||||
def initialize(timeout=600)
|
||||
super()
|
||||
@sentinel = Object.new
|
||||
@gc = {}
|
||||
@curr = {}
|
||||
@renew = {}
|
||||
@timeout = timeout
|
||||
@keeper = keeper
|
||||
super()
|
||||
@sentinel = Object.new
|
||||
@gc = {}
|
||||
@curr = {}
|
||||
@renew = {}
|
||||
@timeout = timeout
|
||||
@keeper = keeper
|
||||
end
|
||||
|
||||
def add(obj)
|
||||
synchronize do
|
||||
key = obj.__id__
|
||||
@curr[key] = obj
|
||||
return key
|
||||
end
|
||||
synchronize do
|
||||
key = obj.__id__
|
||||
@curr[key] = obj
|
||||
return key
|
||||
end
|
||||
end
|
||||
|
||||
def fetch(key, dv=@sentinel)
|
||||
synchronize do
|
||||
obj = peek(key)
|
||||
if obj == @sentinel
|
||||
return dv unless dv == @sentinel
|
||||
raise InvalidIndexError
|
||||
end
|
||||
@renew[key] = obj # KeepIt
|
||||
return obj
|
||||
end
|
||||
synchronize do
|
||||
obj = peek(key)
|
||||
if obj == @sentinel
|
||||
return dv unless dv == @sentinel
|
||||
raise InvalidIndexError
|
||||
end
|
||||
@renew[key] = obj # KeepIt
|
||||
return obj
|
||||
end
|
||||
end
|
||||
|
||||
def include?(key)
|
||||
synchronize do
|
||||
obj = peek(key)
|
||||
return false if obj == @sentinel
|
||||
true
|
||||
end
|
||||
synchronize do
|
||||
obj = peek(key)
|
||||
return false if obj == @sentinel
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def peek(key)
|
||||
synchronize do
|
||||
return @curr.fetch(key, @renew.fetch(key, @gc.fetch(key, @sentinel)))
|
||||
end
|
||||
synchronize do
|
||||
return @curr.fetch(key, @renew.fetch(key, @gc.fetch(key, @sentinel)))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def alternate
|
||||
synchronize do
|
||||
@gc = @curr # GCed
|
||||
@curr = @renew
|
||||
@renew = {}
|
||||
end
|
||||
synchronize do
|
||||
@gc = @curr # GCed
|
||||
@curr = @renew
|
||||
@renew = {}
|
||||
end
|
||||
end
|
||||
|
||||
def keeper
|
||||
Thread.new do
|
||||
loop do
|
||||
alternate
|
||||
sleep(@timeout)
|
||||
end
|
||||
end
|
||||
Thread.new do
|
||||
loop do
|
||||
alternate
|
||||
sleep(@timeout)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,12 +9,12 @@ module DRb
|
|||
class DRbUNIXSocket < DRbTCPSocket
|
||||
def self.parse_uri(uri)
|
||||
if /^drbunix:(.*?)(\?(.*))?$/ =~ uri
|
||||
filename = $1
|
||||
option = $3
|
||||
[filename, option]
|
||||
filename = $1
|
||||
option = $3
|
||||
[filename, option]
|
||||
else
|
||||
raise(DRbBadScheme, uri) unless uri =~ /^drbunix:/
|
||||
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
||||
raise(DRbBadScheme, uri) unless uri =~ /^drbunix:/
|
||||
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -28,11 +28,11 @@ module DRb
|
|||
def self.open_server(uri, config)
|
||||
filename, = parse_uri(uri)
|
||||
if filename.size == 0
|
||||
soc = temp_server
|
||||
soc = temp_server
|
||||
filename = soc.path
|
||||
uri = 'drbunix:' + soc.path
|
||||
uri = 'drbunix:' + soc.path
|
||||
else
|
||||
soc = UNIXServer.open(filename)
|
||||
soc = UNIXServer.open(filename)
|
||||
end
|
||||
owner = config[:UNIXFileOwner]
|
||||
group = config[:UNIXFileGroup]
|
||||
|
@ -67,18 +67,18 @@ module DRb
|
|||
tmpdir = Dir::tmpdir
|
||||
n = 0
|
||||
while true
|
||||
begin
|
||||
tmpname = sprintf('%s/druby%d.%d', tmpdir, $$, n)
|
||||
lock = tmpname + '.lock'
|
||||
unless File.exist?(tmpname) or File.exist?(lock)
|
||||
Dir.mkdir(lock)
|
||||
break
|
||||
end
|
||||
rescue
|
||||
raise "cannot generate tempfile `%s'" % tmpname if n >= Max_try
|
||||
#sleep(1)
|
||||
end
|
||||
n += 1
|
||||
begin
|
||||
tmpname = sprintf('%s/druby%d.%d', tmpdir, $$, n)
|
||||
lock = tmpname + '.lock'
|
||||
unless File.exist?(tmpname) or File.exist?(lock)
|
||||
Dir.mkdir(lock)
|
||||
break
|
||||
end
|
||||
rescue
|
||||
raise "cannot generate tempfile `%s'" % tmpname if n >= Max_try
|
||||
#sleep(1)
|
||||
end
|
||||
n += 1
|
||||
end
|
||||
soc = UNIXServer.new(tmpname)
|
||||
Dir.rmdir(lock)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# e2mmap.rb - for ruby 1.1
|
||||
# $Release Version: 2.0$
|
||||
# $Revision: 1.10 $
|
||||
# by Keiju ISHITSUKA
|
||||
# $Release Version: 2.0$
|
||||
# $Revision: 1.10 $
|
||||
# by Keiju ISHITSUKA
|
||||
#
|
||||
# --
|
||||
# Usage:
|
||||
|
@ -60,19 +60,19 @@ module Exception2MessageMapper
|
|||
def bind(cl)
|
||||
self.module_eval %[
|
||||
def Raise(err = nil, *rest)
|
||||
Exception2MessageMapper.Raise(self.class, err, *rest)
|
||||
Exception2MessageMapper.Raise(self.class, err, *rest)
|
||||
end
|
||||
alias Fail Raise
|
||||
|
||||
def self.included(mod)
|
||||
mod.extend Exception2MessageMapper
|
||||
mod.extend Exception2MessageMapper
|
||||
end
|
||||
]
|
||||
end
|
||||
|
||||
# Fail(err, *rest)
|
||||
# err: exception
|
||||
# rest: message arguments
|
||||
# err: exception
|
||||
# rest: message arguments
|
||||
#
|
||||
def Raise(err = nil, *rest)
|
||||
E2MM.Raise(self, err, *rest)
|
||||
|
@ -81,19 +81,19 @@ module Exception2MessageMapper
|
|||
alias fail Raise
|
||||
|
||||
# def_e2message(c, m)
|
||||
# c: exception
|
||||
# m: message_form
|
||||
# define exception c with message m.
|
||||
# c: exception
|
||||
# m: message_form
|
||||
# define exception c with message m.
|
||||
#
|
||||
def def_e2message(c, m)
|
||||
E2MM.def_e2message(self, c, m)
|
||||
end
|
||||
|
||||
# def_exception(n, m, s)
|
||||
# n: exception_name
|
||||
# m: message_form
|
||||
# s: superclass(default: StandardError)
|
||||
# define exception named ``c'' with message m.
|
||||
# n: exception_name
|
||||
# m: message_form
|
||||
# s: superclass(default: StandardError)
|
||||
# define exception named ``c'' with message m.
|
||||
#
|
||||
def def_exception(n, m, s = StandardError)
|
||||
E2MM.def_exception(self, n, m, s)
|
||||
|
@ -106,10 +106,10 @@ module Exception2MessageMapper
|
|||
@MessageMap = {}
|
||||
|
||||
# E2MM.def_e2message(k, e, m)
|
||||
# k: class to define exception under.
|
||||
# e: exception
|
||||
# m: message_form
|
||||
# define exception c with message m.
|
||||
# k: class to define exception under.
|
||||
# e: exception
|
||||
# m: message_form
|
||||
# define exception c with message m.
|
||||
#
|
||||
def E2MM.def_e2message(k, c, m)
|
||||
E2MM.instance_eval{@MessageMap[[k, c]] = m}
|
||||
|
@ -117,11 +117,11 @@ module Exception2MessageMapper
|
|||
end
|
||||
|
||||
# E2MM.def_exception(k, n, m, s)
|
||||
# k: class to define exception under.
|
||||
# n: exception_name
|
||||
# m: message_form
|
||||
# s: superclass(default: StandardError)
|
||||
# define exception named ``c'' with message m.
|
||||
# k: class to define exception under.
|
||||
# n: exception_name
|
||||
# m: message_form
|
||||
# s: superclass(default: StandardError)
|
||||
# define exception named ``c'' with message m.
|
||||
#
|
||||
def E2MM.def_exception(k, n, m, s = StandardError)
|
||||
n = n.id2name if n.kind_of?(Fixnum)
|
||||
|
@ -131,9 +131,9 @@ module Exception2MessageMapper
|
|||
end
|
||||
|
||||
# Fail(klass, err, *rest)
|
||||
# klass: class to define exception under.
|
||||
# err: exception
|
||||
# rest: message arguments
|
||||
# klass: class to define exception under.
|
||||
# err: exception
|
||||
# rest: message arguments
|
||||
#
|
||||
def E2MM.Raise(klass = E2MM, err = nil, *rest)
|
||||
if form = e2mm_message(klass, err)
|
||||
|
@ -141,7 +141,7 @@ module Exception2MessageMapper
|
|||
#p $@
|
||||
#p __FILE__
|
||||
b.shift if b[0] =~ /^#{Regexp.quote(__FILE__)}:/
|
||||
raise err, sprintf(form, *rest), b
|
||||
raise err, sprintf(form, *rest), b
|
||||
else
|
||||
E2MM.Fail E2MM, ErrNotRegisteredException, err.inspect
|
||||
end
|
||||
|
@ -153,9 +153,9 @@ module Exception2MessageMapper
|
|||
def E2MM.e2mm_message(klass, exp)
|
||||
for c in klass.ancestors
|
||||
if mes = @MessageMap[[c,exp]]
|
||||
#p mes
|
||||
m = klass.instance_eval('"' + mes + '"')
|
||||
return m
|
||||
#p mes
|
||||
m = klass.instance_eval('"' + mes + '"')
|
||||
return m
|
||||
end
|
||||
end
|
||||
nil
|
||||
|
@ -165,8 +165,8 @@ module Exception2MessageMapper
|
|||
end
|
||||
|
||||
E2MM.def_exception(E2MM,
|
||||
:ErrNotRegisteredException,
|
||||
"not registerd exception(%s)")
|
||||
:ErrNotRegisteredException,
|
||||
"not registerd exception(%s)")
|
||||
end
|
||||
|
||||
|
||||
|
|
282
lib/erb.rb
282
lib/erb.rb
|
@ -254,7 +254,7 @@
|
|||
# Rails, the web application framework, uses ERB to create views.
|
||||
#
|
||||
class ERB
|
||||
Revision = '$Date:: $' #'
|
||||
Revision = '$Date:: $' #'
|
||||
|
||||
# Returns revision information for the erb.rb module.
|
||||
def self.version
|
||||
|
@ -351,21 +351,21 @@ class ERB
|
|||
class Scanner # :nodoc:
|
||||
@scanner_map = {}
|
||||
def self.regist_scanner(klass, trim_mode, percent)
|
||||
@scanner_map[[trim_mode, percent]] = klass
|
||||
@scanner_map[[trim_mode, percent]] = klass
|
||||
end
|
||||
|
||||
def self.default_scanner=(klass)
|
||||
@default_scanner = klass
|
||||
@default_scanner = klass
|
||||
end
|
||||
|
||||
def self.make_scanner(src, trim_mode, percent)
|
||||
klass = @scanner_map.fetch([trim_mode, percent], @default_scanner)
|
||||
klass.new(src, trim_mode, percent)
|
||||
klass = @scanner_map.fetch([trim_mode, percent], @default_scanner)
|
||||
klass.new(src, trim_mode, percent)
|
||||
end
|
||||
|
||||
def initialize(src, trim_mode, percent)
|
||||
@src = src
|
||||
@stag = nil
|
||||
@src = src
|
||||
@stag = nil
|
||||
end
|
||||
attr_accessor :stag
|
||||
|
||||
|
@ -374,44 +374,44 @@ class ERB
|
|||
|
||||
class TrimScanner < Scanner # :nodoc:
|
||||
def initialize(src, trim_mode, percent)
|
||||
super
|
||||
@trim_mode = trim_mode
|
||||
@percent = percent
|
||||
if @trim_mode == '>'
|
||||
@scan_line = self.method(:trim_line1)
|
||||
elsif @trim_mode == '<>'
|
||||
@scan_line = self.method(:trim_line2)
|
||||
elsif @trim_mode == '-'
|
||||
@scan_line = self.method(:explicit_trim_line)
|
||||
else
|
||||
@scan_line = self.method(:scan_line)
|
||||
end
|
||||
super
|
||||
@trim_mode = trim_mode
|
||||
@percent = percent
|
||||
if @trim_mode == '>'
|
||||
@scan_line = self.method(:trim_line1)
|
||||
elsif @trim_mode == '<>'
|
||||
@scan_line = self.method(:trim_line2)
|
||||
elsif @trim_mode == '-'
|
||||
@scan_line = self.method(:explicit_trim_line)
|
||||
else
|
||||
@scan_line = self.method(:scan_line)
|
||||
end
|
||||
end
|
||||
attr_accessor :stag
|
||||
|
||||
def scan(&block)
|
||||
@stag = nil
|
||||
if @percent
|
||||
@src.each_line do |line|
|
||||
percent_line(line, &block)
|
||||
end
|
||||
else
|
||||
@stag = nil
|
||||
if @percent
|
||||
@src.each_line do |line|
|
||||
percent_line(line, &block)
|
||||
end
|
||||
else
|
||||
@scan_line.call(@src, &block)
|
||||
end
|
||||
nil
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def percent_line(line, &block)
|
||||
if @stag || line[0] != ?%
|
||||
return @scan_line.call(line, &block)
|
||||
end
|
||||
if @stag || line[0] != ?%
|
||||
return @scan_line.call(line, &block)
|
||||
end
|
||||
|
||||
line[0] = ''
|
||||
if line[0] == ?%
|
||||
@scan_line.call(line, &block)
|
||||
else
|
||||
line[0] = ''
|
||||
if line[0] == ?%
|
||||
@scan_line.call(line, &block)
|
||||
else
|
||||
yield(PercentLine.new(line.chomp))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def scan_line(line)
|
||||
|
@ -420,7 +420,7 @@ class ERB
|
|||
next if token.empty?
|
||||
yield(token)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def trim_line1(line)
|
||||
|
@ -434,11 +434,11 @@ class ERB
|
|||
yield(token)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def trim_line2(line)
|
||||
head = nil
|
||||
head = nil
|
||||
line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
|
||||
tokens.each do |token|
|
||||
next if token.empty?
|
||||
|
@ -456,7 +456,7 @@ class ERB
|
|||
head = nil if token == "\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def explicit_trim_line(line)
|
||||
|
@ -479,7 +479,7 @@ class ERB
|
|||
|
||||
ERB_STAG = %w(<%= <%# <%)
|
||||
def is_erb_stag?(s)
|
||||
ERB_STAG.member?(s)
|
||||
ERB_STAG.member?(s)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -492,7 +492,7 @@ class ERB
|
|||
next if token.empty?
|
||||
yield(token)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -515,23 +515,23 @@ class ERB
|
|||
Scanner.regist_scanner(SimpleScanner2, nil, false)
|
||||
|
||||
class ExplicitScanner < Scanner # :nodoc:
|
||||
def scan
|
||||
def scan
|
||||
stag_reg = /(.*?)(^[ \t]*<%-|<%%|<%=|<%#|<%-|<%|\z)/m
|
||||
etag_reg = /(.*?)(%%>|-%>|%>|\z)/m
|
||||
scanner = StringScanner.new(@src)
|
||||
while ! scanner.eos?
|
||||
scanner.scan(@stag ? etag_reg : stag_reg)
|
||||
scanner.scan(@stag ? etag_reg : stag_reg)
|
||||
yield(scanner[1])
|
||||
|
||||
elem = scanner[2]
|
||||
if /[ \t]*<%-/ =~ elem
|
||||
yield('<%')
|
||||
elsif elem == '-%>'
|
||||
yield('%>')
|
||||
yield(:cr) if scanner.scan(/(\n|\z)/)
|
||||
else
|
||||
yield(elem)
|
||||
end
|
||||
yield('%>')
|
||||
yield(:cr) if scanner.scan(/(\n|\z)/)
|
||||
else
|
||||
yield(elem)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -542,32 +542,32 @@ class ERB
|
|||
|
||||
class Buffer # :nodoc:
|
||||
def initialize(compiler, enc=nil)
|
||||
@compiler = compiler
|
||||
@line = []
|
||||
@compiler = compiler
|
||||
@line = []
|
||||
@script = enc ? "#coding:#{enc.to_s}\n" : ""
|
||||
@compiler.pre_cmd.each do |x|
|
||||
push(x)
|
||||
end
|
||||
@compiler.pre_cmd.each do |x|
|
||||
push(x)
|
||||
end
|
||||
end
|
||||
attr_reader :script
|
||||
|
||||
def push(cmd)
|
||||
@line << cmd
|
||||
@line << cmd
|
||||
end
|
||||
|
||||
def cr
|
||||
@script << (@line.join('; '))
|
||||
@line = []
|
||||
@script << "\n"
|
||||
@script << (@line.join('; '))
|
||||
@line = []
|
||||
@script << "\n"
|
||||
end
|
||||
|
||||
def close
|
||||
return unless @line
|
||||
@compiler.post_cmd.each do |x|
|
||||
push(x)
|
||||
end
|
||||
@script << (@line.join('; '))
|
||||
@line = nil
|
||||
return unless @line
|
||||
@compiler.post_cmd.each do |x|
|
||||
push(x)
|
||||
end
|
||||
@script << (@line.join('; '))
|
||||
@line = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -594,53 +594,53 @@ class ERB
|
|||
scanner.scan do |token|
|
||||
next if token.nil?
|
||||
next if token == ''
|
||||
if scanner.stag.nil?
|
||||
case token
|
||||
if scanner.stag.nil?
|
||||
case token
|
||||
when PercentLine
|
||||
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
||||
content = ''
|
||||
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
||||
content = ''
|
||||
out.push(token.to_s)
|
||||
out.cr
|
||||
when :cr
|
||||
out.cr
|
||||
when '<%', '<%=', '<%#'
|
||||
scanner.stag = token
|
||||
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
||||
content = ''
|
||||
when "\n"
|
||||
content << "\n"
|
||||
out.push("#{@put_cmd} #{content_dump(content)}")
|
||||
content = ''
|
||||
when '<%%'
|
||||
content << '<%'
|
||||
else
|
||||
content << token
|
||||
end
|
||||
else
|
||||
case token
|
||||
when '%>'
|
||||
case scanner.stag
|
||||
when '<%'
|
||||
if content[-1] == ?\n
|
||||
content.chop!
|
||||
out.push(content)
|
||||
out.cr
|
||||
else
|
||||
out.push(content)
|
||||
end
|
||||
when '<%='
|
||||
out.push("#{@insert_cmd}((#{content}).to_s)")
|
||||
when '<%#'
|
||||
# out.push("# #{content_dump(content)}")
|
||||
end
|
||||
scanner.stag = nil
|
||||
content = ''
|
||||
when '%%>'
|
||||
content << '%>'
|
||||
else
|
||||
content << token
|
||||
end
|
||||
end
|
||||
when :cr
|
||||
out.cr
|
||||
when '<%', '<%=', '<%#'
|
||||
scanner.stag = token
|
||||
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
||||
content = ''
|
||||
when "\n"
|
||||
content << "\n"
|
||||
out.push("#{@put_cmd} #{content_dump(content)}")
|
||||
content = ''
|
||||
when '<%%'
|
||||
content << '<%'
|
||||
else
|
||||
content << token
|
||||
end
|
||||
else
|
||||
case token
|
||||
when '%>'
|
||||
case scanner.stag
|
||||
when '<%'
|
||||
if content[-1] == ?\n
|
||||
content.chop!
|
||||
out.push(content)
|
||||
out.cr
|
||||
else
|
||||
out.push(content)
|
||||
end
|
||||
when '<%='
|
||||
out.push("#{@insert_cmd}((#{content}).to_s)")
|
||||
when '<%#'
|
||||
# out.push("# #{content_dump(content)}")
|
||||
end
|
||||
scanner.stag = nil
|
||||
content = ''
|
||||
when '%%>'
|
||||
content << '%>'
|
||||
else
|
||||
content << token
|
||||
end
|
||||
end
|
||||
end
|
||||
out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
|
||||
out.close
|
||||
|
@ -650,24 +650,24 @@ class ERB
|
|||
def prepare_trim_mode(mode) # :nodoc:
|
||||
case mode
|
||||
when 1
|
||||
return [false, '>']
|
||||
return [false, '>']
|
||||
when 2
|
||||
return [false, '<>']
|
||||
return [false, '<>']
|
||||
when 0
|
||||
return [false, nil]
|
||||
return [false, nil]
|
||||
when String
|
||||
perc = mode.include?('%')
|
||||
if mode.include?('-')
|
||||
return [perc, '-']
|
||||
elsif mode.include?('<>')
|
||||
return [perc, '<>']
|
||||
elsif mode.include?('>')
|
||||
return [perc, '>']
|
||||
else
|
||||
[perc, nil]
|
||||
end
|
||||
perc = mode.include?('%')
|
||||
if mode.include?('-')
|
||||
return [perc, '-']
|
||||
elsif mode.include?('<>')
|
||||
return [perc, '<>']
|
||||
elsif mode.include?('>')
|
||||
return [perc, '>']
|
||||
else
|
||||
[perc, nil]
|
||||
end
|
||||
else
|
||||
return [false, nil]
|
||||
return [false, nil]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -701,12 +701,12 @@ class ERB
|
|||
private
|
||||
def detect_magic_comment(s)
|
||||
if /\A<%#(.*)%>/ =~ s or (@percent and /\A%#(.*)/ =~ s)
|
||||
comment = $1
|
||||
comment = $1 if comment[/-\*-\s*(.*?)\s*-*-$/]
|
||||
if %r"coding\s*[=:]\s*([[:alnum:]\-_]+)" =~ comment
|
||||
enc = $1.sub(/-(?:mac|dos|unix)/i, '')
|
||||
enc = Encoding.find(enc)
|
||||
end
|
||||
comment = $1
|
||||
comment = $1 if comment[/-\*-\s*(.*?)\s*-*-$/]
|
||||
if %r"coding\s*[=:]\s*([[:alnum:]\-_]+)" =~ comment
|
||||
enc = $1.sub(/-(?:mac|dos|unix)/i, '')
|
||||
enc = Encoding.find(enc)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -726,9 +726,9 @@ class ERB
|
|||
# If _trim_mode_ is passed a String containing one or more of the following
|
||||
# modifiers, ERB will adjust its code generation as listed:
|
||||
#
|
||||
# % enables Ruby code processing for lines beginning with %
|
||||
# <> omit newline for lines starting with <% and ending in %>
|
||||
# > omit newline for lines ending in %>
|
||||
# % enables Ruby code processing for lines beginning with %
|
||||
# <> omit newline for lines starting with <% and ending in %>
|
||||
# > omit newline for lines ending in %>
|
||||
#
|
||||
# _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
|
||||
|
@ -831,8 +831,8 @@ class ERB
|
|||
def result(b=TOPLEVEL_BINDING)
|
||||
if @safe_level
|
||||
proc {
|
||||
$SAFE = @safe_level
|
||||
eval(@src, b, (@filename || '(erb)'), 0)
|
||||
$SAFE = @safe_level
|
||||
eval(@src, b, (@filename || '(erb)'), 0)
|
||||
}.call
|
||||
else
|
||||
eval(@src, b, (@filename || '(erb)'), 0)
|
||||
|
@ -899,14 +899,14 @@ class ERB
|
|||
#
|
||||
# A utility method for escaping HTML tag characters in _s_.
|
||||
#
|
||||
# require "erb"
|
||||
# include ERB::Util
|
||||
# require "erb"
|
||||
# include ERB::Util
|
||||
#
|
||||
# puts html_escape("is a > 0 & a < 10?")
|
||||
# puts html_escape("is a > 0 & a < 10?")
|
||||
#
|
||||
# _Generates_
|
||||
#
|
||||
# is a > 0 & a < 10?
|
||||
# is a > 0 & a < 10?
|
||||
#
|
||||
def html_escape(s)
|
||||
s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/</, "<")
|
||||
|
@ -918,14 +918,14 @@ class ERB
|
|||
#
|
||||
# A utility method for encoding the String _s_ as a URL.
|
||||
#
|
||||
# require "erb"
|
||||
# include ERB::Util
|
||||
# require "erb"
|
||||
# include ERB::Util
|
||||
#
|
||||
# puts url_encode("Programming Ruby: The Pragmatic Programmer's Guide")
|
||||
# puts url_encode("Programming Ruby: The Pragmatic Programmer's Guide")
|
||||
#
|
||||
# _Generates_
|
||||
#
|
||||
# Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
|
||||
# Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
|
||||
#
|
||||
def url_encode(s)
|
||||
s.to_s.dup.force_encoding("ASCII-8BIT").gsub(/[^a-zA-Z0-9_\-.]/n) {
|
||||
|
@ -971,7 +971,7 @@ class ERB
|
|||
#
|
||||
module DefMethod
|
||||
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)
|
||||
if erb_or_fname.kind_of? String
|
||||
fname = erb_or_fname
|
||||
|
|
|
@ -38,7 +38,7 @@ module Find
|
|||
paths.collect!{|d| raise Errno::ENOENT unless File.exist?(d); d.dup}
|
||||
while file = paths.shift
|
||||
catch(:prune) do
|
||||
yield file.dup.taint
|
||||
yield file.dup.taint
|
||||
begin
|
||||
s = File.lstat(file)
|
||||
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#
|
||||
# forwardable.rb -
|
||||
# $Release Version: 1.1$
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||
# original definition by delegator.rb
|
||||
# $Release Version: 1.1$
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||
# original definition by delegator.rb
|
||||
# Revised by Daniel J. Berger with suggestions from Florian Gross.
|
||||
#
|
||||
# Documentation by James Edward Gray II and Gavin Sinclair
|
||||
|
@ -84,7 +84,7 @@
|
|||
# def_delegator :Implementation, :service
|
||||
#
|
||||
# class Implementation
|
||||
# def service...
|
||||
# def service...
|
||||
# end
|
||||
# end
|
||||
#
|
||||
|
@ -178,12 +178,12 @@ module Forwardable
|
|||
def def_instance_delegator(accessor, method, ali = method)
|
||||
line_no = __LINE__; str = %{
|
||||
def #{ali}(*args, &block)
|
||||
begin
|
||||
#{accessor}.__send__(:#{method}, *args, &block)
|
||||
rescue Exception
|
||||
$@.delete_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug
|
||||
::Kernel::raise
|
||||
end
|
||||
begin
|
||||
#{accessor}.__send__(:#{method}, *args, &block)
|
||||
rescue Exception
|
||||
$@.delete_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug
|
||||
::Kernel::raise
|
||||
end
|
||||
end
|
||||
}
|
||||
# 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)
|
||||
str = %{
|
||||
def #{ali}(*args, &block)
|
||||
begin
|
||||
#{accessor}.__send__(:#{method}, *args, &block)
|
||||
rescue Exception
|
||||
$@.delete_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug
|
||||
::Kernel::raise
|
||||
end
|
||||
begin
|
||||
#{accessor}.__send__(:#{method}, *args, &block)
|
||||
rescue Exception
|
||||
$@.delete_if{|s| %r"#{Regexp.quote(__FILE__)}"o =~ s} unless Forwardable::debug
|
||||
::Kernel::raise
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ class GetoptLong
|
|||
if @status != STATUS_YET
|
||||
set_error(ArgumentError, "argument error")
|
||||
raise RuntimeError,
|
||||
"invoke ordering=, but option processing has already started"
|
||||
"invoke ordering=, but option processing has already started"
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -273,7 +273,7 @@ class GetoptLong
|
|||
#
|
||||
if @status != STATUS_YET
|
||||
raise RuntimeError,
|
||||
"invoke set_options, but option processing has already started"
|
||||
"invoke set_options, but option processing has already started"
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -284,7 +284,7 @@ class GetoptLong
|
|||
|
||||
arguments.each do |arg|
|
||||
if !arg.is_a?(Array)
|
||||
raise ArgumentError, "the option list contains non-Array argument"
|
||||
raise ArgumentError, "the option list contains non-Array argument"
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -292,44 +292,44 @@ class GetoptLong
|
|||
#
|
||||
argument_flag = nil
|
||||
arg.each do |i|
|
||||
if ARGUMENT_FLAGS.include?(i)
|
||||
if argument_flag != nil
|
||||
raise ArgumentError, "too many argument-flags"
|
||||
end
|
||||
argument_flag = i
|
||||
end
|
||||
if ARGUMENT_FLAGS.include?(i)
|
||||
if argument_flag != nil
|
||||
raise ArgumentError, "too many argument-flags"
|
||||
end
|
||||
argument_flag = i
|
||||
end
|
||||
end
|
||||
|
||||
raise ArgumentError, "no argument-flag" if argument_flag == nil
|
||||
|
||||
canonical_name = nil
|
||||
arg.each do |i|
|
||||
#
|
||||
# Check an option name.
|
||||
#
|
||||
next if i == argument_flag
|
||||
begin
|
||||
if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/
|
||||
raise ArgumentError, "an invalid option `#{i}'"
|
||||
end
|
||||
if (@canonical_names.include?(i))
|
||||
raise ArgumentError, "option redefined `#{i}'"
|
||||
end
|
||||
rescue
|
||||
@canonical_names.clear
|
||||
@argument_flags.clear
|
||||
raise
|
||||
end
|
||||
#
|
||||
# Check an option name.
|
||||
#
|
||||
next if i == argument_flag
|
||||
begin
|
||||
if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/
|
||||
raise ArgumentError, "an invalid option `#{i}'"
|
||||
end
|
||||
if (@canonical_names.include?(i))
|
||||
raise ArgumentError, "option redefined `#{i}'"
|
||||
end
|
||||
rescue
|
||||
@canonical_names.clear
|
||||
@argument_flags.clear
|
||||
raise
|
||||
end
|
||||
|
||||
#
|
||||
# Register the option (`i') to the `@canonical_names' and
|
||||
# `@canonical_names' Hashes.
|
||||
#
|
||||
if canonical_name == nil
|
||||
canonical_name = i
|
||||
end
|
||||
@canonical_names[i] = canonical_name
|
||||
@argument_flags[i] = argument_flag
|
||||
#
|
||||
# Register the option (`i') to the `@canonical_names' and
|
||||
# `@canonical_names' Hashes.
|
||||
#
|
||||
if canonical_name == nil
|
||||
canonical_name = i
|
||||
end
|
||||
@canonical_names[i] = canonical_name
|
||||
@argument_flags[i] = argument_flag
|
||||
end
|
||||
raise ArgumentError, "no option name" if canonical_name == nil
|
||||
end
|
||||
|
@ -447,17 +447,17 @@ class GetoptLong
|
|||
return nil
|
||||
elsif @ordering == PERMUTE
|
||||
while 0 < ARGV.length && ARGV[0] !~ /^-./
|
||||
@non_option_arguments.push(ARGV.shift)
|
||||
@non_option_arguments.push(ARGV.shift)
|
||||
end
|
||||
if ARGV.length == 0
|
||||
terminate
|
||||
return nil
|
||||
terminate
|
||||
return nil
|
||||
end
|
||||
argument = ARGV.shift
|
||||
elsif @ordering == REQUIRE_ORDER
|
||||
if (ARGV[0] !~ /^-./)
|
||||
terminate
|
||||
return nil
|
||||
terminate
|
||||
return nil
|
||||
end
|
||||
argument = ARGV.shift
|
||||
else
|
||||
|
@ -482,49 +482,49 @@ class GetoptLong
|
|||
#
|
||||
pattern = $1
|
||||
if @canonical_names.include?(pattern)
|
||||
option_name = pattern
|
||||
option_name = pattern
|
||||
else
|
||||
#
|
||||
# The option `option_name' is not registered in `@canonical_names'.
|
||||
# It may be an abbreviated.
|
||||
#
|
||||
matches = []
|
||||
@canonical_names.each_key do |key|
|
||||
if key.index(pattern) == 0
|
||||
option_name = key
|
||||
matches << key
|
||||
end
|
||||
end
|
||||
if 2 <= matches.length
|
||||
set_error(AmbiguousOption, "option `#{argument}' is ambiguous between #{matches.join(', ')}")
|
||||
elsif matches.length == 0
|
||||
set_error(InvalidOption, "unrecognized option `#{argument}'")
|
||||
end
|
||||
#
|
||||
# The option `option_name' is not registered in `@canonical_names'.
|
||||
# It may be an abbreviated.
|
||||
#
|
||||
matches = []
|
||||
@canonical_names.each_key do |key|
|
||||
if key.index(pattern) == 0
|
||||
option_name = key
|
||||
matches << key
|
||||
end
|
||||
end
|
||||
if 2 <= matches.length
|
||||
set_error(AmbiguousOption, "option `#{argument}' is ambiguous between #{matches.join(', ')}")
|
||||
elsif matches.length == 0
|
||||
set_error(InvalidOption, "unrecognized option `#{argument}'")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Check an argument to the option.
|
||||
#
|
||||
if @argument_flags[option_name] == REQUIRED_ARGUMENT
|
||||
if argument =~ /=(.*)$/
|
||||
option_argument = $1
|
||||
elsif 0 < ARGV.length
|
||||
option_argument = ARGV.shift
|
||||
else
|
||||
set_error(MissingArgument,
|
||||
"option `#{argument}' requires an argument")
|
||||
end
|
||||
if argument =~ /=(.*)$/
|
||||
option_argument = $1
|
||||
elsif 0 < ARGV.length
|
||||
option_argument = ARGV.shift
|
||||
else
|
||||
set_error(MissingArgument,
|
||||
"option `#{argument}' requires an argument")
|
||||
end
|
||||
elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
|
||||
if argument =~ /=(.*)$/
|
||||
option_argument = $1
|
||||
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
||||
option_argument = ARGV.shift
|
||||
else
|
||||
option_argument = ''
|
||||
end
|
||||
if argument =~ /=(.*)$/
|
||||
option_argument = $1
|
||||
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
||||
option_argument = ARGV.shift
|
||||
else
|
||||
option_argument = ''
|
||||
end
|
||||
elsif argument =~ /=(.*)$/
|
||||
set_error(NeedlessArgument,
|
||||
"option `#{option_name}' doesn't allow an argument")
|
||||
set_error(NeedlessArgument,
|
||||
"option `#{option_name}' doesn't allow an argument")
|
||||
end
|
||||
|
||||
elsif argument =~ /^(-(.))(.*)/
|
||||
|
@ -536,40 +536,40 @@ class GetoptLong
|
|||
option_name, ch, @rest_singles = $1, $2, $3
|
||||
|
||||
if @canonical_names.include?(option_name)
|
||||
#
|
||||
# The option `option_name' is found in `@canonical_names'.
|
||||
# Check its argument.
|
||||
#
|
||||
if @argument_flags[option_name] == REQUIRED_ARGUMENT
|
||||
if 0 < @rest_singles.length
|
||||
option_argument = @rest_singles
|
||||
@rest_singles = ''
|
||||
elsif 0 < ARGV.length
|
||||
option_argument = ARGV.shift
|
||||
else
|
||||
# 1003.2 specifies the format of this message.
|
||||
set_error(MissingArgument, "option requires an argument -- #{ch}")
|
||||
end
|
||||
elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
|
||||
if 0 < @rest_singles.length
|
||||
option_argument = @rest_singles
|
||||
@rest_singles = ''
|
||||
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
||||
option_argument = ARGV.shift
|
||||
else
|
||||
option_argument = ''
|
||||
end
|
||||
end
|
||||
#
|
||||
# The option `option_name' is found in `@canonical_names'.
|
||||
# Check its argument.
|
||||
#
|
||||
if @argument_flags[option_name] == REQUIRED_ARGUMENT
|
||||
if 0 < @rest_singles.length
|
||||
option_argument = @rest_singles
|
||||
@rest_singles = ''
|
||||
elsif 0 < ARGV.length
|
||||
option_argument = ARGV.shift
|
||||
else
|
||||
# 1003.2 specifies the format of this message.
|
||||
set_error(MissingArgument, "option requires an argument -- #{ch}")
|
||||
end
|
||||
elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
|
||||
if 0 < @rest_singles.length
|
||||
option_argument = @rest_singles
|
||||
@rest_singles = ''
|
||||
elsif 0 < ARGV.length && ARGV[0] !~ /^-./
|
||||
option_argument = ARGV.shift
|
||||
else
|
||||
option_argument = ''
|
||||
end
|
||||
end
|
||||
else
|
||||
#
|
||||
# This is an invalid option.
|
||||
# 1003.2 specifies the format of this message.
|
||||
#
|
||||
if ENV.include?('POSIXLY_CORRECT')
|
||||
set_error(InvalidOption, "invalid option -- #{ch}")
|
||||
else
|
||||
set_error(InvalidOption, "invalid option -- #{ch}")
|
||||
end
|
||||
#
|
||||
# This is an invalid option.
|
||||
# 1003.2 specifies the format of this message.
|
||||
#
|
||||
if ENV.include?('POSIXLY_CORRECT')
|
||||
set_error(InvalidOption, "invalid option -- #{ch}")
|
||||
else
|
||||
set_error(InvalidOption, "invalid option -- #{ch}")
|
||||
end
|
||||
end
|
||||
else
|
||||
#
|
||||
|
|
|
@ -72,17 +72,17 @@ end
|
|||
#
|
||||
# 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"
|
||||
#
|
||||
# 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
|
||||
|
||||
|
@ -157,13 +157,13 @@ class IPAddr
|
|||
# net1 = IPAddr.new("192.168.2.0/24")
|
||||
# net2 = IPAddr.new("192.168.2.100")
|
||||
# net3 = IPAddr.new("192.168.3.0")
|
||||
# p net1.include?(net2) #=> true
|
||||
# p net1.include?(net3) #=> false
|
||||
# p net1.include?(net2) #=> true
|
||||
# p net1.include?(net3) #=> false
|
||||
def include?(other)
|
||||
other = coerce_other(other)
|
||||
if ipv4_mapped?
|
||||
if (@mask_addr >> 32) != 0xffffffffffffffffffffffff
|
||||
return false
|
||||
return false
|
||||
end
|
||||
mask_addr = (@mask_addr & IN4MASK)
|
||||
addr = (@addr & IN4MASK)
|
||||
|
@ -231,7 +231,7 @@ class IPAddr
|
|||
return [@addr].pack('N')
|
||||
when Socket::AF_INET6
|
||||
return (0..7).map { |i|
|
||||
(@addr >> (112 - 16 * i)) & 0xffff
|
||||
(@addr >> (112 - 16 * i)) & 0xffff
|
||||
}.pack('n8')
|
||||
else
|
||||
raise "unsupported address family"
|
||||
|
@ -372,7 +372,7 @@ class IPAddr
|
|||
raise "unsupported address family"
|
||||
end
|
||||
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
|
||||
|
||||
protected
|
||||
|
@ -381,11 +381,11 @@ class IPAddr
|
|||
case family[0] ? family[0] : @family
|
||||
when Socket::AF_INET
|
||||
if addr < 0 || addr > IN4MASK
|
||||
raise ArgumentError, "invalid address"
|
||||
raise ArgumentError, "invalid address"
|
||||
end
|
||||
when Socket::AF_INET6
|
||||
if addr < 0 || addr > IN6MASK
|
||||
raise ArgumentError, "invalid address"
|
||||
raise ArgumentError, "invalid address"
|
||||
end
|
||||
else
|
||||
raise ArgumentError, "unsupported address family"
|
||||
|
@ -400,15 +400,15 @@ class IPAddr
|
|||
def mask!(mask)
|
||||
if mask.kind_of?(String)
|
||||
if mask =~ /^\d+$/
|
||||
prefixlen = mask.to_i
|
||||
prefixlen = mask.to_i
|
||||
else
|
||||
m = IPAddr.new(mask)
|
||||
if m.family != @family
|
||||
raise ArgumentError, "address family is not same"
|
||||
end
|
||||
@mask_addr = m.to_i
|
||||
@addr &= @mask_addr
|
||||
return self
|
||||
m = IPAddr.new(mask)
|
||||
if m.family != @family
|
||||
raise ArgumentError, "address family is not same"
|
||||
end
|
||||
@mask_addr = m.to_i
|
||||
@addr &= @mask_addr
|
||||
return self
|
||||
end
|
||||
else
|
||||
prefixlen = mask
|
||||
|
@ -416,13 +416,13 @@ class IPAddr
|
|||
case @family
|
||||
when Socket::AF_INET
|
||||
if prefixlen < 0 || prefixlen > 32
|
||||
raise ArgumentError, "invalid length"
|
||||
raise ArgumentError, "invalid length"
|
||||
end
|
||||
masklen = 32 - prefixlen
|
||||
@mask_addr = ((IN4MASK >> masklen) << masklen)
|
||||
when Socket::AF_INET6
|
||||
if prefixlen < 0 || prefixlen > 128
|
||||
raise ArgumentError, "invalid length"
|
||||
raise ArgumentError, "invalid length"
|
||||
end
|
||||
masklen = 128 - prefixlen
|
||||
@mask_addr = ((IN6MASK >> masklen) << masklen)
|
||||
|
@ -461,9 +461,9 @@ class IPAddr
|
|||
@mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
|
||||
return
|
||||
when Socket::AF_UNSPEC
|
||||
raise ArgumentError, "address family must be specified"
|
||||
raise ArgumentError, "address family must be specified"
|
||||
else
|
||||
raise ArgumentError, "unsupported address family: #{family}"
|
||||
raise ArgumentError, "unsupported address family: #{family}"
|
||||
end
|
||||
end
|
||||
prefix, prefixlen = addr.split('/')
|
||||
|
@ -473,9 +473,9 @@ class IPAddr
|
|||
end
|
||||
# It seems AI_NUMERICHOST doesn't do the job.
|
||||
#Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
|
||||
# Socket::AI_NUMERICHOST)
|
||||
# Socket::AI_NUMERICHOST)
|
||||
begin
|
||||
IPSocket.getaddress(prefix) # test if address is valid
|
||||
IPSocket.getaddress(prefix) # test if address is valid
|
||||
rescue
|
||||
raise ArgumentError, "invalid address"
|
||||
end
|
||||
|
@ -483,7 +483,7 @@ class IPAddr
|
|||
if family == Socket::AF_UNSPEC || family == Socket::AF_INET
|
||||
@addr = in_addr(prefix)
|
||||
if @addr
|
||||
@family = Socket::AF_INET
|
||||
@family = Socket::AF_INET
|
||||
end
|
||||
end
|
||||
if !@addr && (family == Socket::AF_UNSPEC || family == Socket::AF_INET6)
|
||||
|
@ -514,8 +514,8 @@ class IPAddr
|
|||
def in_addr(addr)
|
||||
if addr =~ /^\d+\.\d+\.\d+\.\d+$/
|
||||
return addr.split('.').inject(0) { |i, s|
|
||||
i << 8 | s.to_i
|
||||
}
|
||||
i << 8 | s.to_i
|
||||
}
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
@ -559,7 +559,7 @@ class IPAddr
|
|||
case @family
|
||||
when Socket::AF_INET
|
||||
return (0..3).map { |i|
|
||||
(@addr >> (8 * i)) & 0xff
|
||||
(@addr >> (8 * i)) & 0xff
|
||||
}.join('.')
|
||||
when Socket::AF_INET6
|
||||
return ("%.32x" % @addr).reverse!.gsub!(/.(?!$)/, '\&.')
|
||||
|
@ -572,7 +572,7 @@ class IPAddr
|
|||
case @family
|
||||
when Socket::AF_INET
|
||||
return (0..3).map { |i|
|
||||
(addr >> (24 - 8 * i)) & 0xff
|
||||
(addr >> (24 - 8 * i)) & 0xff
|
||||
}.join('.')
|
||||
when Socket::AF_INET6
|
||||
return (("%.32x" % addr).gsub!(/.{4}(?!$)/, '\&:'))
|
||||
|
@ -659,7 +659,7 @@ class TC_IPAddr < Test::Unit::TestCase
|
|||
["[192.168.1.2]/120"],
|
||||
].each { |args|
|
||||
assert_raises(ArgumentError) {
|
||||
IPAddr.new(*args)
|
||||
IPAddr.new(*args)
|
||||
}
|
||||
}
|
||||
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::", @a.to_s)
|
||||
assert_equal("3ffe:505:2:1::",
|
||||
(@a | 0x00000000000000010000000000000000).to_s)
|
||||
(@a | 0x00000000000000010000000000000000).to_s)
|
||||
end
|
||||
|
||||
def test_and
|
||||
|
|
290
lib/irb.rb
290
lib/irb.rb
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# irb.rb - irb main module
|
||||
# $Release Version: 0.9.6 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
# $Release Version: 0.9.6 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
#
|
||||
# --
|
||||
#
|
||||
|
@ -67,12 +67,12 @@ module IRB
|
|||
|
||||
begin
|
||||
catch(:IRB_EXIT) do
|
||||
irb.eval_input
|
||||
irb.eval_input
|
||||
end
|
||||
ensure
|
||||
irb_at_exit
|
||||
end
|
||||
# print "\n"
|
||||
# print "\n"
|
||||
end
|
||||
|
||||
def IRB.irb_at_exit
|
||||
|
@ -108,99 +108,99 @@ module IRB
|
|||
|
||||
def eval_input
|
||||
@scanner.set_prompt do
|
||||
|ltype, indent, continue, line_no|
|
||||
if ltype
|
||||
f = @context.prompt_s
|
||||
elsif continue
|
||||
f = @context.prompt_c
|
||||
elsif indent > 0
|
||||
f = @context.prompt_n
|
||||
else
|
||||
f = @context.prompt_i
|
||||
end
|
||||
f = "" unless f
|
||||
if @context.prompting?
|
||||
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
||||
else
|
||||
@context.io.prompt = p = ""
|
||||
end
|
||||
if @context.auto_indent_mode
|
||||
unless ltype
|
||||
|ltype, indent, continue, line_no|
|
||||
if ltype
|
||||
f = @context.prompt_s
|
||||
elsif continue
|
||||
f = @context.prompt_c
|
||||
elsif indent > 0
|
||||
f = @context.prompt_n
|
||||
else
|
||||
f = @context.prompt_i
|
||||
end
|
||||
f = "" unless f
|
||||
if @context.prompting?
|
||||
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
||||
else
|
||||
@context.io.prompt = p = ""
|
||||
end
|
||||
if @context.auto_indent_mode
|
||||
unless ltype
|
||||
ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
|
||||
indent * 2 - p.size
|
||||
ind += 2 if continue
|
||||
@context.io.prompt = p + " " * ind if ind > 0
|
||||
end
|
||||
end
|
||||
indent * 2 - p.size
|
||||
ind += 2 if continue
|
||||
@context.io.prompt = p + " " * ind if ind > 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@scanner.set_input(@context.io) do
|
||||
signal_status(:IN_INPUT) do
|
||||
if l = @context.io.gets
|
||||
print l if @context.verbose?
|
||||
else
|
||||
if @context.ignore_eof? and @context.io.readable_atfer_eof?
|
||||
l = "\n"
|
||||
if @context.verbose?
|
||||
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
||||
end
|
||||
else
|
||||
print "\n"
|
||||
end
|
||||
end
|
||||
l
|
||||
end
|
||||
signal_status(:IN_INPUT) do
|
||||
if l = @context.io.gets
|
||||
print l if @context.verbose?
|
||||
else
|
||||
if @context.ignore_eof? and @context.io.readable_atfer_eof?
|
||||
l = "\n"
|
||||
if @context.verbose?
|
||||
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
||||
end
|
||||
else
|
||||
print "\n"
|
||||
end
|
||||
end
|
||||
l
|
||||
end
|
||||
end
|
||||
|
||||
@scanner.each_top_level_statement do |line, line_no|
|
||||
signal_status(:IN_EVAL) do
|
||||
begin
|
||||
signal_status(:IN_EVAL) do
|
||||
begin
|
||||
line.untaint
|
||||
@context.evaluate(line, line_no)
|
||||
output_value if @context.echo?
|
||||
exc = nil
|
||||
rescue Interrupt => exc
|
||||
rescue SystemExit, SignalException
|
||||
raise
|
||||
rescue Exception => exc
|
||||
end
|
||||
if exc
|
||||
print exc.class, ": ", exc, "\n"
|
||||
if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
||||
!(SyntaxError === exc)
|
||||
irb_bug = true
|
||||
else
|
||||
irb_bug = false
|
||||
end
|
||||
@context.evaluate(line, line_no)
|
||||
output_value if @context.echo?
|
||||
exc = nil
|
||||
rescue Interrupt => exc
|
||||
rescue SystemExit, SignalException
|
||||
raise
|
||||
rescue Exception => exc
|
||||
end
|
||||
if exc
|
||||
print exc.class, ": ", exc, "\n"
|
||||
if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
||||
!(SyntaxError === exc)
|
||||
irb_bug = true
|
||||
else
|
||||
irb_bug = false
|
||||
end
|
||||
|
||||
messages = []
|
||||
lasts = []
|
||||
levels = 0
|
||||
for m in exc.backtrace
|
||||
m = @context.workspace.filter_backtrace(m) unless irb_bug
|
||||
if m
|
||||
if messages.size < @context.back_trace_limit
|
||||
messages.push "\tfrom "+m
|
||||
else
|
||||
lasts.push "\tfrom "+m
|
||||
if lasts.size > @context.back_trace_limit
|
||||
lasts.shift
|
||||
levels += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
print messages.join("\n"), "\n"
|
||||
unless lasts.empty?
|
||||
printf "... %d levels...\n", levels if levels > 0
|
||||
print lasts.join("\n")
|
||||
end
|
||||
print "Maybe IRB bug!\n" if irb_bug
|
||||
end
|
||||
messages = []
|
||||
lasts = []
|
||||
levels = 0
|
||||
for m in exc.backtrace
|
||||
m = @context.workspace.filter_backtrace(m) unless irb_bug
|
||||
if m
|
||||
if messages.size < @context.back_trace_limit
|
||||
messages.push "\tfrom "+m
|
||||
else
|
||||
lasts.push "\tfrom "+m
|
||||
if lasts.size > @context.back_trace_limit
|
||||
lasts.shift
|
||||
levels += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
print messages.join("\n"), "\n"
|
||||
unless lasts.empty?
|
||||
printf "... %d levels...\n", levels if levels > 0
|
||||
print lasts.join("\n")
|
||||
end
|
||||
print "Maybe IRB bug!\n" if irb_bug
|
||||
end
|
||||
if $SAFE > 2
|
||||
abort "Error: irb does not work for $SAFE level higher than 2"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -208,19 +208,19 @@ module IRB
|
|||
@context.irb_path, back_path = path, @context.irb_path if path
|
||||
@context.irb_name, back_name = name, @context.irb_name if name
|
||||
begin
|
||||
yield back_path, back_name
|
||||
yield back_path, back_name
|
||||
ensure
|
||||
@context.irb_path = back_path if path
|
||||
@context.irb_name = back_name if name
|
||||
@context.irb_path = back_path if path
|
||||
@context.irb_name = back_name if name
|
||||
end
|
||||
end
|
||||
|
||||
def suspend_workspace(workspace)
|
||||
@context.workspace, back_workspace = workspace, @context.workspace
|
||||
begin
|
||||
yield back_workspace
|
||||
yield back_workspace
|
||||
ensure
|
||||
@context.workspace = back_workspace
|
||||
@context.workspace = back_workspace
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -228,39 +228,39 @@ module IRB
|
|||
back_io = @context.io
|
||||
@context.instance_eval{@io = input_method}
|
||||
begin
|
||||
yield back_io
|
||||
yield back_io
|
||||
ensure
|
||||
@context.instance_eval{@io = back_io}
|
||||
@context.instance_eval{@io = back_io}
|
||||
end
|
||||
end
|
||||
|
||||
def suspend_context(context)
|
||||
@context, back_context = context, @context
|
||||
begin
|
||||
yield back_context
|
||||
yield back_context
|
||||
ensure
|
||||
@context = back_context
|
||||
@context = back_context
|
||||
end
|
||||
end
|
||||
|
||||
def signal_handle
|
||||
unless @context.ignore_sigint?
|
||||
print "\nabort!\n" if @context.verbose?
|
||||
exit
|
||||
print "\nabort!\n" if @context.verbose?
|
||||
exit
|
||||
end
|
||||
|
||||
case @signal_status
|
||||
when :IN_INPUT
|
||||
print "^C\n"
|
||||
raise RubyLex::TerminateLineInput
|
||||
print "^C\n"
|
||||
raise RubyLex::TerminateLineInput
|
||||
when :IN_EVAL
|
||||
IRB.irb_abort(self)
|
||||
IRB.irb_abort(self)
|
||||
when :IN_LOAD
|
||||
IRB.irb_abort(self, LoadAbort)
|
||||
IRB.irb_abort(self, LoadAbort)
|
||||
when :IN_IRB
|
||||
# ignore
|
||||
# ignore
|
||||
else
|
||||
# ignore other cases as well
|
||||
# ignore other cases as well
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -270,39 +270,39 @@ module IRB
|
|||
signal_status_back = @signal_status
|
||||
@signal_status = status
|
||||
begin
|
||||
yield
|
||||
yield
|
||||
ensure
|
||||
@signal_status = signal_status_back
|
||||
@signal_status = signal_status_back
|
||||
end
|
||||
end
|
||||
|
||||
def prompt(prompt, ltype, indent, line_no)
|
||||
p = prompt.dup
|
||||
p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
|
||||
case $2
|
||||
when "N"
|
||||
@context.irb_name
|
||||
when "m"
|
||||
@context.main.to_s
|
||||
when "M"
|
||||
@context.main.inspect
|
||||
when "l"
|
||||
ltype
|
||||
when "i"
|
||||
if $1
|
||||
format("%" + $1 + "d", indent)
|
||||
else
|
||||
indent.to_s
|
||||
end
|
||||
when "n"
|
||||
if $1
|
||||
format("%" + $1 + "d", line_no)
|
||||
else
|
||||
line_no.to_s
|
||||
end
|
||||
when "%"
|
||||
"%"
|
||||
end
|
||||
case $2
|
||||
when "N"
|
||||
@context.irb_name
|
||||
when "m"
|
||||
@context.main.to_s
|
||||
when "M"
|
||||
@context.main.inspect
|
||||
when "l"
|
||||
ltype
|
||||
when "i"
|
||||
if $1
|
||||
format("%" + $1 + "d", indent)
|
||||
else
|
||||
indent.to_s
|
||||
end
|
||||
when "n"
|
||||
if $1
|
||||
format("%" + $1 + "d", line_no)
|
||||
else
|
||||
line_no.to_s
|
||||
end
|
||||
when "%"
|
||||
"%"
|
||||
end
|
||||
end
|
||||
p
|
||||
end
|
||||
|
@ -314,14 +314,14 @@ module IRB
|
|||
def inspect
|
||||
ary = []
|
||||
for iv in instance_variables
|
||||
case (iv = iv.to_s)
|
||||
when "@signal_status"
|
||||
ary.push format("%s=:%s", iv, @signal_status.id2name)
|
||||
when "@context"
|
||||
ary.push format("%s=%s", iv, eval(iv).__to_s__)
|
||||
else
|
||||
ary.push format("%s=%s", iv, eval(iv))
|
||||
end
|
||||
case (iv = iv.to_s)
|
||||
when "@signal_status"
|
||||
ary.push format("%s=:%s", iv, @signal_status.id2name)
|
||||
when "@context"
|
||||
ary.push format("%s=%s", iv, eval(iv).__to_s__)
|
||||
else
|
||||
ary.push format("%s=%s", iv, eval(iv))
|
||||
end
|
||||
end
|
||||
format("#<%s: %s>", self.class, ary.join(", "))
|
||||
end
|
||||
|
@ -335,16 +335,16 @@ module IRB
|
|||
for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
|
||||
case k
|
||||
when :MAIN_CONTEXT, :__TMP__EHV__
|
||||
array.push format("CONF[:%s]=...myself...", k.id2name)
|
||||
array.push format("CONF[:%s]=...myself...", k.id2name)
|
||||
when :PROMPT
|
||||
s = v.collect{
|
||||
|kk, vv|
|
||||
ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
|
||||
format(":%s=>{%s}", kk.id2name, ss.join(", "))
|
||||
}
|
||||
array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
|
||||
s = v.collect{
|
||||
|kk, vv|
|
||||
ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
|
||||
format(":%s=>{%s}", kk.id2name, ss.join(", "))
|
||||
}
|
||||
array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
|
||||
else
|
||||
array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
|
||||
array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
|
||||
end
|
||||
end
|
||||
array.join("\n")
|
||||
|
|
|
@ -263,9 +263,9 @@ class Logger
|
|||
alias sev_threshold level
|
||||
alias sev_threshold= level=
|
||||
|
||||
# Returns +true+ iff the current severity level allows for the printing of
|
||||
# +DEBUG+ messages.
|
||||
def debug?; @level <= DEBUG; end
|
||||
# Returns +true+ iff the current severity level allows for the printing of
|
||||
# +DEBUG+ messages.
|
||||
def debug?; @level <= DEBUG; end
|
||||
|
||||
# Returns +true+ iff the current severity level allows for the printing of
|
||||
# +INFO+ messages.
|
||||
|
@ -312,7 +312,7 @@ class Logger
|
|||
@logdev = nil
|
||||
if logdev
|
||||
@logdev = LogDevice.new(logdev, :shift_age => shift_age,
|
||||
:shift_size => shift_size)
|
||||
:shift_size => shift_size)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -376,7 +376,7 @@ class Logger
|
|||
end
|
||||
@logdev.write(
|
||||
format_message(format_severity(severity), Time.now, progname, message))
|
||||
true
|
||||
true
|
||||
end
|
||||
alias log add
|
||||
|
||||
|
@ -478,7 +478,7 @@ class Logger
|
|||
@logdev.close if @logdev
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
# Severity label for logging. (max 5 char)
|
||||
SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY)
|
||||
|
@ -507,7 +507,7 @@ private
|
|||
msg2str(msg)]
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def format_datetime(time)
|
||||
if @datetime_format.nil?
|
||||
|
@ -523,7 +523,7 @@ private
|
|||
msg
|
||||
when ::Exception
|
||||
"#{ msg.message } (#{ msg.class })\n" <<
|
||||
(msg.backtrace || []).join("\n")
|
||||
(msg.backtrace || []).join("\n")
|
||||
else
|
||||
msg.inspect
|
||||
end
|
||||
|
@ -585,7 +585,7 @@ private
|
|||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def open_logfile(filename)
|
||||
if (FileTest.exist?(filename))
|
||||
|
@ -791,7 +791,7 @@ private
|
|||
@log.add(severity, message, @appname, &block) if @log
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def run
|
||||
# TODO: should be an NotImplementedError
|
||||
|
|
116
lib/mkmf.rb
116
lib/mkmf.rb
|
@ -299,18 +299,18 @@ end
|
|||
|
||||
def xsystem command, opts = nil
|
||||
varpat = /\$\((\w+)\)|\$\{(\w+)\}/
|
||||
if varpat =~ command
|
||||
vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
|
||||
command = command.dup
|
||||
nil while command.gsub!(varpat) {vars[$1||$2]}
|
||||
end
|
||||
if varpat =~ command
|
||||
vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
|
||||
command = command.dup
|
||||
nil while command.gsub!(varpat) {vars[$1||$2]}
|
||||
end
|
||||
Logging::open do
|
||||
puts command.quote
|
||||
if opts and opts[:werror]
|
||||
result = nil
|
||||
Logging.postpone do |log|
|
||||
result = (system(command) and File.zero?(log.path))
|
||||
""
|
||||
result = (system(command) and File.zero?(log.path))
|
||||
""
|
||||
end
|
||||
result
|
||||
else
|
||||
|
@ -337,12 +337,12 @@ def log_src(src)
|
|||
Logging::message <<"EOM"
|
||||
checked program was:
|
||||
/* begin */
|
||||
EOM
|
||||
EOM
|
||||
src.each_with_index {|line, no| Logging::message fmt, no+1, line}
|
||||
Logging::message <<"EOM"
|
||||
/* end */
|
||||
|
||||
EOM
|
||||
EOM
|
||||
end
|
||||
|
||||
def create_tmpsrc(src)
|
||||
|
@ -410,7 +410,7 @@ def cc_command(opt="")
|
|||
'arch_hdrdir' => "#$arch_hdrdir",
|
||||
'top_srcdir' => $top_srcdir.quote)
|
||||
RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
|
||||
conf)
|
||||
conf)
|
||||
end
|
||||
|
||||
def cpp_command(outfile, opt="")
|
||||
|
@ -418,7 +418,7 @@ def cpp_command(outfile, opt="")
|
|||
'arch_hdrdir' => "#$arch_hdrdir",
|
||||
'top_srcdir' => $top_srcdir.quote)
|
||||
RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
|
||||
conf)
|
||||
conf)
|
||||
end
|
||||
|
||||
def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
|
||||
|
@ -547,7 +547,7 @@ end
|
|||
def try_static_assert(expr, headers = nil, opt = "", &b)
|
||||
headers = cpp_include(headers)
|
||||
try_compile(<<SRC, opt, &b)
|
||||
#{headers}
|
||||
#{headers}
|
||||
/*top*/
|
||||
int conftest_const[(#{expr}) ? 1 : -1];
|
||||
SRC
|
||||
|
@ -616,15 +616,15 @@ def try_func(func, libs, headers = nil, &b)
|
|||
decltype = proc {|x| "void ((*#{x})())"}
|
||||
end
|
||||
try_link(<<"SRC", libs, &b) or
|
||||
#{headers}
|
||||
#{headers}
|
||||
/*top*/
|
||||
#{MAIN_DOES_NOTHING}
|
||||
#{MAIN_DOES_NOTHING}
|
||||
int t() { #{decltype["volatile p"]}; p = (#{decltype[]})#{func}; return 0; }
|
||||
SRC
|
||||
call && try_link(<<"SRC", libs, &b)
|
||||
#{headers}
|
||||
#{headers}
|
||||
/*top*/
|
||||
#{MAIN_DOES_NOTHING}
|
||||
#{MAIN_DOES_NOTHING}
|
||||
int t() { #{func}(); return 0; }
|
||||
SRC
|
||||
end
|
||||
|
@ -633,9 +633,9 @@ end
|
|||
def try_var(var, headers = nil, &b)
|
||||
headers = cpp_include(headers)
|
||||
try_compile(<<"SRC", &b)
|
||||
#{headers}
|
||||
#{headers}
|
||||
/*top*/
|
||||
#{MAIN_DOES_NOTHING}
|
||||
#{MAIN_DOES_NOTHING}
|
||||
int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
|
||||
SRC
|
||||
end
|
||||
|
@ -659,18 +659,18 @@ def egrep_cpp(pat, src, opt = "", &b)
|
|||
if Regexp === pat
|
||||
puts(" ruby -ne 'print if #{pat.inspect}'")
|
||||
f.grep(pat) {|l|
|
||||
puts "#{f.lineno}: #{l}"
|
||||
return true
|
||||
puts "#{f.lineno}: #{l}"
|
||||
return true
|
||||
}
|
||||
false
|
||||
else
|
||||
puts(" egrep '#{pat}'")
|
||||
begin
|
||||
stdin = $stdin.dup
|
||||
$stdin.reopen(f)
|
||||
system("egrep", pat)
|
||||
stdin = $stdin.dup
|
||||
$stdin.reopen(f)
|
||||
system("egrep", pat)
|
||||
ensure
|
||||
$stdin.reopen(stdin)
|
||||
$stdin.reopen(stdin)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -867,11 +867,11 @@ def find_library(lib, func, *paths, &b)
|
|||
libs = append_library($libs, lib)
|
||||
begin
|
||||
until r = try_func(func, libs, &b) or paths.empty?
|
||||
$LIBPATH = libpath | [paths.shift]
|
||||
$LIBPATH = libpath | [paths.shift]
|
||||
end
|
||||
if r
|
||||
$libs = libs
|
||||
libpath = nil
|
||||
$libs = libs
|
||||
libpath = nil
|
||||
end
|
||||
ensure
|
||||
$LIBPATH = libpath if libpath
|
||||
|
@ -999,9 +999,9 @@ end
|
|||
def have_struct_member(type, member, headers = nil, &b)
|
||||
checking_for checking_message("#{type}.#{member}", headers) do
|
||||
if try_compile(<<"SRC", &b)
|
||||
#{cpp_include(headers)}
|
||||
#{cpp_include(headers)}
|
||||
/*top*/
|
||||
#{MAIN_DOES_NOTHING}
|
||||
#{MAIN_DOES_NOTHING}
|
||||
int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
|
||||
SRC
|
||||
$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)
|
||||
if try_compile(<<"SRC", opt, &b)
|
||||
#{cpp_include(headers)}
|
||||
#{cpp_include(headers)}
|
||||
/*top*/
|
||||
typedef #{type} conftest_type;
|
||||
int conftestval[sizeof(conftest_type)?1:-1];
|
||||
|
@ -1077,7 +1077,7 @@ end
|
|||
def try_const(const, headers = nil, opt = "", &b)
|
||||
const, type = *const
|
||||
if try_compile(<<"SRC", opt, &b)
|
||||
#{cpp_include(headers)}
|
||||
#{cpp_include(headers)}
|
||||
/*top*/
|
||||
typedef #{type || 'int'} conftest_type;
|
||||
conftest_type conftestval = #{type ? '' : '(int)'}#{const};
|
||||
|
@ -1217,18 +1217,18 @@ def convertible_int(type, headers = nil, opts = nil, &b)
|
|||
u = "unsigned " if signed > 0
|
||||
prelude << "extern rbcv_typedef_ foo();"
|
||||
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
|
||||
macname ||= type.sub(/_(?=t\z)/, '').tr_cpp
|
||||
conv = (compat == "long long" ? "LL" : compat.upcase)
|
||||
compat = "#{u}#{compat}"
|
||||
$defs.push(format("-DTYPEOF_%s=%s", type.tr_cpp, compat.quote))
|
||||
$defs.push(format("-DPRI_%s_PREFIX=PRI_%s_PREFIX", macname, conv))
|
||||
conv = (u ? "U" : "") + conv
|
||||
$defs.push(format("-D%s2NUM=%s2NUM", macname, conv))
|
||||
$defs.push(format("-DNUM2%s=NUM2%s", macname, conv))
|
||||
compat
|
||||
macname ||= type.sub(/_(?=t\z)/, '').tr_cpp
|
||||
conv = (compat == "long long" ? "LL" : compat.upcase)
|
||||
compat = "#{u}#{compat}"
|
||||
$defs.push(format("-DTYPEOF_%s=%s", type.tr_cpp, compat.quote))
|
||||
$defs.push(format("-DPRI_%s_PREFIX=PRI_%s_PREFIX", macname, conv))
|
||||
conv = (u ? "U" : "") + conv
|
||||
$defs.push(format("-D%s2NUM=%s2NUM", macname, conv))
|
||||
$defs.push(format("-DNUM2%s=NUM2%s", macname, conv))
|
||||
compat
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1239,10 +1239,10 @@ end
|
|||
# pointer.
|
||||
def scalar_ptr_type?(type, member = nil, headers = nil, &b)
|
||||
try_compile(<<"SRC", &b) # pointer
|
||||
#{cpp_include(headers)}
|
||||
#{cpp_include(headers)}
|
||||
/*top*/
|
||||
volatile #{type} conftestval;
|
||||
#{MAIN_DOES_NOTHING}
|
||||
#{MAIN_DOES_NOTHING}
|
||||
int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
|
||||
SRC
|
||||
end
|
||||
|
@ -1251,10 +1251,10 @@ end
|
|||
# pointer.
|
||||
def scalar_type?(type, member = nil, headers = nil, &b)
|
||||
try_compile(<<"SRC", &b) # pointer
|
||||
#{cpp_include(headers)}
|
||||
#{cpp_include(headers)}
|
||||
/*top*/
|
||||
volatile #{type} conftestval;
|
||||
#{MAIN_DOES_NOTHING}
|
||||
#{MAIN_DOES_NOTHING}
|
||||
int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
|
||||
SRC
|
||||
end
|
||||
|
@ -1266,7 +1266,7 @@ def have_typeof?
|
|||
$typeof = %w[__typeof__ typeof].find do |t|
|
||||
try_compile(<<SRC)
|
||||
int rbcv_foo;
|
||||
#{t}(rbcv_foo) rbcv_bar;
|
||||
#{t}(rbcv_foo) rbcv_bar;
|
||||
SRC
|
||||
end
|
||||
end
|
||||
|
@ -1644,7 +1644,7 @@ ECHO1 = $(V:1=@:)
|
|||
ECHO = $(ECHO1:0=@echo)
|
||||
|
||||
#### 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}
|
||||
topdir = #{mkintpath($extmk ? CONFIG["topdir"] : $topdir).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
|
||||
"!ifndef " + $1 + "\n" +
|
||||
$& +
|
||||
"!endif\n"
|
||||
"!endif\n"
|
||||
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 "\t$(INSTALL_PROG) #{fseprepl[f]} $(@D#{sep})\n"
|
||||
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
|
||||
else
|
||||
|
@ -2020,17 +2020,17 @@ static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
|
|||
files = install_files(mfile, i, nil, srcprefix) or next
|
||||
for dir, *files in files
|
||||
unless dirs.include?(dir)
|
||||
dirs << dir
|
||||
mfile.print "pre-install-rb#{sfx}: #{dir}\n"
|
||||
dirs << dir
|
||||
mfile.print "pre-install-rb#{sfx}: #{dir}\n"
|
||||
end
|
||||
for f in files
|
||||
dest = "#{dir}/#{File.basename(f)}"
|
||||
mfile.print("install-rb#{sfx}: #{dest} #{dir}\n")
|
||||
mfile.print("#{dest}: #{f}\n")
|
||||
mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $(@D#{sep})\n")
|
||||
if defined?($installed_list) and !$extout
|
||||
mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
|
||||
end
|
||||
dest = "#{dir}/#{File.basename(f)}"
|
||||
mfile.print("install-rb#{sfx}: #{dest} #{dir}\n")
|
||||
mfile.print("#{dest}: #{f}\n")
|
||||
mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $(@D#{sep})\n")
|
||||
if defined?($installed_list) and !$extout
|
||||
mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
|
||||
end
|
||||
if $extout
|
||||
mfile.print("clean-rb#{sfx}::\n")
|
||||
mfile.print("\t@-$(RM) #{fseprepl[dest]}\n")
|
||||
|
|
|
@ -109,7 +109,7 @@ module MonitorMixin
|
|||
#
|
||||
def wait_while
|
||||
while yield
|
||||
wait
|
||||
wait
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -118,7 +118,7 @@ module MonitorMixin
|
|||
#
|
||||
def wait_until
|
||||
until yield
|
||||
wait
|
||||
wait
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
#
|
||||
# mutex_m.rb -
|
||||
# $Release Version: 3.0$
|
||||
# $Revision: 1.7 $
|
||||
# $Release Version: 3.0$
|
||||
# $Revision: 1.7 $
|
||||
# Original from mutex.rb
|
||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||
# modified by matz
|
||||
# patched by akira yamada
|
||||
#
|
||||
# --
|
||||
# Usage:
|
||||
# require "mutex_m.rb"
|
||||
# obj = Object.new
|
||||
# obj.extend Mutex_m
|
||||
# ...
|
||||
# extended object can be handled like Mutex
|
||||
# require "mutex_m.rb"
|
||||
# obj = Object.new
|
||||
# obj.extend Mutex_m
|
||||
# ...
|
||||
# extended object can be handled like Mutex
|
||||
# or
|
||||
# class Foo
|
||||
# include Mutex_m
|
||||
# ...
|
||||
# end
|
||||
# obj = Foo.new
|
||||
# this obj can be handled like Mutex
|
||||
# class Foo
|
||||
# include Mutex_m
|
||||
# ...
|
||||
# end
|
||||
# obj = Foo.new
|
||||
# this obj can be handled like Mutex
|
||||
#
|
||||
|
||||
require 'thread'
|
||||
|
@ -48,11 +48,11 @@ module Mutex_m
|
|||
|
||||
def mu_extended
|
||||
unless (defined? locked? and
|
||||
defined? lock and
|
||||
defined? unlock and
|
||||
defined? try_lock and
|
||||
defined? synchronize)
|
||||
Mutex_m.define_aliases(singleton_class)
|
||||
defined? lock and
|
||||
defined? unlock and
|
||||
defined? try_lock and
|
||||
defined? synchronize)
|
||||
Mutex_m.define_aliases(singleton_class)
|
||||
end
|
||||
mu_initialize
|
||||
end
|
||||
|
|
336
lib/net/ftp.rb
336
lib/net/ftp.rb
|
@ -136,10 +136,10 @@ module Net
|
|||
@sock = NullSocket.new
|
||||
@logged_in = false
|
||||
if host
|
||||
connect(host)
|
||||
if user
|
||||
login(user, passwd, acct)
|
||||
end
|
||||
connect(host)
|
||||
if user
|
||||
login(user, passwd, acct)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -197,10 +197,10 @@ module Net
|
|||
# else a TCPSocket is returned.
|
||||
def open_socket(host, port)
|
||||
if defined? SOCKSSocket and ENV["SOCKS_SERVER"]
|
||||
@passive = true
|
||||
return SOCKSSocket.open(host, port)
|
||||
@passive = true
|
||||
return SOCKSSocket.open(host, port)
|
||||
else
|
||||
return TCPSocket.open(host, port)
|
||||
return TCPSocket.open(host, port)
|
||||
end
|
||||
end
|
||||
private :open_socket
|
||||
|
@ -213,11 +213,11 @@ module Net
|
|||
#
|
||||
def connect(host, port = FTP_PORT)
|
||||
if @debug_mode
|
||||
print "connect: ", host, ", ", port, "\n"
|
||||
print "connect: ", host, ", ", port, "\n"
|
||||
end
|
||||
synchronize do
|
||||
@sock = open_socket(host, port)
|
||||
voidresp
|
||||
@sock = open_socket(host, port)
|
||||
voidresp
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -226,10 +226,10 @@ module Net
|
|||
#
|
||||
def set_socket(sock, get_greeting = true)
|
||||
synchronize do
|
||||
@sock = sock
|
||||
if get_greeting
|
||||
voidresp
|
||||
end
|
||||
@sock = sock
|
||||
if get_greeting
|
||||
voidresp
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -237,9 +237,9 @@ module Net
|
|||
# then the contents of the password are cleaned from the string using "*"
|
||||
def sanitize(s)
|
||||
if s =~ /^PASS /i
|
||||
return s[0, 5] + "*" * (s.length - 5)
|
||||
return s[0, 5] + "*" * (s.length - 5)
|
||||
else
|
||||
return s
|
||||
return s
|
||||
end
|
||||
end
|
||||
private :sanitize
|
||||
|
@ -248,7 +248,7 @@ module Net
|
|||
# and writes it to the socket.
|
||||
def putline(line)
|
||||
if @debug_mode
|
||||
print "put: ", sanitize(line), "\n"
|
||||
print "put: ", sanitize(line), "\n"
|
||||
end
|
||||
line = line + CRLF
|
||||
@sock.write(line)
|
||||
|
@ -261,7 +261,7 @@ module Net
|
|||
line = @sock.readline # if get EOF, raise EOFError
|
||||
line.sub!(/(\r\n|\n|\r)\z/n, "")
|
||||
if @debug_mode
|
||||
print "get: ", sanitize(line), "\n"
|
||||
print "get: ", sanitize(line), "\n"
|
||||
end
|
||||
return line
|
||||
end
|
||||
|
@ -272,11 +272,11 @@ module Net
|
|||
line = getline
|
||||
buff = line
|
||||
if line[3] == ?-
|
||||
code = line[0, 3]
|
||||
begin
|
||||
line = getline
|
||||
buff << "\n" << line
|
||||
end until line[0, 3] == code and line[3] != ?-
|
||||
code = line[0, 3]
|
||||
begin
|
||||
line = getline
|
||||
buff << "\n" << line
|
||||
end until line[0, 3] == code and line[3] != ?-
|
||||
end
|
||||
return buff << "\n"
|
||||
end
|
||||
|
@ -290,13 +290,13 @@ module Net
|
|||
@last_response_code = @last_response[0, 3]
|
||||
case @last_response_code
|
||||
when /\A[123]/
|
||||
return @last_response
|
||||
return @last_response
|
||||
when /\A4/
|
||||
raise FTPTempError, @last_response
|
||||
raise FTPTempError, @last_response
|
||||
when /\A5/
|
||||
raise FTPPermError, @last_response
|
||||
raise FTPPermError, @last_response
|
||||
else
|
||||
raise FTPProtoError, @last_response
|
||||
raise FTPProtoError, @last_response
|
||||
end
|
||||
end
|
||||
private :getresp
|
||||
|
@ -306,7 +306,7 @@ module Net
|
|||
def voidresp
|
||||
resp = getresp
|
||||
if resp[0] != ?2
|
||||
raise FTPReplyError, resp
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
end
|
||||
private :voidresp
|
||||
|
@ -316,8 +316,8 @@ module Net
|
|||
#
|
||||
def sendcmd(cmd)
|
||||
synchronize do
|
||||
putline(cmd)
|
||||
return getresp
|
||||
putline(cmd)
|
||||
return getresp
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -326,8 +326,8 @@ module Net
|
|||
#
|
||||
def voidcmd(cmd)
|
||||
synchronize do
|
||||
putline(cmd)
|
||||
voidresp
|
||||
putline(cmd)
|
||||
voidresp
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -335,11 +335,11 @@ module Net
|
|||
def sendport(host, port)
|
||||
af = (@sock.peeraddr)[0]
|
||||
if af == "AF_INET"
|
||||
cmd = "PORT " + (host.split(".") + port.divmod(256)).join(",")
|
||||
cmd = "PORT " + (host.split(".") + port.divmod(256)).join(",")
|
||||
elsif af == "AF_INET6"
|
||||
cmd = sprintf("EPRT |2|%s|%d|", host, port)
|
||||
cmd = sprintf("EPRT |2|%s|%d|", host, port)
|
||||
else
|
||||
raise FTPProtoError, host
|
||||
raise FTPProtoError, host
|
||||
end
|
||||
voidcmd(cmd)
|
||||
end
|
||||
|
@ -360,10 +360,10 @@ module Net
|
|||
# sends the appropriate command to enable a passive connection
|
||||
def makepasv
|
||||
if @sock.peeraddr[0] == "AF_INET"
|
||||
host, port = parse227(sendcmd("PASV"))
|
||||
host, port = parse227(sendcmd("PASV"))
|
||||
else
|
||||
host, port = parse229(sendcmd("EPSV"))
|
||||
# host, port = parse228(sendcmd("LPSV"))
|
||||
host, port = parse229(sendcmd("EPSV"))
|
||||
# host, port = parse228(sendcmd("LPSV"))
|
||||
end
|
||||
return host, port
|
||||
end
|
||||
|
@ -372,36 +372,36 @@ module Net
|
|||
# Constructs a connection for transferring data
|
||||
def transfercmd(cmd, rest_offset = nil)
|
||||
if @passive
|
||||
host, port = makepasv
|
||||
conn = open_socket(host, port)
|
||||
if @resume and rest_offset
|
||||
resp = sendcmd("REST " + rest_offset.to_s)
|
||||
if resp[0] != ?3
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
end
|
||||
resp = sendcmd(cmd)
|
||||
host, port = makepasv
|
||||
conn = open_socket(host, port)
|
||||
if @resume and rest_offset
|
||||
resp = sendcmd("REST " + rest_offset.to_s)
|
||||
if resp[0] != ?3
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
end
|
||||
resp = sendcmd(cmd)
|
||||
# skip 2XX for some ftp servers
|
||||
resp = getresp if resp[0] == ?2
|
||||
if resp[0] != ?1
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
if resp[0] != ?1
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
else
|
||||
sock = makeport
|
||||
if @resume and rest_offset
|
||||
resp = sendcmd("REST " + rest_offset.to_s)
|
||||
if resp[0] != ?3
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
end
|
||||
resp = sendcmd(cmd)
|
||||
sock = makeport
|
||||
if @resume and rest_offset
|
||||
resp = sendcmd("REST " + rest_offset.to_s)
|
||||
if resp[0] != ?3
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
end
|
||||
resp = sendcmd(cmd)
|
||||
# skip 2XX for some ftp servers
|
||||
resp = getresp if resp[0] == ?2
|
||||
if resp[0] != ?1
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
conn = sock.accept
|
||||
sock.close
|
||||
if resp[0] != ?1
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
conn = sock.accept
|
||||
sock.close
|
||||
end
|
||||
return conn
|
||||
end
|
||||
|
@ -417,23 +417,23 @@ module Net
|
|||
#
|
||||
def login(user = "anonymous", passwd = nil, acct = nil)
|
||||
if user == "anonymous" and passwd == nil
|
||||
passwd = "anonymous@"
|
||||
passwd = "anonymous@"
|
||||
end
|
||||
|
||||
resp = ""
|
||||
synchronize do
|
||||
resp = sendcmd('USER ' + user)
|
||||
if resp[0] == ?3
|
||||
resp = sendcmd('USER ' + user)
|
||||
if resp[0] == ?3
|
||||
raise FTPReplyError, resp if passwd.nil?
|
||||
resp = sendcmd('PASS ' + passwd)
|
||||
end
|
||||
if resp[0] == ?3
|
||||
resp = sendcmd('PASS ' + passwd)
|
||||
end
|
||||
if resp[0] == ?3
|
||||
raise FTPReplyError, resp if acct.nil?
|
||||
resp = sendcmd('ACCT ' + acct)
|
||||
end
|
||||
resp = sendcmd('ACCT ' + acct)
|
||||
end
|
||||
end
|
||||
if resp[0] != ?2
|
||||
raise FTPReplyError, resp
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
@welcome = resp
|
||||
send_type_command
|
||||
|
@ -448,7 +448,7 @@ module Net
|
|||
#
|
||||
def retrbinary(cmd, blocksize, rest_offset = nil) # :yield: data
|
||||
synchronize do
|
||||
with_binary(true) do
|
||||
with_binary(true) do
|
||||
conn = transfercmd(cmd, rest_offset)
|
||||
loop do
|
||||
data = conn.read(blocksize)
|
||||
|
@ -469,7 +469,7 @@ module Net
|
|||
#
|
||||
def retrlines(cmd) # :yield: line
|
||||
synchronize do
|
||||
with_binary(false) do
|
||||
with_binary(false) do
|
||||
conn = transfercmd(cmd)
|
||||
loop do
|
||||
line = conn.gets
|
||||
|
@ -493,7 +493,7 @@ module Net
|
|||
file.seek(rest_offset, IO::SEEK_SET)
|
||||
end
|
||||
synchronize do
|
||||
with_binary(true) do
|
||||
with_binary(true) do
|
||||
conn = transfercmd(cmd)
|
||||
loop do
|
||||
buf = file.read(blocksize)
|
||||
|
@ -522,7 +522,7 @@ module Net
|
|||
#
|
||||
def storlines(cmd, file, &block) # :yield: line
|
||||
synchronize do
|
||||
with_binary(false) do
|
||||
with_binary(false) do
|
||||
conn = transfercmd(cmd)
|
||||
loop do
|
||||
buf = file.gets
|
||||
|
@ -553,7 +553,7 @@ module Net
|
|||
# chunks.
|
||||
#
|
||||
def getbinaryfile(remotefile, localfile = File.basename(remotefile),
|
||||
blocksize = DEFAULT_BLOCKSIZE) # :yield: data
|
||||
blocksize = DEFAULT_BLOCKSIZE) # :yield: data
|
||||
result = nil
|
||||
if localfile
|
||||
if @resume
|
||||
|
@ -567,15 +567,15 @@ module Net
|
|||
result = ""
|
||||
end
|
||||
begin
|
||||
f.binmode if localfile
|
||||
retrbinary("RETR " + remotefile.to_s, blocksize, rest_offset) do |data|
|
||||
f.write(data) if localfile
|
||||
yield(data) if block_given?
|
||||
f.binmode if localfile
|
||||
retrbinary("RETR " + remotefile.to_s, blocksize, rest_offset) do |data|
|
||||
f.write(data) if localfile
|
||||
yield(data) if block_given?
|
||||
result.concat(data) if result
|
||||
end
|
||||
end
|
||||
return result
|
||||
ensure
|
||||
f.close if localfile
|
||||
f.close if localfile
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -594,15 +594,15 @@ module Net
|
|||
result = ""
|
||||
end
|
||||
begin
|
||||
retrlines("RETR " + remotefile) do |line, newline|
|
||||
retrlines("RETR " + remotefile) do |line, newline|
|
||||
l = newline ? line + "\n" : line
|
||||
f.print(l) if localfile
|
||||
yield(line, newline) if block_given?
|
||||
f.print(l) if localfile
|
||||
yield(line, newline) if block_given?
|
||||
result.concat(l) if result
|
||||
end
|
||||
end
|
||||
return result
|
||||
ensure
|
||||
f.close if localfile
|
||||
f.close if localfile
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -611,11 +611,11 @@ module Net
|
|||
# binary). See #gettextfile and #getbinaryfile.
|
||||
#
|
||||
def get(remotefile, localfile = File.basename(remotefile),
|
||||
blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
|
||||
blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
|
||||
if @binary
|
||||
getbinaryfile(remotefile, localfile, blocksize, &block)
|
||||
getbinaryfile(remotefile, localfile, blocksize, &block)
|
||||
else
|
||||
gettextfile(remotefile, localfile, &block)
|
||||
gettextfile(remotefile, localfile, &block)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -625,7 +625,7 @@ module Net
|
|||
# data in +blocksize+ chunks.
|
||||
#
|
||||
def putbinaryfile(localfile, remotefile = File.basename(localfile),
|
||||
blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
|
||||
blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
|
||||
if @resume
|
||||
begin
|
||||
rest_offset = size(remotefile)
|
||||
|
@ -633,18 +633,18 @@ module Net
|
|||
rest_offset = nil
|
||||
end
|
||||
else
|
||||
rest_offset = nil
|
||||
rest_offset = nil
|
||||
end
|
||||
f = open(localfile)
|
||||
begin
|
||||
f.binmode
|
||||
f.binmode
|
||||
if rest_offset
|
||||
storbinary("APPE " + remotefile, f, blocksize, rest_offset, &block)
|
||||
else
|
||||
storbinary("STOR " + remotefile, f, blocksize, rest_offset, &block)
|
||||
end
|
||||
ensure
|
||||
f.close
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -656,9 +656,9 @@ module Net
|
|||
def puttextfile(localfile, remotefile = File.basename(localfile), &block) # :yield: line
|
||||
f = open(localfile)
|
||||
begin
|
||||
storlines("STOR " + remotefile, f, &block)
|
||||
storlines("STOR " + remotefile, f, &block)
|
||||
ensure
|
||||
f.close
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -667,11 +667,11 @@ module Net
|
|||
# (text or binary). See #puttextfile and #putbinaryfile.
|
||||
#
|
||||
def put(localfile, remotefile = File.basename(localfile),
|
||||
blocksize = DEFAULT_BLOCKSIZE, &block)
|
||||
blocksize = DEFAULT_BLOCKSIZE, &block)
|
||||
if @binary
|
||||
putbinaryfile(localfile, remotefile, blocksize, &block)
|
||||
putbinaryfile(localfile, remotefile, blocksize, &block)
|
||||
else
|
||||
puttextfile(localfile, remotefile, &block)
|
||||
puttextfile(localfile, remotefile, &block)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -692,11 +692,11 @@ module Net
|
|||
def nlst(dir = nil)
|
||||
cmd = "NLST"
|
||||
if dir
|
||||
cmd = cmd + " " + dir
|
||||
cmd = cmd + " " + dir
|
||||
end
|
||||
files = []
|
||||
retrlines(cmd) do |line|
|
||||
files.push(line)
|
||||
files.push(line)
|
||||
end
|
||||
return files
|
||||
end
|
||||
|
@ -708,16 +708,16 @@ module Net
|
|||
def list(*args, &block) # :yield: line
|
||||
cmd = "LIST"
|
||||
args.each do |arg|
|
||||
cmd = cmd + " " + arg.to_s
|
||||
cmd = cmd + " " + arg.to_s
|
||||
end
|
||||
if block
|
||||
retrlines(cmd, &block)
|
||||
retrlines(cmd, &block)
|
||||
else
|
||||
lines = []
|
||||
retrlines(cmd) do |line|
|
||||
lines << line
|
||||
end
|
||||
return lines
|
||||
lines = []
|
||||
retrlines(cmd) do |line|
|
||||
lines << line
|
||||
end
|
||||
return lines
|
||||
end
|
||||
end
|
||||
alias ls list
|
||||
|
@ -729,7 +729,7 @@ module Net
|
|||
def rename(fromname, toname)
|
||||
resp = sendcmd("RNFR " + fromname)
|
||||
if resp[0] != ?3
|
||||
raise FTPReplyError, resp
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
voidcmd("RNTO " + toname)
|
||||
end
|
||||
|
@ -740,11 +740,11 @@ module Net
|
|||
def delete(filename)
|
||||
resp = sendcmd("DELE " + filename)
|
||||
if resp[0, 3] == "250"
|
||||
return
|
||||
return
|
||||
elsif resp[0] == ?5
|
||||
raise FTPPermError, resp
|
||||
raise FTPPermError, resp
|
||||
else
|
||||
raise FTPReplyError, resp
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -753,14 +753,14 @@ module Net
|
|||
#
|
||||
def chdir(dirname)
|
||||
if dirname == ".."
|
||||
begin
|
||||
voidcmd("CDUP")
|
||||
return
|
||||
rescue FTPPermError => e
|
||||
if e.message[0, 3] != "500"
|
||||
raise e
|
||||
end
|
||||
end
|
||||
begin
|
||||
voidcmd("CDUP")
|
||||
return
|
||||
rescue FTPPermError => e
|
||||
if e.message[0, 3] != "500"
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
cmd = "CWD " + dirname
|
||||
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:
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
def mtime(filename, local = false)
|
||||
str = mdtm(filename)
|
||||
ary = str.scan(MDTM_REGEXP)[0].collect {|i| i.to_i}
|
||||
return local ? Time.local(*ary) : Time.gm(*ary)
|
||||
end
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
def mtime(filename, local = false)
|
||||
str = mdtm(filename)
|
||||
ary = str.scan(MDTM_REGEXP)[0].collect {|i| i.to_i}
|
||||
return local ? Time.local(*ary) : Time.gm(*ary)
|
||||
end
|
||||
|
||||
#
|
||||
# Creates a remote directory.
|
||||
|
@ -821,7 +821,7 @@ module Net
|
|||
def system
|
||||
resp = sendcmd("SYST")
|
||||
if resp[0, 3] != "215"
|
||||
raise FTPReplyError, resp
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
return resp[4 .. -1]
|
||||
end
|
||||
|
@ -835,7 +835,7 @@ module Net
|
|||
@sock.send(line, Socket::MSG_OOB)
|
||||
resp = getmultiline
|
||||
unless ["426", "226", "225"].include?(resp[0, 3])
|
||||
raise FTPProtoError, resp
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
return resp
|
||||
end
|
||||
|
@ -856,7 +856,7 @@ module Net
|
|||
def mdtm(filename)
|
||||
resp = sendcmd("MDTM " + filename)
|
||||
if resp[0, 3] == "213"
|
||||
return resp[3 .. -1].strip
|
||||
return resp[3 .. -1].strip
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -866,7 +866,7 @@ module Net
|
|||
def help(arg = nil)
|
||||
cmd = "HELP"
|
||||
if arg
|
||||
cmd = cmd + " " + arg
|
||||
cmd = cmd + " " + arg
|
||||
end
|
||||
sendcmd(cmd)
|
||||
end
|
||||
|
@ -916,16 +916,16 @@ module Net
|
|||
# Returns host and port.
|
||||
def parse227(resp)
|
||||
if resp[0, 3] != "227"
|
||||
raise FTPReplyError, resp
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
left = resp.index("(")
|
||||
right = resp.index(")")
|
||||
if left == nil or right == nil
|
||||
raise FTPProtoError, resp
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
numbers = resp[left + 1 .. right - 1].split(",")
|
||||
if numbers.length != 6
|
||||
raise FTPProtoError, resp
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
host = numbers[0, 4].join(".")
|
||||
port = (numbers[4].to_i << 8) + numbers[5].to_i
|
||||
|
@ -939,31 +939,31 @@ module Net
|
|||
# Returns host and port.
|
||||
def parse228(resp)
|
||||
if resp[0, 3] != "228"
|
||||
raise FTPReplyError, resp
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
left = resp.index("(")
|
||||
right = resp.index(")")
|
||||
if left == nil or right == nil
|
||||
raise FTPProtoError, resp
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
numbers = resp[left + 1 .. right - 1].split(",")
|
||||
if numbers[0] == "4"
|
||||
if numbers.length != 9 || numbers[1] != "4" || numbers[2 + 4] != "2"
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
host = numbers[2, 4].join(".")
|
||||
port = (numbers[7].to_i << 8) + numbers[8].to_i
|
||||
if numbers.length != 9 || numbers[1] != "4" || numbers[2 + 4] != "2"
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
host = numbers[2, 4].join(".")
|
||||
port = (numbers[7].to_i << 8) + numbers[8].to_i
|
||||
elsif numbers[0] == "6"
|
||||
if numbers.length != 21 || numbers[1] != "16" || numbers[2 + 16] != "2"
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
v6 = ["", "", "", "", "", "", "", ""]
|
||||
for i in 0 .. 7
|
||||
v6[i] = sprintf("%02x%02x", numbers[(i * 2) + 2].to_i,
|
||||
numbers[(i * 2) + 3].to_i)
|
||||
end
|
||||
host = v6[0, 8].join(":")
|
||||
port = (numbers[19].to_i << 8) + numbers[20].to_i
|
||||
if numbers.length != 21 || numbers[1] != "16" || numbers[2 + 16] != "2"
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
v6 = ["", "", "", "", "", "", "", ""]
|
||||
for i in 0 .. 7
|
||||
v6[i] = sprintf("%02x%02x", numbers[(i * 2) + 2].to_i,
|
||||
numbers[(i * 2) + 3].to_i)
|
||||
end
|
||||
host = v6[0, 8].join(":")
|
||||
port = (numbers[19].to_i << 8) + numbers[20].to_i
|
||||
end
|
||||
return host, port
|
||||
end
|
||||
|
@ -975,16 +975,16 @@ module Net
|
|||
# Returns host and port.
|
||||
def parse229(resp)
|
||||
if resp[0, 3] != "229"
|
||||
raise FTPReplyError, resp
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
left = resp.index("(")
|
||||
right = resp.index(")")
|
||||
if left == nil or right == nil
|
||||
raise FTPProtoError, resp
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
numbers = resp[left + 1 .. right - 1].split(resp[left + 1, 1])
|
||||
if numbers.length != 4
|
||||
raise FTPProtoError, resp
|
||||
raise FTPProtoError, resp
|
||||
end
|
||||
port = numbers[3].to_i
|
||||
host = (@sock.peeraddr())[3]
|
||||
|
@ -998,24 +998,24 @@ module Net
|
|||
# Returns host and port.
|
||||
def parse257(resp)
|
||||
if resp[0, 3] != "257"
|
||||
raise FTPReplyError, resp
|
||||
raise FTPReplyError, resp
|
||||
end
|
||||
if resp[3, 2] != ' "'
|
||||
return ""
|
||||
return ""
|
||||
end
|
||||
dirname = ""
|
||||
i = 5
|
||||
n = resp.length
|
||||
while i < n
|
||||
c = resp[i, 1]
|
||||
i = i + 1
|
||||
if c == '"'
|
||||
if i > n or resp[i, 1] != '"'
|
||||
break
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
dirname = dirname + c
|
||||
c = resp[i, 1]
|
||||
i = i + 1
|
||||
if c == '"'
|
||||
if i > n or resp[i, 1] != '"'
|
||||
break
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
dirname = dirname + c
|
||||
end
|
||||
return dirname
|
||||
end
|
||||
|
|
320
lib/net/imap.rb
320
lib/net/imap.rb
|
@ -1091,7 +1091,7 @@ module Net
|
|||
when UntaggedResponse
|
||||
record_response(resp.name, resp.data)
|
||||
if resp.data.instance_of?(ResponseText) &&
|
||||
(code = resp.data.code)
|
||||
(code = resp.data.code)
|
||||
record_response(code.name, code.data)
|
||||
end
|
||||
if resp.name == "BYE" && @logout_command_tag.nil?
|
||||
|
@ -1550,7 +1550,7 @@ module Net
|
|||
def ensure_nz_number(num)
|
||||
if num < -1 || num == 0 || num >= 4294967296
|
||||
msg = "nz_number must be non-zero unsigned 32-bit integer: " +
|
||||
num.inspect
|
||||
num.inspect
|
||||
raise DataFormatError, msg
|
||||
end
|
||||
end
|
||||
|
@ -2032,43 +2032,43 @@ module Net
|
|||
T_TEXT = :TEXT
|
||||
|
||||
BEG_REGEXP = /\G(?:\
|
||||
(?# 1: SPACE )( +)|\
|
||||
(?# 2: NIL )(NIL)(?=[\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+])|\
|
||||
(?# 3: NUMBER )(\d+)(?=[\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+])|\
|
||||
(?# 4: ATOM )([^\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+]+)|\
|
||||
(?# 5: QUOTED )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\
|
||||
(?# 6: LPAR )(\()|\
|
||||
(?# 7: RPAR )(\))|\
|
||||
(?# 8: BSLASH )(\\)|\
|
||||
(?# 9: STAR )(\*)|\
|
||||
(?# 10: LBRA )(\[)|\
|
||||
(?# 11: RBRA )(\])|\
|
||||
(?# 12: LITERAL )\{(\d+)\}\r\n|\
|
||||
(?# 13: PLUS )(\+)|\
|
||||
(?# 14: PERCENT )(%)|\
|
||||
(?# 15: CRLF )(\r\n)|\
|
||||
(?# 16: EOF )(\z))/ni
|
||||
(?# 1: SPACE )( +)|\
|
||||
(?# 2: NIL )(NIL)(?=[\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+])|\
|
||||
(?# 3: NUMBER )(\d+)(?=[\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+])|\
|
||||
(?# 4: ATOM )([^\x80-\xff(){ \x00-\x1f\x7f%*#{'"'}\\\[\]+]+)|\
|
||||
(?# 5: QUOTED )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\
|
||||
(?# 6: LPAR )(\()|\
|
||||
(?# 7: RPAR )(\))|\
|
||||
(?# 8: BSLASH )(\\)|\
|
||||
(?# 9: STAR )(\*)|\
|
||||
(?# 10: LBRA )(\[)|\
|
||||
(?# 11: RBRA )(\])|\
|
||||
(?# 12: LITERAL )\{(\d+)\}\r\n|\
|
||||
(?# 13: PLUS )(\+)|\
|
||||
(?# 14: PERCENT )(%)|\
|
||||
(?# 15: CRLF )(\r\n)|\
|
||||
(?# 16: EOF )(\z))/ni
|
||||
|
||||
DATA_REGEXP = /\G(?:\
|
||||
(?# 1: SPACE )( )|\
|
||||
(?# 2: NIL )(NIL)|\
|
||||
(?# 3: NUMBER )(\d+)|\
|
||||
(?# 4: QUOTED )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\
|
||||
(?# 5: LITERAL )\{(\d+)\}\r\n|\
|
||||
(?# 6: LPAR )(\()|\
|
||||
(?# 7: RPAR )(\)))/ni
|
||||
DATA_REGEXP = /\G(?:\
|
||||
(?# 1: SPACE )( )|\
|
||||
(?# 2: NIL )(NIL)|\
|
||||
(?# 3: NUMBER )(\d+)|\
|
||||
(?# 4: QUOTED )"((?:[^\x00\r\n"\\]|\\["\\])*)"|\
|
||||
(?# 5: LITERAL )\{(\d+)\}\r\n|\
|
||||
(?# 6: LPAR )(\()|\
|
||||
(?# 7: RPAR )(\)))/ni
|
||||
|
||||
TEXT_REGEXP = /\G(?:\
|
||||
(?# 1: TEXT )([^\x00\r\n]*))/ni
|
||||
TEXT_REGEXP = /\G(?:\
|
||||
(?# 1: TEXT )([^\x00\r\n]*))/ni
|
||||
|
||||
RTEXT_REGEXP = /\G(?:\
|
||||
(?# 1: LBRA )(\[)|\
|
||||
(?# 2: TEXT )([^\x00\r\n]*))/ni
|
||||
RTEXT_REGEXP = /\G(?:\
|
||||
(?# 1: LBRA )(\[)|\
|
||||
(?# 2: TEXT )([^\x00\r\n]*))/ni
|
||||
|
||||
CTEXT_REGEXP = /\G(?:\
|
||||
(?# 1: TEXT )([^\x00\r\n\]]*))/ni
|
||||
CTEXT_REGEXP = /\G(?:\
|
||||
(?# 1: TEXT )([^\x00\r\n\]]*))/ni
|
||||
|
||||
Token = Struct.new(:symbol, :value)
|
||||
Token = Struct.new(:symbol, :value)
|
||||
|
||||
def response
|
||||
token = lookahead
|
||||
|
@ -2932,11 +2932,11 @@ module Net
|
|||
end
|
||||
|
||||
ADDRESS_REGEXP = /\G\
|
||||
(?# 1: NAME )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
||||
(?# 2: ROUTE )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
||||
(?# 3: MAILBOX )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
||||
(?# 4: HOST )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)")\
|
||||
\)/ni
|
||||
(?# 1: NAME )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
||||
(?# 2: ROUTE )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
||||
(?# 3: MAILBOX )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)") \
|
||||
(?# 4: HOST )(?:NIL|"((?:[^\x80-\xff\x00\r\n"\\]|\\["\\])*)")\
|
||||
\)/ni
|
||||
|
||||
def address
|
||||
match(T_LPAR)
|
||||
|
@ -2965,62 +2965,62 @@ module Net
|
|||
return Address.new(name, route, mailbox, host)
|
||||
end
|
||||
|
||||
# def flag_list
|
||||
# result = []
|
||||
# match(T_LPAR)
|
||||
# while true
|
||||
# token = lookahead
|
||||
# case token.symbol
|
||||
# when T_RPAR
|
||||
# shift_token
|
||||
# break
|
||||
# when T_SPACE
|
||||
# shift_token
|
||||
# end
|
||||
# result.push(flag)
|
||||
# end
|
||||
# return result
|
||||
# end
|
||||
# def flag_list
|
||||
# result = []
|
||||
# match(T_LPAR)
|
||||
# while true
|
||||
# token = lookahead
|
||||
# case token.symbol
|
||||
# when T_RPAR
|
||||
# shift_token
|
||||
# break
|
||||
# when T_SPACE
|
||||
# shift_token
|
||||
# end
|
||||
# result.push(flag)
|
||||
# end
|
||||
# return result
|
||||
# end
|
||||
|
||||
# def flag
|
||||
# token = lookahead
|
||||
# if token.symbol == T_BSLASH
|
||||
# shift_token
|
||||
# token = lookahead
|
||||
# if token.symbol == T_STAR
|
||||
# shift_token
|
||||
# return token.value.intern
|
||||
# else
|
||||
# return atom.intern
|
||||
# end
|
||||
# else
|
||||
# return atom
|
||||
# end
|
||||
# end
|
||||
# def flag
|
||||
# token = lookahead
|
||||
# if token.symbol == T_BSLASH
|
||||
# shift_token
|
||||
# token = lookahead
|
||||
# if token.symbol == T_STAR
|
||||
# shift_token
|
||||
# return token.value.intern
|
||||
# else
|
||||
# return atom.intern
|
||||
# end
|
||||
# else
|
||||
# return atom
|
||||
# end
|
||||
# end
|
||||
|
||||
FLAG_REGEXP = /\
|
||||
(?# FLAG )\\([^\x80-\xff(){ \x00-\x1f\x7f%"\\]+)|\
|
||||
(?# ATOM )([^\x80-\xff(){ \x00-\x1f\x7f%*"\\]+)/n
|
||||
(?# FLAG )\\([^\x80-\xff(){ \x00-\x1f\x7f%"\\]+)|\
|
||||
(?# ATOM )([^\x80-\xff(){ \x00-\x1f\x7f%*"\\]+)/n
|
||||
|
||||
def flag_list
|
||||
if @str.index(/\(([^)]*)\)/ni, @pos)
|
||||
@pos = $~.end(0)
|
||||
return $1.scan(FLAG_REGEXP).collect { |flag, atom|
|
||||
if atom
|
||||
atom
|
||||
else
|
||||
symbol = flag.capitalize.untaint.intern
|
||||
@flag_symbols[symbol] = true
|
||||
if @flag_symbols.length > IMAP.max_flag_count
|
||||
raise FlagCountError, "number of flag symbols exceeded"
|
||||
def flag_list
|
||||
if @str.index(/\(([^)]*)\)/ni, @pos)
|
||||
@pos = $~.end(0)
|
||||
return $1.scan(FLAG_REGEXP).collect { |flag, atom|
|
||||
if atom
|
||||
atom
|
||||
else
|
||||
symbol = flag.capitalize.untaint.intern
|
||||
@flag_symbols[symbol] = true
|
||||
if @flag_symbols.length > IMAP.max_flag_count
|
||||
raise FlagCountError, "number of flag symbols exceeded"
|
||||
end
|
||||
symbol
|
||||
end
|
||||
}
|
||||
else
|
||||
parse_error("invalid flag list")
|
||||
end
|
||||
symbol
|
||||
end
|
||||
}
|
||||
else
|
||||
parse_error("invalid flag list")
|
||||
end
|
||||
end
|
||||
|
||||
def nstring
|
||||
token = lookahead
|
||||
|
@ -3347,73 +3347,73 @@ module Net
|
|||
# #authenticate().
|
||||
class DigestMD5Authenticator
|
||||
def process(challenge)
|
||||
case @stage
|
||||
when STAGE_ONE
|
||||
@stage = STAGE_TWO
|
||||
sparams = {}
|
||||
c = StringScanner.new(challenge)
|
||||
while c.scan(/(?:\s*,)?\s*(\w+)=("(?:[^\\"]+|\\.)*"|[^,]+)\s*/)
|
||||
k, v = c[1], c[2]
|
||||
if v =~ /^"(.*)"$/
|
||||
v = $1
|
||||
if v =~ /,/
|
||||
v = v.split(',')
|
||||
end
|
||||
end
|
||||
sparams[k] = v
|
||||
end
|
||||
case @stage
|
||||
when STAGE_ONE
|
||||
@stage = STAGE_TWO
|
||||
sparams = {}
|
||||
c = StringScanner.new(challenge)
|
||||
while c.scan(/(?:\s*,)?\s*(\w+)=("(?:[^\\"]+|\\.)*"|[^,]+)\s*/)
|
||||
k, v = c[1], c[2]
|
||||
if v =~ /^"(.*)"$/
|
||||
v = $1
|
||||
if v =~ /,/
|
||||
v = v.split(',')
|
||||
end
|
||||
end
|
||||
sparams[k] = v
|
||||
end
|
||||
|
||||
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 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")
|
||||
|
||||
response = {
|
||||
:nonce => sparams['nonce'],
|
||||
:username => @user,
|
||||
:realm => sparams['realm'],
|
||||
:cnonce => Digest::MD5.hexdigest("%.15f:%.15f:%d" % [Time.now.to_f, rand, Process.pid.to_s]),
|
||||
:'digest-uri' => 'imap/' + sparams['realm'],
|
||||
:qop => 'auth',
|
||||
:maxbuf => 65535,
|
||||
:nc => "%08d" % nc(sparams['nonce']),
|
||||
:charset => sparams['charset'],
|
||||
}
|
||||
response = {
|
||||
:nonce => sparams['nonce'],
|
||||
:username => @user,
|
||||
:realm => sparams['realm'],
|
||||
:cnonce => Digest::MD5.hexdigest("%.15f:%.15f:%d" % [Time.now.to_f, rand, Process.pid.to_s]),
|
||||
:'digest-uri' => 'imap/' + sparams['realm'],
|
||||
:qop => 'auth',
|
||||
:maxbuf => 65535,
|
||||
:nc => "%08d" % nc(sparams['nonce']),
|
||||
:charset => sparams['charset'],
|
||||
}
|
||||
|
||||
response[:authzid] = @authname unless @authname.nil?
|
||||
response[:authzid] = @authname unless @authname.nil?
|
||||
|
||||
# now, the real thing
|
||||
a0 = Digest::MD5.digest( [ response.values_at(:username, :realm), @password ].join(':') )
|
||||
# now, the real thing
|
||||
a0 = Digest::MD5.digest( [ response.values_at(:username, :realm), @password ].join(':') )
|
||||
|
||||
a1 = [ a0, response.values_at(:nonce,:cnonce) ].join(':')
|
||||
a1 << ':' + response[:authzid] unless response[:authzid].nil?
|
||||
a1 = [ a0, response.values_at(:nonce,:cnonce) ].join(':')
|
||||
a1 << ':' + response[:authzid] unless response[:authzid].nil?
|
||||
|
||||
a2 = "AUTHENTICATE:" + response[:'digest-uri']
|
||||
a2 << ":00000000000000000000000000000000" if response[:qop] and response[:qop] =~ /^auth-(?:conf|int)$/
|
||||
a2 = "AUTHENTICATE:" + response[:'digest-uri']
|
||||
a2 << ":00000000000000000000000000000000" if response[:qop] and response[:qop] =~ /^auth-(?:conf|int)$/
|
||||
|
||||
response[:response] = Digest::MD5.hexdigest(
|
||||
[
|
||||
Digest::MD5.hexdigest(a1),
|
||||
response.values_at(:nonce, :nc, :cnonce, :qop),
|
||||
Digest::MD5.hexdigest(a2)
|
||||
].join(':')
|
||||
)
|
||||
response[:response] = Digest::MD5.hexdigest(
|
||||
[
|
||||
Digest::MD5.hexdigest(a1),
|
||||
response.values_at(:nonce, :nc, :cnonce, :qop),
|
||||
Digest::MD5.hexdigest(a2)
|
||||
].join(':')
|
||||
)
|
||||
|
||||
return response.keys.map {|key| qdval(key.to_s, response[key]) }.join(',')
|
||||
when STAGE_TWO
|
||||
@stage = nil
|
||||
# if at the second stage, return an empty string
|
||||
if challenge =~ /rspauth=/
|
||||
return ''
|
||||
else
|
||||
raise ResponseParseError, challenge
|
||||
end
|
||||
else
|
||||
raise ResponseParseError, challenge
|
||||
end
|
||||
return response.keys.map {|key| qdval(key.to_s, response[key]) }.join(',')
|
||||
when STAGE_TWO
|
||||
@stage = nil
|
||||
# if at the second stage, return an empty string
|
||||
if challenge =~ /rspauth=/
|
||||
return ''
|
||||
else
|
||||
raise ResponseParseError, challenge
|
||||
end
|
||||
else
|
||||
raise ResponseParseError, challenge
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(user, password, authname = nil)
|
||||
@user, @password, @authname = user, password, authname
|
||||
@nc, @stage = {}, STAGE_ONE
|
||||
@user, @password, @authname = user, password, authname
|
||||
@nc, @stage = {}, STAGE_ONE
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -3422,23 +3422,23 @@ module Net
|
|||
STAGE_TWO = :stage_two
|
||||
|
||||
def nc(nonce)
|
||||
if @nc.has_key? nonce
|
||||
@nc[nonce] = @nc[nonce] + 1
|
||||
else
|
||||
@nc[nonce] = 1
|
||||
end
|
||||
return @nc[nonce]
|
||||
if @nc.has_key? nonce
|
||||
@nc[nonce] = @nc[nonce] + 1
|
||||
else
|
||||
@nc[nonce] = 1
|
||||
end
|
||||
return @nc[nonce]
|
||||
end
|
||||
|
||||
# some responses need quoting
|
||||
def qdval(k, v)
|
||||
return if k.nil? or v.nil?
|
||||
if %w"username authzid realm nonce cnonce digest-uri qop".include? k
|
||||
v.gsub!(/([\\"])/, "\\\1")
|
||||
return '%s="%s"' % [k, v]
|
||||
else
|
||||
return '%s=%s' % [k, v]
|
||||
end
|
||||
return if k.nil? or v.nil?
|
||||
if %w"username authzid realm nonce cnonce digest-uri qop".include? k
|
||||
v.gsub!(/([\\"])/, "\\\1")
|
||||
return '%s="%s"' % [k, v]
|
||||
else
|
||||
return '%s=%s' % [k, v]
|
||||
end
|
||||
end
|
||||
end
|
||||
add_authenticator "DIGEST-MD5", DigestMD5Authenticator
|
||||
|
@ -3514,7 +3514,7 @@ usage: #{$0} [options] <host>
|
|||
--auth=AUTH specifies auth type
|
||||
--starttls use starttls
|
||||
--ssl use ssl
|
||||
EOF
|
||||
EOF
|
||||
end
|
||||
|
||||
begin
|
||||
|
@ -3649,7 +3649,7 @@ summary display summary
|
|||
fetch [msgno] display message
|
||||
logout logout
|
||||
help, ? display help message
|
||||
EOF
|
||||
EOF
|
||||
else
|
||||
print "unknown command: ", cmd, "\n"
|
||||
end
|
||||
|
|
|
@ -433,18 +433,18 @@ module Net
|
|||
# combine CR+NULL into CR
|
||||
string = string.gsub(/#{CR}#{NULL}/no, CR) if @options["Telnetmode"]
|
||||
|
||||
# combine EOL into "\n"
|
||||
string = string.gsub(/#{EOL}/no, "\n") unless @options["Binmode"]
|
||||
# combine EOL into "\n"
|
||||
string = string.gsub(/#{EOL}/no, "\n") unless @options["Binmode"]
|
||||
|
||||
# remove NULL
|
||||
string = string.gsub(/#{NULL}/no, '') unless @options["Binmode"]
|
||||
# remove NULL
|
||||
string = string.gsub(/#{NULL}/no, '') unless @options["Binmode"]
|
||||
|
||||
string.gsub(/#{IAC}(
|
||||
[#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|
|
||||
[#{DO}#{DONT}#{WILL}#{WONT}]
|
||||
[#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]|
|
||||
#{SB}[^#{IAC}]*#{IAC}#{SE}
|
||||
)/xno) do
|
||||
string.gsub(/#{IAC}(
|
||||
[#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]|
|
||||
[#{DO}#{DONT}#{WILL}#{WONT}]
|
||||
[#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]|
|
||||
#{SB}[^#{IAC}]*#{IAC}#{SE}
|
||||
)/xno) do
|
||||
if IAC == $1 # handle escaped IAC characters
|
||||
IAC
|
||||
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"
|
||||
if OPT_BINARY[0] == $1[1]
|
||||
self.write(IAC + DO + OPT_BINARY)
|
||||
elsif OPT_ECHO[0] == $1[1]
|
||||
self.write(IAC + DO + OPT_ECHO)
|
||||
elsif OPT_SGA[0] == $1[1]
|
||||
@telnet_option["SGA"] = true
|
||||
self.write(IAC + DO + OPT_SGA)
|
||||
else
|
||||
self.write(IAC + DONT + $1[1..1])
|
||||
end
|
||||
''
|
||||
elsif WONT[0] == $1[0] # respond to "IAC WON'T x"
|
||||
if OPT_ECHO[0] == $1[1]
|
||||
self.write(IAC + DONT + OPT_ECHO)
|
||||
elsif OPT_SGA[0] == $1[1]
|
||||
@telnet_option["SGA"] = false
|
||||
self.write(IAC + DONT + OPT_SGA)
|
||||
else
|
||||
self.write(IAC + DONT + $1[1..1])
|
||||
end
|
||||
''
|
||||
else
|
||||
''
|
||||
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 = ''
|
||||
elsif OPT_ECHO[0] == $1[1]
|
||||
self.write(IAC + DO + OPT_ECHO)
|
||||
elsif OPT_SGA[0] == $1[1]
|
||||
@telnet_option["SGA"] = true
|
||||
self.write(IAC + DO + OPT_SGA)
|
||||
else
|
||||
self.write(IAC + DONT + $1[1..1])
|
||||
end
|
||||
''
|
||||
elsif WONT[0] == $1[0] # respond to "IAC WON'T x"
|
||||
if OPT_ECHO[0] == $1[1]
|
||||
self.write(IAC + DONT + OPT_ECHO)
|
||||
elsif OPT_SGA[0] == $1[1]
|
||||
@telnet_option["SGA"] = false
|
||||
self.write(IAC + DONT + OPT_SGA)
|
||||
else
|
||||
self.write(IAC + DONT + $1[1..1])
|
||||
end
|
||||
''
|
||||
else
|
||||
''
|
||||
end
|
||||
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 # 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
|
||||
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
|
||||
@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?
|
||||
|
||||
# Write +string+ to the host.
|
||||
#
|
||||
# Does not perform any conversions on +string+. Will log +string+ to the
|
||||
# dumplog, if the Dump_log option is set.
|
||||
def write(string)
|
||||
length = string.length
|
||||
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
|
||||
break
|
||||
end
|
||||
end
|
||||
line
|
||||
end
|
||||
|
||||
# Write +string+ to the host.
|
||||
#
|
||||
# Does not perform any conversions on +string+. Will log +string+ to the
|
||||
# dumplog, if the Dump_log option is set.
|
||||
def write(string)
|
||||
length = string.length
|
||||
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
|
||||
# Sends a string to the host.
|
||||
#
|
||||
# This does _not_ automatically append a newline to the string. Embedded
|
||||
# newlines may be converted and telnet command sequences escaped
|
||||
# depending upon the values of telnetmode, binmode, and telnet options
|
||||
# set by the host.
|
||||
def print(string)
|
||||
string = string.gsub(/#{IAC}/no, IAC + IAC) if @options["Telnetmode"]
|
||||
|
||||
# Sends a string to the host.
|
||||
#
|
||||
# This does _not_ automatically append a newline to the string. Embedded
|
||||
# newlines may be converted and telnet command sequences escaped
|
||||
# depending upon the values of telnetmode, binmode, and telnet options
|
||||
# set by the host.
|
||||
def print(string)
|
||||
string = string.gsub(/#{IAC}/no, IAC + IAC) if @options["Telnetmode"]
|
||||
if @options["Binmode"]
|
||||
self.write(string)
|
||||
else
|
||||
if @telnet_option["BINARY"] and @telnet_option["SGA"]
|
||||
# IAC WILL SGA IAC DO BIN send EOL --> CR
|
||||
self.write(string.gsub(/\n/n, CR))
|
||||
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
|
||||
|
||||
if @options["Binmode"]
|
||||
self.write(string)
|
||||
else
|
||||
if @telnet_option["BINARY"] and @telnet_option["SGA"]
|
||||
# IAC WILL SGA IAC DO BIN send EOL --> CR
|
||||
self.write(string.gsub(/\n/n, CR))
|
||||
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.
|
||||
#
|
||||
# Same as #print(), but appends a newline to the string.
|
||||
def puts(string)
|
||||
self.print(string + "\n")
|
||||
end
|
||||
|
||||
# Sends a string to the host.
|
||||
#
|
||||
# Same as #print(), but appends a newline to the string.
|
||||
def puts(string)
|
||||
self.print(string + "\n")
|
||||
end
|
||||
# Send a command to the host.
|
||||
#
|
||||
# More exactly, sends a string to the host, and reads in all received
|
||||
# data until is sees the prompt or other matched sequence.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# More exactly, sends a string to the host, and reads in all received
|
||||
# data until is sees the prompt or other matched sequence.
|
||||
#
|
||||
# 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"]
|
||||
if options.kind_of?(Hash)
|
||||
string = options["String"]
|
||||
match = options["Match"] if options.has_key?("Match")
|
||||
time_out = options["Timeout"] if options.has_key?("Timeout")
|
||||
fail_eof = options["FailEOF"] if options.has_key?("FailEOF")
|
||||
else
|
||||
string = options
|
||||
end
|
||||
|
||||
if options.kind_of?(Hash)
|
||||
string = options["String"]
|
||||
match = options["Match"] if options.has_key?("Match")
|
||||
time_out = options["Timeout"] if options.has_key?("Timeout")
|
||||
fail_eof = options["FailEOF"] if options.has_key?("FailEOF")
|
||||
else
|
||||
string = options
|
||||
end
|
||||
self.puts(string)
|
||||
if block_given?
|
||||
waitfor({"Prompt" => match, "Timeout" => time_out, "FailEOF" => fail_eof}){|c| yield c }
|
||||
else
|
||||
waitfor({"Prompt" => match, "Timeout" => time_out, "FailEOF" => fail_eof})
|
||||
end
|
||||
end
|
||||
|
||||
self.puts(string)
|
||||
if block_given?
|
||||
waitfor({"Prompt" => match, "Timeout" => time_out, "FailEOF" => fail_eof}){|c| yield c }
|
||||
else
|
||||
waitfor({"Prompt" => match, "Timeout" => time_out, "FailEOF" => fail_eof})
|
||||
end
|
||||
end
|
||||
# Login to the host with a given username and password.
|
||||
#
|
||||
# The username and password can either be provided as two string
|
||||
# arguments in that order, or as a hash with keys "Name" and
|
||||
# "Password".
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# The username and password can either be provided as two string
|
||||
# arguments in that order, or as a hash with keys "Name" and
|
||||
# "Password".
|
||||
#
|
||||
# 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
|
||||
if block_given?
|
||||
line = waitfor(login_prompt){|c| yield c }
|
||||
if password
|
||||
line += cmd({"String" => username,
|
||||
"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
|
||||
|
||||
if block_given?
|
||||
line = waitfor(login_prompt){|c| yield c }
|
||||
if password
|
||||
line += cmd({"String" => username,
|
||||
"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
|
||||
def close
|
||||
@sock.close
|
||||
end
|
||||
|
||||
# Closes the connection
|
||||
def close
|
||||
@sock.close
|
||||
end
|
||||
|
||||
end # class Telnet
|
||||
end # module Net
|
||||
end # class Telnet
|
||||
end # module Net
|
||||
|
||||
|
|
|
@ -205,9 +205,9 @@ module Open3
|
|||
result = [*parent_io, wait_thr]
|
||||
if defined? yield
|
||||
begin
|
||||
return yield(*result)
|
||||
return yield(*result)
|
||||
ensure
|
||||
parent_io.each{|io| io.close unless io.closed?}
|
||||
parent_io.each{|io| io.close unless io.closed?}
|
||||
wait_thr.join
|
||||
end
|
||||
end
|
||||
|
@ -700,9 +700,9 @@ module Open3
|
|||
child_io.each {|io| io.close }
|
||||
if defined? yield
|
||||
begin
|
||||
return yield(*result)
|
||||
return yield(*result)
|
||||
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 }
|
||||
end
|
||||
end
|
||||
|
|
752
lib/prime.rb
752
lib/prime.rb
|
@ -99,397 +99,397 @@ class Prime
|
|||
|
||||
def method_added(method) # :nodoc:
|
||||
(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
|
||||
|
||||
# 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
|
||||
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
|
||||
|
||||
# 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
|
||||
}
|
||||
def upper_bound=(ubound)
|
||||
@ubound = ubound
|
||||
end
|
||||
def upper_bound
|
||||
@ubound
|
||||
end
|
||||
|
||||
# Returns the factorization of +value+.
|
||||
# returns the next pseudo-prime number, and move the internal
|
||||
# position forward.
|
||||
#
|
||||
# == 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.
|
||||
# +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.
|
||||
#
|
||||
# === 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]]
|
||||
# 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
|
||||
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
|
||||
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
|
||||
block.call(succ)
|
||||
end
|
||||
end
|
||||
alias next succ
|
||||
def rewind
|
||||
initialize
|
||||
end
|
||||
end
|
||||
|
||||
# see +Enumerator+#with_index.
|
||||
alias with_index each_with_index
|
||||
|
||||
|
||||
|
||||
# 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
|
||||
# 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
|
||||
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 = ']]>'
|
||||
ILLEGAL = /(\]\]>)/
|
||||
|
||||
# Constructor. CData is data between <![CDATA[ ... ]]>
|
||||
#
|
||||
# _Examples_
|
||||
# CData.new( source )
|
||||
# CData.new( "Here is some CDATA" )
|
||||
# CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element )
|
||||
def initialize( first, whitespace=true, parent=nil )
|
||||
super( first, whitespace, parent, false, true, ILLEGAL )
|
||||
end
|
||||
# Constructor. CData is data between <![CDATA[ ... ]]>
|
||||
#
|
||||
# _Examples_
|
||||
# CData.new( source )
|
||||
# CData.new( "Here is some CDATA" )
|
||||
# CData.new( "Some unprocessed data", respect_whitespace_TF, parent_element )
|
||||
def initialize( first, whitespace=true, parent=nil )
|
||||
super( first, whitespace, parent, false, true, ILLEGAL )
|
||||
end
|
||||
|
||||
# Make a copy of this object
|
||||
#
|
||||
|
|
|
@ -7,7 +7,7 @@ module REXML
|
|||
# class directly.
|
||||
class Child
|
||||
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
|
||||
# sure this method is called.
|
||||
|
|
|
@ -38,15 +38,15 @@ module REXML
|
|||
# See REXML::Formatters
|
||||
#
|
||||
# output::
|
||||
# Where to write the string
|
||||
# Where to write the string
|
||||
# indent::
|
||||
# An integer. If -1, no indenting will be used; otherwise, the
|
||||
# indentation will be this number of spaces, and children will be
|
||||
# indented an additional amount.
|
||||
# An integer. If -1, no indenting will be used; otherwise, the
|
||||
# indentation will be this number of spaces, and children will be
|
||||
# indented an additional amount.
|
||||
# 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::
|
||||
# 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 )
|
||||
Kernel.warn("Comment.write is deprecated. See REXML::Formatters")
|
||||
indent( output, indent )
|
||||
|
|
|
@ -165,7 +165,7 @@ module REXML
|
|||
# Document.new("<a><b/></a>").serialize( tr )
|
||||
#
|
||||
# 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.
|
||||
# indent::
|
||||
# An integer. If -1, no indenting will be used; otherwise, the
|
||||
|
@ -188,15 +188,15 @@ module REXML
|
|||
output = Output.new( output, xml_decl.encoding )
|
||||
end
|
||||
formatter = if indent > -1
|
||||
if transitive
|
||||
require "rexml/formatters/transitive"
|
||||
REXML::Formatters::Transitive.new( indent, ie_hack )
|
||||
else
|
||||
REXML::Formatters::Pretty.new( indent, ie_hack )
|
||||
end
|
||||
else
|
||||
REXML::Formatters::Default.new( ie_hack )
|
||||
end
|
||||
if transitive
|
||||
require "rexml/formatters/transitive"
|
||||
REXML::Formatters::Transitive.new( indent, ie_hack )
|
||||
else
|
||||
REXML::Formatters::Pretty.new( indent, ie_hack )
|
||||
end
|
||||
else
|
||||
REXML::Formatters::Default.new( ie_hack )
|
||||
end
|
||||
formatter.write( self, output )
|
||||
end
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ module REXML
|
|||
class Element < Parent
|
||||
include Namespace
|
||||
|
||||
UNDEFINED = "UNDEFINED"; # The default name
|
||||
UNDEFINED = "UNDEFINED"; # The default name
|
||||
|
||||
# Mechanisms for accessing attributes and child elements of this
|
||||
# element.
|
||||
|
@ -31,17 +31,17 @@ module REXML
|
|||
|
||||
# Constructor
|
||||
# arg::
|
||||
# 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 an Element, the object will be shallowly cloned; name,
|
||||
# attributes, and namespaces will be copied. Children will +not+ be
|
||||
# copied.
|
||||
# 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 an Element, the object will be shallowly cloned; name,
|
||||
# attributes, and namespaces will be copied. Children will +not+ be
|
||||
# copied.
|
||||
# parent::
|
||||
# if supplied, must be a Parent, and will be used as
|
||||
# the parent of this object.
|
||||
# if supplied, must be a Parent, and will be used as
|
||||
# the parent of this object.
|
||||
# context::
|
||||
# If supplied, must be a hash containing context items. Context items
|
||||
# include:
|
||||
# If supplied, must be a hash containing context items. Context items
|
||||
# include:
|
||||
# * <tt>:respect_whitespace</tt> the value of this is :+all+ or an array of
|
||||
# strings being the names of the elements to respect
|
||||
# whitespace for. Defaults to :+all+.
|
||||
|
@ -297,7 +297,7 @@ module REXML
|
|||
el = @elements.add(element)
|
||||
attrs.each do |key, value|
|
||||
el.attributes[key]=value
|
||||
end if attrs.kind_of? Hash
|
||||
end if attrs.kind_of? Hash
|
||||
el
|
||||
end
|
||||
|
||||
|
@ -667,7 +667,7 @@ module REXML
|
|||
#
|
||||
# Writes out this element, and recursively, all children.
|
||||
# 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.
|
||||
# indent::
|
||||
# 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)
|
||||
Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters")
|
||||
formatter = if indent > -1
|
||||
if transitive
|
||||
require "rexml/formatters/transitive"
|
||||
REXML::Formatters::Transitive.new( indent, ie_hack )
|
||||
else
|
||||
REXML::Formatters::Pretty.new( indent, ie_hack )
|
||||
end
|
||||
else
|
||||
REXML::Formatters::Default.new( ie_hack )
|
||||
end
|
||||
if transitive
|
||||
require "rexml/formatters/transitive"
|
||||
REXML::Formatters::Transitive.new( indent, ie_hack )
|
||||
else
|
||||
REXML::Formatters::Pretty.new( indent, ie_hack )
|
||||
end
|
||||
else
|
||||
REXML::Formatters::Default.new( ie_hack )
|
||||
end
|
||||
formatter.write( self, output )
|
||||
end
|
||||
|
||||
|
@ -778,7 +778,7 @@ module REXML
|
|||
else
|
||||
return XPath::first( @element, index )
|
||||
#{ |element|
|
||||
# return element if element.kind_of? Element
|
||||
# return element if element.kind_of? Element
|
||||
#}
|
||||
#return nil
|
||||
end
|
||||
|
@ -1086,7 +1086,7 @@ module REXML
|
|||
# doc.root.attributes['foo'] = '4'
|
||||
# doc.root.attributes['x:foo'] = nil
|
||||
def []=( name, value )
|
||||
if value.nil? # Delete the named attribute
|
||||
if value.nil? # Delete the named attribute
|
||||
attr = get_attribute(name)
|
||||
delete attr
|
||||
return
|
||||
|
@ -1116,8 +1116,8 @@ module REXML
|
|||
value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
|
||||
@element.namespace( old_attr.prefix ) ==
|
||||
@element.namespace( value.prefix )
|
||||
store value.name, { old_attr.prefix => old_attr,
|
||||
value.prefix => value }
|
||||
store value.name, { old_attr.prefix => old_attr,
|
||||
value.prefix => value }
|
||||
else
|
||||
store value.name, value
|
||||
end
|
||||
|
@ -1236,7 +1236,7 @@ module REXML
|
|||
( !namespace.empty? || !attribute.fully_expanded_name.index(':') )
|
||||
# foo will match xmlns:foo, but only if foo isn't also an attribute
|
||||
result = attribute if !result or !namespace.empty? or
|
||||
!attribute.fully_expanded_name.index(':')
|
||||
!attribute.fully_expanded_name.index(':')
|
||||
end
|
||||
}
|
||||
result
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
require 'rexml/xmltokens'
|
||||
|
||||
# [ :element, parent, name, attributes, children* ]
|
||||
# a = Node.new
|
||||
# a << "B" # => <a>B</a>
|
||||
# a.b # => <a>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[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 = Node.new
|
||||
# a << "B" # => <a>B</a>
|
||||
# a.b # => <a>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[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>
|
||||
module REXML
|
||||
module Light
|
||||
# Represents a tagged XML element. Elements are characterized by
|
||||
|
|
|
@ -36,12 +36,12 @@ module REXML
|
|||
end
|
||||
|
||||
def indent to, ind
|
||||
if @parent and @parent.context and not @parent.context[:indentstyle].nil? then
|
||||
indentstyle = @parent.context[:indentstyle]
|
||||
else
|
||||
indentstyle = ' '
|
||||
end
|
||||
to << indentstyle*ind unless ind<1
|
||||
if @parent and @parent.context and not @parent.context[:indentstyle].nil? then
|
||||
indentstyle = @parent.context[:indentstyle]
|
||||
else
|
||||
indentstyle = ' '
|
||||
end
|
||||
to << indentstyle*ind unless ind<1
|
||||
end
|
||||
|
||||
def parent?
|
||||
|
|
|
@ -44,10 +44,10 @@ module REXML
|
|||
end
|
||||
|
||||
# An element is an array. The array contains:
|
||||
# 0 The parent element
|
||||
# 1 The tag name
|
||||
# 2 A hash of attributes
|
||||
# 3..-1 The child elements
|
||||
# 0 The parent element
|
||||
# 1 The tag name
|
||||
# 2 A hash of attributes
|
||||
# 3..-1 The child elements
|
||||
# An element is an array of size > 3
|
||||
# Text is a String
|
||||
# PIs are [ :processing_instruction, target, data ]
|
||||
|
|
|
@ -28,15 +28,15 @@ module REXML
|
|||
# Listen arguments:
|
||||
#
|
||||
# Symbol, Array, Block
|
||||
# Listen to Symbol events on Array elements
|
||||
# Listen to Symbol events on Array elements
|
||||
# Symbol, Block
|
||||
# Listen to Symbol events
|
||||
# Array, Listener
|
||||
# Listen to all events on Array elements
|
||||
# Listen to all events on Array elements
|
||||
# Array, Block
|
||||
# Listen to :start_element events on Array elements
|
||||
# Listen to :start_element events on Array elements
|
||||
# Listener
|
||||
# Listen to All events
|
||||
# Listen to All events
|
||||
#
|
||||
# Symbol can be one of: :start_element, :end_element,
|
||||
# :start_prefix_mapping, :end_prefix_mapping, :characters,
|
||||
|
@ -209,7 +209,7 @@ module REXML
|
|||
((name.nil? and match.nil?) or match.nil? or (
|
||||
(name == match) or
|
||||
(match.kind_of? Regexp and name =~ match)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
end.collect{|x| x[-1]}
|
||||
|
@ -222,7 +222,7 @@ module REXML
|
|||
((name.nil? and match.nil?) or match.nil? or (
|
||||
(name == match) or
|
||||
(match.kind_of? Regexp and name =~ match)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
end.collect{|x| x[-1]}
|
||||
|
|
|
@ -42,10 +42,10 @@ module REXML
|
|||
end
|
||||
|
||||
# An element is an array. The array contains:
|
||||
# 0 The parent element
|
||||
# 1 The tag name
|
||||
# 2 A hash of attributes
|
||||
# 3..-1 The child elements
|
||||
# 0 The parent element
|
||||
# 1 The tag name
|
||||
# 2 A hash of attributes
|
||||
# 3..-1 The child elements
|
||||
# An element is an array of size > 3
|
||||
# Text is a String
|
||||
# PIs are [ :processing_instruction, target, data ]
|
||||
|
|
|
@ -49,20 +49,20 @@ module REXML
|
|||
def QuickPath::filter elements, path
|
||||
return elements if path.nil? or path == '' or elements.size == 0
|
||||
case path
|
||||
when /^\/\//u # Descendant
|
||||
when /^\/\//u # Descendant
|
||||
return axe( elements, "descendant-or-self", $' )
|
||||
when /^\/?\b(\w[-\w]*)\b::/u # Axe
|
||||
when /^\/?\b(\w[-\w]*)\b::/u # Axe
|
||||
return axe( elements, $1, $' )
|
||||
when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child
|
||||
rest = $'
|
||||
results = []
|
||||
elements.each do |element|
|
||||
results |= filter( element.to_a, rest )
|
||||
end
|
||||
return results
|
||||
when /^\/?(\w[-\w]*)\(/u # / Function
|
||||
return function( elements, $1, $' )
|
||||
when Namespace::NAMESPLIT # Element name
|
||||
when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child
|
||||
rest = $'
|
||||
results = []
|
||||
elements.each do |element|
|
||||
results |= filter( element.to_a, rest )
|
||||
end
|
||||
return results
|
||||
when /^\/?(\w[-\w]*)\(/u # / Function
|
||||
return function( elements, $1, $' )
|
||||
when Namespace::NAMESPLIT # Element name
|
||||
name = $2
|
||||
ns = $1
|
||||
rest = $'
|
||||
|
@ -79,22 +79,22 @@ module REXML
|
|||
matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element
|
||||
end
|
||||
return matches
|
||||
when /^\[/u # Predicate
|
||||
when /^\[/u # Predicate
|
||||
return predicate( elements, path )
|
||||
when /^\/?\.\.\./u # Ancestor
|
||||
when /^\/?\.\.\./u # Ancestor
|
||||
return axe( elements, "ancestor", $' )
|
||||
when /^\/?\.\./u # Parent
|
||||
when /^\/?\.\./u # Parent
|
||||
return filter( elements.collect{|e|e.parent}, $' )
|
||||
when /^\/?\./u # Self
|
||||
when /^\/?\./u # Self
|
||||
return filter( elements, $' )
|
||||
when /^\*/u # Any
|
||||
when /^\*/u # Any
|
||||
results = []
|
||||
elements.each do |element|
|
||||
results |= filter( [element], $' ) if element.kind_of? Element
|
||||
#if element.kind_of? Element
|
||||
# children = element.to_a
|
||||
# children.delete_if { |child| !child.kind_of?(Element) }
|
||||
# results |= filter( children, $' )
|
||||
# children = element.to_a
|
||||
# children.delete_if { |child| !child.kind_of?(Element) }
|
||||
# results |= filter( children, $' )
|
||||
#end
|
||||
end
|
||||
return results
|
||||
|
@ -132,7 +132,7 @@ module REXML
|
|||
matches = filter(elements.collect{|element| element.parent}.uniq, rest)
|
||||
when "following-sibling"
|
||||
matches = filter(elements.collect{|element| element.next_sibling}.uniq,
|
||||
rest)
|
||||
rest)
|
||||
when "previous-sibling"
|
||||
matches = filter(elements.collect{|element|
|
||||
element.previous_sibling}.uniq, rest )
|
||||
|
@ -174,32 +174,32 @@ module REXML
|
|||
predicate.gsub!(
|
||||
/#{OPERAND_}\s*([<>=])\s*#{OPERAND_}\s*([<>=])\s*#{OPERAND_}/u,
|
||||
'\1 \2 \3 and \3 \4 \5' )
|
||||
# Let's do some Ruby trickery to avoid some work:
|
||||
predicate.gsub!( /&/u, "&&" )
|
||||
predicate.gsub!( /=/u, "==" )
|
||||
predicate.gsub!( /@(\w[-\w.]*)/u, 'attribute("\1")' )
|
||||
predicate.gsub!( /\bmod\b/u, "%" )
|
||||
predicate.gsub!( /\b(\w[-\w.]*\()/u ) {
|
||||
fname = $1
|
||||
fname.gsub( /-/u, "_" )
|
||||
}
|
||||
# Let's do some Ruby trickery to avoid some work:
|
||||
predicate.gsub!( /&/u, "&&" )
|
||||
predicate.gsub!( /=/u, "==" )
|
||||
predicate.gsub!( /@(\w[-\w.]*)/u, 'attribute("\1")' )
|
||||
predicate.gsub!( /\bmod\b/u, "%" )
|
||||
predicate.gsub!( /\b(\w[-\w.]*\()/u ) {
|
||||
fname = $1
|
||||
fname.gsub( /-/u, "_" )
|
||||
}
|
||||
|
||||
Functions.pair = [ 0, elements.size ]
|
||||
results = []
|
||||
elements.each do |element|
|
||||
Functions.pair[0] += 1
|
||||
Functions.node = element
|
||||
res = eval( predicate )
|
||||
case res
|
||||
when true
|
||||
results << element
|
||||
when Fixnum
|
||||
results << element if Functions.pair[0] == res
|
||||
when String
|
||||
results << element
|
||||
Functions.pair = [ 0, elements.size ]
|
||||
results = []
|
||||
elements.each do |element|
|
||||
Functions.pair[0] += 1
|
||||
Functions.node = element
|
||||
res = eval( predicate )
|
||||
case res
|
||||
when true
|
||||
results << element
|
||||
when Fixnum
|
||||
results << element if Functions.pair[0] == res
|
||||
when String
|
||||
results << element
|
||||
end
|
||||
end
|
||||
end
|
||||
return filter( results, rest )
|
||||
return filter( results, rest )
|
||||
end
|
||||
|
||||
def QuickPath::attribute( name )
|
||||
|
|
|
@ -12,12 +12,12 @@ module REXML
|
|||
|
||||
# Finds and returns the first node that matches the supplied xpath.
|
||||
# element::
|
||||
# The context element
|
||||
# The context element
|
||||
# path::
|
||||
# The xpath to search for. If not supplied or nil, returns the first
|
||||
# node matching '*'.
|
||||
# The xpath to search for. If not supplied or nil, returns the first
|
||||
# node matching '*'.
|
||||
# namespaces::
|
||||
# If supplied, a Hash which defines a namespace mapping.
|
||||
# If supplied, a Hash which defines a namespace mapping.
|
||||
# variables::
|
||||
# If supplied, a Hash which maps $variables in the query
|
||||
# to values. This can be used to avoid XPath injection attacks
|
||||
|
@ -45,7 +45,7 @@ module REXML
|
|||
# path::
|
||||
# The xpath to search for. If not supplied or nil, defaults to '*'
|
||||
# namespaces::
|
||||
# If supplied, a Hash which defines a namespace mapping
|
||||
# If supplied, a Hash which defines a namespace mapping
|
||||
# variables::
|
||||
# If supplied, a Hash which maps $variables in the query
|
||||
# to values. This can be used to avoid XPath injection attacks
|
||||
|
|
|
@ -43,10 +43,10 @@ module Rinda
|
|||
|
||||
def write_service
|
||||
Thread.new do
|
||||
loop do
|
||||
msg = @soc.recv(1024)
|
||||
do_write(msg)
|
||||
end
|
||||
loop do
|
||||
msg = @soc.recv(1024)
|
||||
do_write(msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -56,11 +56,11 @@ module Rinda
|
|||
|
||||
def do_write(msg)
|
||||
Thread.new do
|
||||
begin
|
||||
tuple, sec = Marshal.load(msg)
|
||||
@ts.write(tuple, sec)
|
||||
rescue
|
||||
end
|
||||
begin
|
||||
tuple, sec = Marshal.load(msg)
|
||||
@ts.write(tuple, sec)
|
||||
rescue
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -69,9 +69,9 @@ module Rinda
|
|||
|
||||
def reply_service
|
||||
Thread.new do
|
||||
loop do
|
||||
do_reply
|
||||
end
|
||||
loop do
|
||||
do_reply
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -105,8 +105,8 @@ module Rinda
|
|||
|
||||
def self.finger
|
||||
unless @@finger
|
||||
@@finger = self.new
|
||||
@@finger.lookup_ring_any
|
||||
@@finger = self.new
|
||||
@@finger.lookup_ring_any
|
||||
end
|
||||
@@finger
|
||||
end
|
||||
|
@ -178,15 +178,15 @@ module Rinda
|
|||
|
||||
msg = Marshal.dump([[:lookup_ring, DRbObject.new(block)], timeout])
|
||||
@broadcast_list.each do |it|
|
||||
soc = UDPSocket.open
|
||||
begin
|
||||
soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
|
||||
soc.send(msg, 0, it, @port)
|
||||
rescue
|
||||
nil
|
||||
ensure
|
||||
soc.close
|
||||
end
|
||||
soc = UDPSocket.open
|
||||
begin
|
||||
soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
|
||||
soc.send(msg, 0, it, @port)
|
||||
rescue
|
||||
nil
|
||||
ensure
|
||||
soc.close
|
||||
end
|
||||
end
|
||||
sleep(timeout)
|
||||
end
|
||||
|
@ -199,13 +199,13 @@ module Rinda
|
|||
queue = Queue.new
|
||||
|
||||
Thread.new do
|
||||
self.lookup_ring(timeout) do |ts|
|
||||
queue.push(ts)
|
||||
end
|
||||
queue.push(nil)
|
||||
while it = queue.pop
|
||||
@rings.push(it)
|
||||
end
|
||||
self.lookup_ring(timeout) do |ts|
|
||||
queue.push(ts)
|
||||
end
|
||||
queue.push(nil)
|
||||
while it = queue.pop
|
||||
@rings.push(it)
|
||||
end
|
||||
end
|
||||
|
||||
@primary = queue.pop
|
||||
|
|
|
@ -51,7 +51,7 @@ module RSS
|
|||
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def new_#{name}
|
||||
#{name} = self.class::#{klass_name}.new(@maker)
|
||||
#{name} = self.class::#{klass_name}.new(@maker)
|
||||
@#{plural} << #{name}
|
||||
if block_given?
|
||||
yield #{name}
|
||||
|
@ -63,14 +63,14 @@ module RSS
|
|||
|
||||
def to_feed(*args)
|
||||
@#{plural}.each do |#{name}|
|
||||
#{name}.to_feed(*args)
|
||||
#{name}.to_feed(*args)
|
||||
end
|
||||
end
|
||||
|
||||
def replace(elements)
|
||||
@#{plural}.replace(elements.to_a)
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_classed_element_without_accessor(name, class_name=nil)
|
||||
|
@ -88,7 +88,7 @@ module RSS
|
|||
def make_#{name}
|
||||
self.class::#{class_name}.new(@maker)
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_classed_element(name, class_name=nil, attribute_name=nil)
|
||||
|
@ -106,7 +106,7 @@ module RSS
|
|||
def #{name}=(new_value)
|
||||
@#{name}.#{attribute_name} = new_value
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
else
|
||||
attr_reader name
|
||||
end
|
||||
|
@ -126,17 +126,17 @@ module RSS
|
|||
end
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def #{name}
|
||||
#{local_variable_name} = #{plural_name}.first
|
||||
#{local_variable_name} ? #{local_variable_name}.#{attribute} : nil
|
||||
#{local_variable_name} = #{plural_name}.first
|
||||
#{local_variable_name} ? #{local_variable_name}.#{attribute} : nil
|
||||
end
|
||||
|
||||
def #{name}=(#{new_value_variable_name})
|
||||
#{local_variable_name} =
|
||||
#{plural_name}.first || #{plural_name}.new_#{new_name}
|
||||
#{additional_setup_code}
|
||||
#{local_variable_name}.#{attribute} = #{new_value_variable_name}
|
||||
#{local_variable_name} =
|
||||
#{plural_name}.first || #{plural_name}.new_#{new_name}
|
||||
#{additional_setup_code}
|
||||
#{local_variable_name}.#{attribute} = #{new_value_variable_name}
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_other_element(name)
|
||||
|
@ -153,7 +153,7 @@ module RSS
|
|||
current.#{name} = @#{name}
|
||||
end
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_csv_element(name, type=nil)
|
||||
|
@ -167,7 +167,7 @@ module RSS
|
|||
def #{name}=(value)
|
||||
@#{name} = Utils::CSV.parse(value)#{converter}
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -308,7 +308,7 @@ module RSS
|
|||
def ensure_xml_content(content)
|
||||
xhtml_uri = ::RSS::Atom::XHTML_URI
|
||||
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 = [children] unless content.is_a?(Array)
|
||||
children = set_xhtml_uri_as_default_uri(children)
|
||||
|
@ -331,7 +331,7 @@ module RSS
|
|||
def set_xhtml_uri_as_default_uri(children)
|
||||
children.collect do |child|
|
||||
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,
|
||||
child.attributes.dup,
|
||||
set_xhtml_uri_as_default_uri(child.children))
|
||||
|
@ -385,7 +385,7 @@ module RSS
|
|||
}
|
||||
_language = language
|
||||
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.value = _language.dup
|
||||
dc_languages.unshift(dc_language)
|
||||
|
@ -417,7 +417,7 @@ module RSS
|
|||
def make_#{element}
|
||||
self.class::#{Utils.to_class_name(element)}.new(self)
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
attr_reader :feed_version
|
||||
|
@ -500,9 +500,9 @@ module RSS
|
|||
end
|
||||
|
||||
[
|
||||
["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}],
|
||||
["author", "name"],
|
||||
["contributor", "name"],
|
||||
["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}],
|
||||
["author", "name"],
|
||||
["contributor", "name"],
|
||||
].each do |name, attribute, additional_setup_maker|
|
||||
def_classed_elements(name, attribute, &additional_setup_maker)
|
||||
end
|
||||
|
@ -511,7 +511,7 @@ module RSS
|
|||
managingEditor webMaster rating docs ttl).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
end
|
||||
end
|
||||
|
||||
%w(date lastBuildDate).each do |date_element|
|
||||
attr_reader date_element
|
||||
|
@ -713,12 +713,12 @@ module RSS
|
|||
end
|
||||
|
||||
[
|
||||
["author", "name"],
|
||||
["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}],
|
||||
["contributor", "name"],
|
||||
["author", "name"],
|
||||
["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}],
|
||||
["contributor", "name"],
|
||||
].each do |name, attribute|
|
||||
def_classed_elements(name, attribute)
|
||||
end
|
||||
end
|
||||
|
||||
%w(comments id published).each do |element|
|
||||
attr_accessor element
|
||||
|
@ -795,10 +795,10 @@ module RSS
|
|||
%w(authors categories contributors generator icon
|
||||
logo rights subtitle title).each do |name|
|
||||
def_classed_element(name)
|
||||
end
|
||||
end
|
||||
|
||||
[
|
||||
["link", "href"],
|
||||
["link", "href"],
|
||||
].each do |name, attribute|
|
||||
def_classed_elements(name, attribute)
|
||||
end
|
||||
|
|
|
@ -13,11 +13,11 @@ module RSS
|
|||
end
|
||||
|
||||
def self.install_image_item(klass)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
class ImageItem < ImageItemBase
|
||||
DublinCoreModel.install_dublin_core(self)
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
class ImageItemBase < Base
|
||||
|
@ -29,9 +29,9 @@ EOC
|
|||
add_need_initialize_variable("image_width")
|
||||
add_need_initialize_variable("image_height")
|
||||
alias width= image_width=
|
||||
alias width image_width
|
||||
alias width image_width
|
||||
alias height= image_height=
|
||||
alias height image_height
|
||||
alias height image_height
|
||||
|
||||
def have_required_values?
|
||||
@about
|
||||
|
@ -57,7 +57,7 @@ EOC
|
|||
end
|
||||
|
||||
def self.install_image_favicon(klass)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
class ImageFavicon < ImageFaviconBase
|
||||
DublinCoreModel.install_dublin_core(self)
|
||||
end
|
||||
|
@ -73,9 +73,9 @@ EOC
|
|||
alias size image_size
|
||||
alias size= image_size=
|
||||
|
||||
def have_required_values?
|
||||
@about and @image_size
|
||||
end
|
||||
def have_required_values?
|
||||
@about and @image_size
|
||||
end
|
||||
|
||||
def to_feed(feed, current)
|
||||
if current.respond_to?(:image_favicon=) and have_required_values?
|
||||
|
|
|
@ -5,27 +5,27 @@ class Time
|
|||
unless respond_to?(:w3cdtf)
|
||||
def w3cdtf(date)
|
||||
if /\A\s*
|
||||
(-?\d+)-(\d\d)-(\d\d)
|
||||
(?:T
|
||||
(\d\d):(\d\d)(?::(\d\d))?
|
||||
(\.\d+)?
|
||||
(Z|[+-]\d\d:\d\d)?)?
|
||||
\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]
|
||||
usec = 0
|
||||
usec = $7.to_f * 1000000 if $7
|
||||
zone = $8
|
||||
if zone
|
||||
off = zone_offset(zone, datetime[0])
|
||||
datetime = apply_offset(*(datetime + [off]))
|
||||
datetime << usec
|
||||
time = Time.utc(*datetime)
|
||||
time.localtime unless zone_utc?(zone)
|
||||
time
|
||||
else
|
||||
datetime << usec
|
||||
Time.local(*datetime)
|
||||
end
|
||||
(-?\d+)-(\d\d)-(\d\d)
|
||||
(?:T
|
||||
(\d\d):(\d\d)(?::(\d\d))?
|
||||
(\.\d+)?
|
||||
(Z|[+-]\d\d:\d\d)?)?
|
||||
\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]
|
||||
usec = 0
|
||||
usec = $7.to_f * 1000000 if $7
|
||||
zone = $8
|
||||
if zone
|
||||
off = zone_offset(zone, datetime[0])
|
||||
datetime = apply_offset(*(datetime + [off]))
|
||||
datetime << usec
|
||||
time = Time.utc(*datetime)
|
||||
time.localtime unless zone_utc?(zone)
|
||||
time
|
||||
else
|
||||
datetime << usec
|
||||
Time.local(*datetime)
|
||||
end
|
||||
else
|
||||
raise ArgumentError.new("invalid date: #{date.inspect}")
|
||||
end
|
||||
|
@ -209,7 +209,7 @@ module RSS
|
|||
else
|
||||
''
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
end
|
||||
alias_method(:install_have_attribute_element, :install_have_child_element)
|
||||
|
@ -230,7 +230,7 @@ EOC
|
|||
rv << value if /\\A\\s*\\z/ !~ value
|
||||
end
|
||||
rv.join("\n")
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -259,12 +259,12 @@ EOC
|
|||
else
|
||||
rv << value
|
||||
end
|
||||
rv << "</#{elem_name}>"
|
||||
rv << "</#{elem_name}>"
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -290,12 +290,12 @@ EOC
|
|||
else
|
||||
rv << value
|
||||
end
|
||||
rv << "</#{elem_name}>"
|
||||
rv << "</#{elem_name}>"
|
||||
rv
|
||||
else
|
||||
''
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -307,10 +307,10 @@ EOC
|
|||
add_to_element_method(method_name)
|
||||
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
|
||||
def #{method_name}(need_convert=true, indent='')
|
||||
#{yield(name, elem_name)}
|
||||
#{yield(name, elem_name)}
|
||||
end
|
||||
private :#{method_name}
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def inherit_convert_attr_reader(*attrs)
|
||||
|
@ -323,14 +323,14 @@ EOC
|
|||
|
||||
def #{attr}
|
||||
if @#{attr}
|
||||
#{attr}_without_inherit
|
||||
#{attr}_without_inherit
|
||||
elsif @parent
|
||||
@parent.#{attr}
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -351,7 +351,7 @@ EOC
|
|||
"\#{base}\#{value}"
|
||||
end
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -362,7 +362,7 @@ EOC
|
|||
def #{attr}
|
||||
convert(@#{attr})
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -408,7 +408,7 @@ EOC
|
|||
@#{attr}.join(#{separator.dump})
|
||||
end
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -448,7 +448,7 @@ EOC
|
|||
end
|
||||
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def integer_writer(name, disp_name=name)
|
||||
|
@ -468,7 +468,7 @@ EOC
|
|||
end
|
||||
end
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def positive_integer_writer(name, disp_name=name)
|
||||
|
@ -490,7 +490,7 @@ EOC
|
|||
end
|
||||
end
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def boolean_writer(name, disp_name=name)
|
||||
|
@ -510,7 +510,7 @@ EOC
|
|||
end
|
||||
end
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def text_type_writer(name, disp_name=name)
|
||||
|
@ -522,7 +522,7 @@ EOC
|
|||
end
|
||||
@#{name} = new_value
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def content_writer(name, disp_name=name)
|
||||
|
@ -536,7 +536,7 @@ EOC
|
|||
@#{name}.content = new_value
|
||||
end
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
def yes_clean_other_writer(name, disp_name=name)
|
||||
|
@ -603,7 +603,7 @@ EOC
|
|||
end
|
||||
end
|
||||
alias_method(:set_#{accessor_name}, :#{accessor_name}=)
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -630,7 +630,7 @@ EOC
|
|||
value = __send__(var)
|
||||
next if value.nil?
|
||||
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)
|
||||
else
|
||||
setter = "#{var}="
|
||||
|
@ -1173,7 +1173,7 @@ EOC
|
|||
else
|
||||
if name == tag
|
||||
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)
|
||||
end
|
||||
else
|
||||
|
|
96
lib/scanf.rb
96
lib/scanf.rb
|
@ -506,28 +506,28 @@ module Scanf
|
|||
class FormatString
|
||||
|
||||
attr_reader :string_left, :last_spec_tried,
|
||||
:last_match_tried, :matched_count, :space
|
||||
:last_match_tried, :matched_count, :space
|
||||
|
||||
SPECIFIERS = 'diuXxofFeEgGscaA'
|
||||
REGEX = /
|
||||
# possible space, followed by...
|
||||
(?:\s*
|
||||
# percent sign, followed by...
|
||||
%
|
||||
# another percent sign, or...
|
||||
(?:%|
|
||||
# optional assignment suppression flag
|
||||
\*?
|
||||
# optional maximum field width
|
||||
\d*
|
||||
# named character class, ...
|
||||
(?:\[\[:\w+:\]\]|
|
||||
# traditional character class, or...
|
||||
\[[^\]]*\]|
|
||||
# specifier letter.
|
||||
[#{SPECIFIERS}])))|
|
||||
# or miscellaneous characters
|
||||
[^%\s]+/ix
|
||||
# possible space, followed by...
|
||||
(?:\s*
|
||||
# percent sign, followed by...
|
||||
%
|
||||
# another percent sign, or...
|
||||
(?:%|
|
||||
# optional assignment suppression flag
|
||||
\*?
|
||||
# optional maximum field width
|
||||
\d*
|
||||
# named character class, ...
|
||||
(?:\[\[:\w+:\]\]|
|
||||
# traditional character class, or...
|
||||
\[[^\]]*\]|
|
||||
# specifier letter.
|
||||
[#{SPECIFIERS}])))|
|
||||
# or miscellaneous characters
|
||||
[^%\s]+/ix
|
||||
|
||||
def initialize(str)
|
||||
@specs = []
|
||||
|
@ -578,33 +578,33 @@ end
|
|||
|
||||
class IO
|
||||
|
||||
# The trick here is doing a match where you grab one *line*
|
||||
# of input at a time. The linebreak may or may not occur
|
||||
# at the boundary where the string matches a format specifier.
|
||||
# And if it does, some rule about whitespace may or may not
|
||||
# be in effect...
|
||||
#
|
||||
# That's why this is much more elaborate than the string
|
||||
# version.
|
||||
#
|
||||
# For each line:
|
||||
# Match succeeds (non-emptily)
|
||||
# and the last attempted spec/string sub-match succeeded:
|
||||
#
|
||||
# could the last spec keep matching?
|
||||
# yes: save interim results and continue (next line)
|
||||
#
|
||||
# The last attempted spec/string did not match:
|
||||
#
|
||||
# are we on the next-to-last spec in the string?
|
||||
# yes:
|
||||
# is fmt_string.string_left all spaces?
|
||||
# yes: does current spec care about input space?
|
||||
# yes: fatal failure
|
||||
# no: save interim results and continue
|
||||
# no: continue [this state could be analyzed further]
|
||||
#
|
||||
#
|
||||
# The trick here is doing a match where you grab one *line*
|
||||
# of input at a time. The linebreak may or may not occur
|
||||
# at the boundary where the string matches a format specifier.
|
||||
# And if it does, some rule about whitespace may or may not
|
||||
# be in effect...
|
||||
#
|
||||
# That's why this is much more elaborate than the string
|
||||
# version.
|
||||
#
|
||||
# For each line:
|
||||
# Match succeeds (non-emptily)
|
||||
# and the last attempted spec/string sub-match succeeded:
|
||||
#
|
||||
# could the last spec keep matching?
|
||||
# yes: save interim results and continue (next line)
|
||||
#
|
||||
# The last attempted spec/string did not match:
|
||||
#
|
||||
# are we on the next-to-last spec in the string?
|
||||
# yes:
|
||||
# is fmt_string.string_left all spaces?
|
||||
# yes: does current spec care about input space?
|
||||
# yes: fatal failure
|
||||
# no: save interim results and continue
|
||||
# no: continue [this state could be analyzed further]
|
||||
#
|
||||
#
|
||||
|
||||
def scanf(str,&b)
|
||||
return block_scanf(str,&b) if b
|
||||
|
@ -671,8 +671,8 @@ class IO
|
|||
|
||||
def block_scanf(str)
|
||||
final = []
|
||||
# Sub-ideal, since another FS gets created in scanf.
|
||||
# But used here to determine the number of specifiers.
|
||||
# Sub-ideal, since another FS gets created in scanf.
|
||||
# But used here to determine the number of specifiers.
|
||||
fstr = Scanf::FormatString.new(str)
|
||||
last_spec = fstr.last_spec
|
||||
begin
|
||||
|
|
534
lib/set.rb
534
lib/set.rb
|
@ -92,19 +92,19 @@ class Set
|
|||
@hash = orig.instance_eval{@hash}.dup
|
||||
end
|
||||
|
||||
def freeze # :nodoc:
|
||||
def freeze # :nodoc:
|
||||
super
|
||||
@hash.freeze
|
||||
self
|
||||
end
|
||||
|
||||
def taint # :nodoc:
|
||||
def taint # :nodoc:
|
||||
super
|
||||
@hash.taint
|
||||
self
|
||||
end
|
||||
|
||||
def untaint # :nodoc:
|
||||
def untaint # :nodoc:
|
||||
super
|
||||
@hash.untaint
|
||||
self
|
||||
|
@ -148,15 +148,15 @@ class Set
|
|||
def flatten_merge(set, seen = Set.new) # :nodoc:
|
||||
set.each { |e|
|
||||
if e.is_a?(Set)
|
||||
if seen.include?(e_id = e.object_id)
|
||||
raise ArgumentError, "tried to flatten recursive Set"
|
||||
end
|
||||
if seen.include?(e_id = e.object_id)
|
||||
raise ArgumentError, "tried to flatten recursive Set"
|
||||
end
|
||||
|
||||
seen.add(e_id)
|
||||
flatten_merge(e, seen)
|
||||
seen.delete(e_id)
|
||||
seen.add(e_id)
|
||||
flatten_merge(e, seen)
|
||||
seen.delete(e_id)
|
||||
else
|
||||
add(e)
|
||||
add(e)
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -325,163 +325,163 @@ class Set
|
|||
def |(enum)
|
||||
dup.merge(enum)
|
||||
end
|
||||
alias + | ##
|
||||
alias union | ##
|
||||
alias + | ##
|
||||
alias union | ##
|
||||
|
||||
# Returns a new set built by duplicating the set, removing every
|
||||
# element that appears in the given enumerable object.
|
||||
def -(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
|
||||
# Returns a new set built by duplicating the set, removing every
|
||||
# element that appears in the given enumerable object.
|
||||
def -(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
|
||||
|
||||
def hash # :nodoc:
|
||||
@hash.hash
|
||||
end
|
||||
def hash # :nodoc:
|
||||
@hash.hash
|
||||
end
|
||||
|
||||
def eql?(o) # :nodoc:
|
||||
return false unless o.is_a?(Set)
|
||||
@hash.eql?(o.instance_eval{@hash})
|
||||
end
|
||||
def eql?(o) # :nodoc:
|
||||
return false unless o.is_a?(Set)
|
||||
@hash.eql?(o.instance_eval{@hash})
|
||||
end
|
||||
|
||||
# Classifies the set by the return value of the given block and
|
||||
# returns a hash of {value => set of elements} pairs. The block is
|
||||
# called once for each element of the set, passing the element as
|
||||
# parameter.
|
||||
#
|
||||
# e.g.:
|
||||
#
|
||||
# require 'set'
|
||||
# files = Set.new(Dir.glob("*.rb"))
|
||||
# hash = files.classify { |f| File.mtime(f).year }
|
||||
# p hash # => {2000=>#<Set: {"a.rb", "b.rb"}>,
|
||||
# # 2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
|
||||
# # 2002=>#<Set: {"f.rb"}>}
|
||||
def classify # :yields: o
|
||||
block_given? or return enum_for(__method__)
|
||||
# Classifies the set by the return value of the given block and
|
||||
# returns a hash of {value => set of elements} pairs. The block is
|
||||
# called once for each element of the set, passing the element as
|
||||
# parameter.
|
||||
#
|
||||
# e.g.:
|
||||
#
|
||||
# require 'set'
|
||||
# files = Set.new(Dir.glob("*.rb"))
|
||||
# hash = files.classify { |f| File.mtime(f).year }
|
||||
# p hash # => {2000=>#<Set: {"a.rb", "b.rb"}>,
|
||||
# # 2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
|
||||
# # 2002=>#<Set: {"f.rb"}>}
|
||||
def classify # :yields: o
|
||||
block_given? or return enum_for(__method__)
|
||||
|
||||
h = {}
|
||||
h = {}
|
||||
|
||||
each { |i|
|
||||
x = yield(i)
|
||||
(h[x] ||= self.class.new).add(i)
|
||||
}
|
||||
each { |i|
|
||||
x = yield(i)
|
||||
(h[x] ||= self.class.new).add(i)
|
||||
}
|
||||
|
||||
h
|
||||
end
|
||||
h
|
||||
end
|
||||
|
||||
# Divides the set into a set of subsets according to the commonality
|
||||
# defined by the given block.
|
||||
#
|
||||
# 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
|
||||
# in common if block.call(o1) == block.call(o2).
|
||||
#
|
||||
# e.g.:
|
||||
#
|
||||
# require 'set'
|
||||
# numbers = Set[1, 3, 4, 6, 9, 10, 11]
|
||||
# set = numbers.divide { |i,j| (i - j).abs == 1 }
|
||||
# p set # => #<Set: {#<Set: {1}>,
|
||||
# # #<Set: {11, 9, 10}>,
|
||||
# # #<Set: {3, 4}>,
|
||||
# # #<Set: {6}>}>
|
||||
def divide(&func)
|
||||
func or return enum_for(__method__)
|
||||
# Divides the set into a set of subsets according to the commonality
|
||||
# defined by the given block.
|
||||
#
|
||||
# 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
|
||||
# in common if block.call(o1) == block.call(o2).
|
||||
#
|
||||
# e.g.:
|
||||
#
|
||||
# require 'set'
|
||||
# numbers = Set[1, 3, 4, 6, 9, 10, 11]
|
||||
# set = numbers.divide { |i,j| (i - j).abs == 1 }
|
||||
# p set # => #<Set: {#<Set: {1}>,
|
||||
# # #<Set: {11, 9, 10}>,
|
||||
# # #<Set: {3, 4}>,
|
||||
# # #<Set: {6}>}>
|
||||
def divide(&func)
|
||||
func or return enum_for(__method__)
|
||||
|
||||
if func.arity == 2
|
||||
require 'tsort'
|
||||
if func.arity == 2
|
||||
require 'tsort'
|
||||
|
||||
class << dig = {} # :nodoc:
|
||||
include TSort
|
||||
class << dig = {} # :nodoc:
|
||||
include TSort
|
||||
|
||||
alias tsort_each_node each_key
|
||||
def tsort_each_child(node, &block)
|
||||
fetch(node).each(&block)
|
||||
end
|
||||
alias tsort_each_node each_key
|
||||
def tsort_each_child(node, &block)
|
||||
fetch(node).each(&block)
|
||||
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
|
||||
|
||||
begin
|
||||
ids << object_id
|
||||
return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])
|
||||
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
|
||||
}
|
||||
each { |u|
|
||||
dig[u] = a = []
|
||||
each{ |v| func.call(u, v) and a << v }
|
||||
}
|
||||
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
|
||||
|
||||
def pretty_print_cycle(pp) # :nodoc:
|
||||
pp.text sprintf('#<%s: {%s}>', self.class.name, empty? ? '' : '...')
|
||||
begin
|
||||
ids << object_id
|
||||
return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])
|
||||
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 "}>"
|
||||
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
|
||||
# yielded in sorted order (according to the return values of their
|
||||
|
@ -515,11 +515,11 @@ class SortedSet < Set
|
|||
@@setup = false
|
||||
|
||||
class << self
|
||||
def [](*ary) # :nodoc:
|
||||
def [](*ary) # :nodoc:
|
||||
new(ary)
|
||||
end
|
||||
|
||||
def setup # :nodoc:
|
||||
def setup # :nodoc:
|
||||
@@setup and return
|
||||
|
||||
module_eval {
|
||||
|
@ -528,89 +528,89 @@ class SortedSet < Set
|
|||
remove_method :old_init
|
||||
}
|
||||
begin
|
||||
require 'rbtree'
|
||||
require 'rbtree'
|
||||
|
||||
module_eval %{
|
||||
def initialize(*args, &block)
|
||||
@hash = RBTree.new
|
||||
super
|
||||
end
|
||||
module_eval %{
|
||||
def initialize(*args, &block)
|
||||
@hash = RBTree.new
|
||||
super
|
||||
end
|
||||
|
||||
def add(o)
|
||||
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
|
||||
super
|
||||
end
|
||||
alias << add
|
||||
}
|
||||
def add(o)
|
||||
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
|
||||
super
|
||||
end
|
||||
alias << add
|
||||
}
|
||||
rescue LoadError
|
||||
module_eval %{
|
||||
def initialize(*args, &block)
|
||||
@keys = nil
|
||||
super
|
||||
end
|
||||
module_eval %{
|
||||
def initialize(*args, &block)
|
||||
@keys = nil
|
||||
super
|
||||
end
|
||||
|
||||
def clear
|
||||
@keys = nil
|
||||
super
|
||||
end
|
||||
def clear
|
||||
@keys = nil
|
||||
super
|
||||
end
|
||||
|
||||
def replace(enum)
|
||||
@keys = nil
|
||||
super
|
||||
end
|
||||
def replace(enum)
|
||||
@keys = nil
|
||||
super
|
||||
end
|
||||
|
||||
def add(o)
|
||||
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
|
||||
@keys = nil
|
||||
super
|
||||
end
|
||||
alias << add
|
||||
def add(o)
|
||||
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
|
||||
@keys = nil
|
||||
super
|
||||
end
|
||||
alias << add
|
||||
|
||||
def delete(o)
|
||||
@keys = nil
|
||||
@hash.delete(o)
|
||||
self
|
||||
end
|
||||
def delete(o)
|
||||
@keys = nil
|
||||
@hash.delete(o)
|
||||
self
|
||||
end
|
||||
|
||||
def delete_if
|
||||
def delete_if
|
||||
block_given? or return enum_for(__method__)
|
||||
n = @hash.size
|
||||
super
|
||||
@keys = nil if @hash.size != n
|
||||
self
|
||||
end
|
||||
n = @hash.size
|
||||
super
|
||||
@keys = nil if @hash.size != n
|
||||
self
|
||||
end
|
||||
|
||||
def keep_if
|
||||
block_given? or return enum_for(__method__)
|
||||
n = @hash.size
|
||||
super
|
||||
@keys = nil if @hash.size != n
|
||||
self
|
||||
end
|
||||
def keep_if
|
||||
block_given? or return enum_for(__method__)
|
||||
n = @hash.size
|
||||
super
|
||||
@keys = nil if @hash.size != n
|
||||
self
|
||||
end
|
||||
|
||||
def merge(enum)
|
||||
@keys = nil
|
||||
super
|
||||
end
|
||||
def merge(enum)
|
||||
@keys = nil
|
||||
super
|
||||
end
|
||||
|
||||
def each
|
||||
block_given? or return enum_for(__method__)
|
||||
to_a.each { |o| yield(o) }
|
||||
self
|
||||
end
|
||||
def each
|
||||
block_given? or return enum_for(__method__)
|
||||
to_a.each { |o| yield(o) }
|
||||
self
|
||||
end
|
||||
|
||||
def to_a
|
||||
(@keys = @hash.keys).sort! unless @keys
|
||||
@keys
|
||||
end
|
||||
}
|
||||
def to_a
|
||||
(@keys = @hash.keys).sort! unless @keys
|
||||
@keys
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
@@setup = true
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(*args, &block) # :nodoc:
|
||||
def initialize(*args, &block) # :nodoc:
|
||||
SortedSet.setup
|
||||
initialize(*args, &block)
|
||||
end
|
||||
|
@ -657,54 +657,54 @@ end
|
|||
#
|
||||
# if @proc.arity == 2
|
||||
# instance_eval %{
|
||||
# def add(o)
|
||||
# @hash[o] = true if @proc.call(self, o)
|
||||
# self
|
||||
# end
|
||||
# alias << add
|
||||
# def add(o)
|
||||
# @hash[o] = true if @proc.call(self, o)
|
||||
# self
|
||||
# end
|
||||
# alias << add
|
||||
#
|
||||
# def add?(o)
|
||||
# if include?(o) || !@proc.call(self, o)
|
||||
# nil
|
||||
# else
|
||||
# @hash[o] = true
|
||||
# self
|
||||
# end
|
||||
# end
|
||||
# def add?(o)
|
||||
# if include?(o) || !@proc.call(self, o)
|
||||
# nil
|
||||
# else
|
||||
# @hash[o] = true
|
||||
# self
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# def replace(enum)
|
||||
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
|
||||
# clear
|
||||
# enum.each_entry { |o| add(o) }
|
||||
# def replace(enum)
|
||||
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
|
||||
# clear
|
||||
# enum.each_entry { |o| add(o) }
|
||||
#
|
||||
# self
|
||||
# end
|
||||
# self
|
||||
# end
|
||||
#
|
||||
# def merge(enum)
|
||||
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
|
||||
# enum.each_entry { |o| add(o) }
|
||||
# def merge(enum)
|
||||
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
|
||||
# enum.each_entry { |o| add(o) }
|
||||
#
|
||||
# self
|
||||
# end
|
||||
# self
|
||||
# end
|
||||
# }
|
||||
# else
|
||||
# instance_eval %{
|
||||
# def add(o)
|
||||
# def add(o)
|
||||
# if @proc.call(o)
|
||||
# @hash[o] = true
|
||||
# @hash[o] = true
|
||||
# end
|
||||
# self
|
||||
# end
|
||||
# alias << add
|
||||
# self
|
||||
# end
|
||||
# alias << add
|
||||
#
|
||||
# def add?(o)
|
||||
# if include?(o) || !@proc.call(o)
|
||||
# nil
|
||||
# else
|
||||
# @hash[o] = true
|
||||
# self
|
||||
# end
|
||||
# end
|
||||
# def add?(o)
|
||||
# if include?(o) || !@proc.call(o)
|
||||
# nil
|
||||
# else
|
||||
# @hash[o] = true
|
||||
# self
|
||||
# end
|
||||
# end
|
||||
# }
|
||||
# end
|
||||
#
|
||||
|
@ -835,13 +835,13 @@ class TC_Set < Test::Unit::TestCase
|
|||
set1 = Set[
|
||||
1,
|
||||
Set[
|
||||
5,
|
||||
Set[7,
|
||||
Set[0]
|
||||
],
|
||||
Set[6,2],
|
||||
1
|
||||
],
|
||||
5,
|
||||
Set[7,
|
||||
Set[0]
|
||||
],
|
||||
Set[6,2],
|
||||
1
|
||||
],
|
||||
3,
|
||||
Set[3,4]
|
||||
]
|
||||
|
@ -1020,8 +1020,8 @@ class TC_Set < Test::Unit::TestCase
|
|||
|
||||
assert_nothing_raised {
|
||||
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(', ')}"
|
||||
}
|
||||
|
@ -1085,11 +1085,11 @@ class TC_Set < Test::Unit::TestCase
|
|||
ret = set.collect! { |i|
|
||||
case i
|
||||
when Numeric
|
||||
i * 2
|
||||
i * 2
|
||||
when String
|
||||
i.upcase
|
||||
i.upcase
|
||||
else
|
||||
nil
|
||||
nil
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -1168,8 +1168,8 @@ class TC_Set < Test::Unit::TestCase
|
|||
set2 = Set["a", "b", set1]
|
||||
set1 = set1.add(set1.clone)
|
||||
|
||||
# assert_equal(set1, set2)
|
||||
# assert_equal(set2, set1)
|
||||
# assert_equal(set1, set2)
|
||||
# assert_equal(set2, set1)
|
||||
assert_equal(set2, set2.clone)
|
||||
assert_equal(set1.clone, set1)
|
||||
|
||||
|
@ -1214,15 +1214,15 @@ class TC_Set < Test::Unit::TestCase
|
|||
assert_equal(set, ret.flatten)
|
||||
ret.each { |s|
|
||||
if s.include?(0)
|
||||
assert_equal(Set[0,1], s)
|
||||
assert_equal(Set[0,1], s)
|
||||
elsif s.include?(3)
|
||||
assert_equal(Set[3,4,5], s)
|
||||
assert_equal(Set[3,4,5], s)
|
||||
elsif s.include?(7)
|
||||
assert_equal(Set[7], s)
|
||||
assert_equal(Set[7], s)
|
||||
elsif s.include?(9)
|
||||
assert_equal(Set[9,10,11], s)
|
||||
assert_equal(Set[9,10,11], s)
|
||||
else
|
||||
raise "unexpected group: #{s.inspect}"
|
||||
raise "unexpected group: #{s.inspect}"
|
||||
end
|
||||
}
|
||||
end
|
||||
|
|
72
lib/shell.rb
72
lib/shell.rb
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# shell.rb -
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision: 1.9 $
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision: 1.9 $
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
#
|
||||
# --
|
||||
#
|
||||
|
@ -25,7 +25,7 @@ class Shell
|
|||
include Error
|
||||
extend Exception2MessageMapper
|
||||
|
||||
# @cascade = true
|
||||
# @cascade = true
|
||||
# debug: true -> normal debug
|
||||
# debug: 1 -> eval definition debug
|
||||
# debug: 2 -> detail inspect debug
|
||||
|
@ -41,7 +41,7 @@ class Shell
|
|||
|
||||
attr_accessor :cascade, :debug, :verbose
|
||||
|
||||
# alias cascade? cascade
|
||||
# alias cascade? cascade
|
||||
alias debug? debug
|
||||
alias verbose? verbose
|
||||
@verbose = true
|
||||
|
@ -57,9 +57,9 @@ class Shell
|
|||
|
||||
def default_system_path
|
||||
if @default_system_path
|
||||
@default_system_path
|
||||
@default_system_path
|
||||
else
|
||||
ENV["PATH"].split(":")
|
||||
ENV["PATH"].split(":")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -69,9 +69,9 @@ class Shell
|
|||
|
||||
def default_record_separator
|
||||
if @default_record_separator
|
||||
@default_record_separator
|
||||
@default_record_separator
|
||||
else
|
||||
$/
|
||||
$/
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -156,10 +156,10 @@ class Shell
|
|||
notify("chdir(with block) #{path}") if verbose
|
||||
cwd_old = @cwd
|
||||
begin
|
||||
chdir(path, nil)
|
||||
yield
|
||||
chdir(path, nil)
|
||||
yield
|
||||
ensure
|
||||
chdir(cwd_old, nil)
|
||||
chdir(cwd_old, nil)
|
||||
end
|
||||
else
|
||||
notify("chdir #{path}") if verbose
|
||||
|
@ -179,9 +179,9 @@ class Shell
|
|||
notify("pushdir(with block) #{path}") if verbose
|
||||
pushdir(path, nil)
|
||||
begin
|
||||
yield
|
||||
yield
|
||||
ensure
|
||||
popdir
|
||||
popdir
|
||||
end
|
||||
elsif path
|
||||
notify("pushdir #{path}") if verbose
|
||||
|
@ -192,12 +192,12 @@ class Shell
|
|||
else
|
||||
notify("pushdir") if verbose
|
||||
if pop = @dir_stack.pop
|
||||
@dir_stack.push @cwd
|
||||
chdir pop
|
||||
notify "dir stack: [#{@dir_stack.join ', '}]"
|
||||
self
|
||||
@dir_stack.push @cwd
|
||||
chdir pop
|
||||
notify "dir stack: [#{@dir_stack.join ', '}]"
|
||||
self
|
||||
else
|
||||
Shell.Fail DirStackEmpty
|
||||
Shell.Fail DirStackEmpty
|
||||
end
|
||||
end
|
||||
Void.new(self)
|
||||
|
@ -265,32 +265,32 @@ class Shell
|
|||
def self.notify(*opts, &block)
|
||||
Shell::debug_output_synchronize do
|
||||
if opts[-1].kind_of?(String)
|
||||
yorn = verbose?
|
||||
yorn = verbose?
|
||||
else
|
||||
yorn = opts.pop
|
||||
yorn = opts.pop
|
||||
end
|
||||
return unless yorn
|
||||
|
||||
if @debug_display_thread_id
|
||||
if @debug_display_process_id
|
||||
prefix = "shell(##{Process.pid}:#{Thread.current.to_s.sub("Thread", "Th")}): "
|
||||
else
|
||||
prefix = "shell(#{Thread.current.to_s.sub("Thread", "Th")}): "
|
||||
end
|
||||
if @debug_display_process_id
|
||||
prefix = "shell(##{Process.pid}:#{Thread.current.to_s.sub("Thread", "Th")}): "
|
||||
else
|
||||
prefix = "shell(#{Thread.current.to_s.sub("Thread", "Th")}): "
|
||||
end
|
||||
else
|
||||
prefix = "shell: "
|
||||
prefix = "shell: "
|
||||
end
|
||||
_head = true
|
||||
STDERR.print opts.collect{|mes|
|
||||
mes = mes.dup
|
||||
yield mes if iterator?
|
||||
if _head
|
||||
_head = false
|
||||
# "shell" " + mes
|
||||
prefix + mes
|
||||
else
|
||||
" "* prefix.size + mes
|
||||
end
|
||||
mes = mes.dup
|
||||
yield mes if iterator?
|
||||
if _head
|
||||
_head = false
|
||||
# "shell" " + mes
|
||||
prefix + mes
|
||||
else
|
||||
" "* prefix.size + mes
|
||||
end
|
||||
}.join("\n")+"\n"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# shell/builtin-command.rb -
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
#
|
||||
# --
|
||||
#
|
||||
|
@ -40,7 +40,7 @@ class Shell
|
|||
def each(rs = nil)
|
||||
rs = @shell.record_separator unless rs
|
||||
for str in @strings
|
||||
yield str + rs
|
||||
yield str + rs
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -53,11 +53,11 @@ class Shell
|
|||
|
||||
def each(rs = nil)
|
||||
if @cat_files.empty?
|
||||
super
|
||||
super
|
||||
else
|
||||
for src in @cat_files
|
||||
@shell.foreach(src, rs){|l| yield l}
|
||||
end
|
||||
for src in @cat_files
|
||||
@shell.foreach(src, rs){|l| yield l}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -71,31 +71,31 @@ class Shell
|
|||
|
||||
def each(rs = nil)
|
||||
if @pattern[0] == ?/
|
||||
@files = Dir[@pattern]
|
||||
@files = Dir[@pattern]
|
||||
else
|
||||
prefix = @shell.pwd+"/"
|
||||
@files = Dir[prefix+@pattern].collect{|p| p.sub(prefix, "")}
|
||||
prefix = @shell.pwd+"/"
|
||||
@files = Dir[prefix+@pattern].collect{|p| p.sub(prefix, "")}
|
||||
end
|
||||
rs = @shell.record_separator unless rs
|
||||
for f in @files
|
||||
yield f+rs
|
||||
yield f+rs
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# class Sort < Cat
|
||||
# def initialize(sh, *filenames)
|
||||
# super
|
||||
# end
|
||||
#
|
||||
# def each(rs = nil)
|
||||
# ary = []
|
||||
# super{|l| ary.push l}
|
||||
# for l in ary.sort!
|
||||
# yield l
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
# class Sort < Cat
|
||||
# def initialize(sh, *filenames)
|
||||
# super
|
||||
# end
|
||||
#
|
||||
# def each(rs = nil)
|
||||
# ary = []
|
||||
# super{|l| ary.push l}
|
||||
# for l in ary.sort!
|
||||
# yield l
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
||||
class AppendIO < BuiltInCommand
|
||||
def initialize(sh, io, filter)
|
||||
|
@ -107,7 +107,7 @@ class Shell
|
|||
def input=(filter)
|
||||
@input.input=filter
|
||||
for l in @input
|
||||
@io << l
|
||||
@io << l
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -122,9 +122,9 @@ class Shell
|
|||
|
||||
def input=(filter)
|
||||
begin
|
||||
super
|
||||
super
|
||||
ensure
|
||||
@io.close
|
||||
@io.close
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -138,9 +138,9 @@ class Shell
|
|||
def each(rs = nil)
|
||||
to = @shell.open(@to_filename, "w")
|
||||
begin
|
||||
super{|l| to << l; yield l}
|
||||
super{|l| to << l; yield l}
|
||||
ensure
|
||||
to.close
|
||||
to.close
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -153,7 +153,7 @@ class Shell
|
|||
|
||||
def each(rs = nil)
|
||||
while job = @jobs.shift
|
||||
job.each{|l| yield l}
|
||||
job.each{|l| yield l}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# shell/command-controller.rb -
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
#
|
||||
# --
|
||||
#
|
||||
|
@ -19,7 +19,7 @@ require "shell/builtin-command"
|
|||
|
||||
class Shell
|
||||
class CommandProcessor
|
||||
# include Error
|
||||
# include Error
|
||||
|
||||
#
|
||||
# initialize of Shell and related classes.
|
||||
|
@ -37,11 +37,11 @@ class Shell
|
|||
|
||||
# define CommandProcessor#methods to Shell#methods and Filter#methods
|
||||
for m in CommandProcessor.instance_methods(false) - NoDelegateMethods
|
||||
add_delegate_command_to_shell(m)
|
||||
add_delegate_command_to_shell(m)
|
||||
end
|
||||
|
||||
def self.method_added(id)
|
||||
add_delegate_command_to_shell(id)
|
||||
add_delegate_command_to_shell(id)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -50,14 +50,14 @@ class Shell
|
|||
#
|
||||
def self.run_config
|
||||
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
|
||||
print "load error: #{rc}\n"
|
||||
print $!.class, ": ", $!, "\n"
|
||||
for err in $@[0, $@.size - 2]
|
||||
print "\t", err, "\n"
|
||||
end
|
||||
print "load error: #{rc}\n"
|
||||
print $!.class, ": ", $!, "\n"
|
||||
for err in $@[0, $@.size - 2]
|
||||
print "\t", err, "\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -68,9 +68,9 @@ class Shell
|
|||
|
||||
#
|
||||
# CommandProcessor#expand_path(path)
|
||||
# path: String
|
||||
# return: String
|
||||
# returns the absolute path for <path>
|
||||
# path: String
|
||||
# return: String
|
||||
# returns the absolute path for <path>
|
||||
#
|
||||
def expand_path(path)
|
||||
@shell.expand_path(path)
|
||||
|
@ -86,68 +86,68 @@ class Shell
|
|||
# -
|
||||
#
|
||||
# CommandProcessor#foreach(path, rs)
|
||||
# path: String
|
||||
# rs: String - record separator
|
||||
# iterator
|
||||
# Same as:
|
||||
# File#foreach (when path is file)
|
||||
# Dir#foreach (when path is directory)
|
||||
# path is relative to pwd
|
||||
# path: String
|
||||
# rs: String - record separator
|
||||
# iterator
|
||||
# Same as:
|
||||
# File#foreach (when path is file)
|
||||
# Dir#foreach (when path is directory)
|
||||
# path is relative to pwd
|
||||
#
|
||||
def foreach(path = nil, *rs)
|
||||
path = "." unless path
|
||||
path = expand_path(path)
|
||||
|
||||
if File.directory?(path)
|
||||
Dir.foreach(path){|fn| yield fn}
|
||||
Dir.foreach(path){|fn| yield fn}
|
||||
else
|
||||
IO.foreach(path, *rs){|l| yield l}
|
||||
IO.foreach(path, *rs){|l| yield l}
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# CommandProcessor#open(path, mode)
|
||||
# path: String
|
||||
# mode: String
|
||||
# return: File or Dir
|
||||
# Same as:
|
||||
# File#open (when path is file)
|
||||
# Dir#open (when path is directory)
|
||||
# mode has an effect only when path is a file
|
||||
# path: String
|
||||
# mode: String
|
||||
# return: File or Dir
|
||||
# Same as:
|
||||
# File#open (when path is file)
|
||||
# Dir#open (when path is directory)
|
||||
# mode has an effect only when path is a file
|
||||
#
|
||||
def open(path, mode = nil, perm = 0666, &b)
|
||||
path = expand_path(path)
|
||||
if File.directory?(path)
|
||||
Dir.open(path, &b)
|
||||
Dir.open(path, &b)
|
||||
else
|
||||
if @shell.umask
|
||||
f = File.open(path, mode, perm)
|
||||
File.chmod(perm & ~@shell.umask, path)
|
||||
if block_given?
|
||||
f.each(&b)
|
||||
end
|
||||
f
|
||||
else
|
||||
f = File.open(path, mode, perm, &b)
|
||||
end
|
||||
if @shell.umask
|
||||
f = File.open(path, mode, perm)
|
||||
File.chmod(perm & ~@shell.umask, path)
|
||||
if block_given?
|
||||
f.each(&b)
|
||||
end
|
||||
f
|
||||
else
|
||||
f = File.open(path, mode, perm, &b)
|
||||
end
|
||||
end
|
||||
end
|
||||
# public :open
|
||||
|
||||
#
|
||||
# CommandProcessor#unlink(path)
|
||||
# same as:
|
||||
# Dir#unlink (when path is directory)
|
||||
# File#unlink (when path is file)
|
||||
# same as:
|
||||
# Dir#unlink (when path is directory)
|
||||
# File#unlink (when path is file)
|
||||
#
|
||||
def unlink(path)
|
||||
@shell.check_point
|
||||
|
||||
path = expand_path(path)
|
||||
if File.directory?(path)
|
||||
Dir.unlink(path)
|
||||
Dir.unlink(path)
|
||||
else
|
||||
IO.unlink(path)
|
||||
IO.unlink(path)
|
||||
end
|
||||
Void.new(@shell)
|
||||
end
|
||||
|
@ -155,19 +155,19 @@ class Shell
|
|||
#
|
||||
# CommandProcessor#test(command, file1, file2)
|
||||
# CommandProcessor#[command, file1, file2]
|
||||
# command: char or String or Symbol
|
||||
# file1: String
|
||||
# file2: String(optional)
|
||||
# return: Boolean
|
||||
# same as:
|
||||
# test() (when command is char or length 1 string or symbol)
|
||||
# FileTest.command (others)
|
||||
# example:
|
||||
# sh[?e, "foo"]
|
||||
# sh[:e, "foo"]
|
||||
# sh["e", "foo"]
|
||||
# sh[:exists?, "foo"]
|
||||
# sh["exists?", "foo"]
|
||||
# command: char or String or Symbol
|
||||
# file1: String
|
||||
# file2: String(optional)
|
||||
# return: Boolean
|
||||
# same as:
|
||||
# test() (when command is char or length 1 string or symbol)
|
||||
# FileTest.command (others)
|
||||
# example:
|
||||
# sh[?e, "foo"]
|
||||
# sh[:e, "foo"]
|
||||
# sh["e", "foo"]
|
||||
# sh[:exists?, "foo"]
|
||||
# sh["exists?", "foo"]
|
||||
#
|
||||
alias top_level_test test
|
||||
def test(command, file1, file2=nil)
|
||||
|
@ -177,25 +177,25 @@ class Shell
|
|||
|
||||
case command
|
||||
when Integer
|
||||
if file2
|
||||
top_level_test(command, file1, file2)
|
||||
else
|
||||
top_level_test(command, file1)
|
||||
end
|
||||
if file2
|
||||
top_level_test(command, file1, file2)
|
||||
else
|
||||
top_level_test(command, file1)
|
||||
end
|
||||
when String
|
||||
if command.size == 1
|
||||
if file2
|
||||
top_level_test(command, file1, file2)
|
||||
else
|
||||
top_level_test(command, file1)
|
||||
end
|
||||
else
|
||||
if file2
|
||||
FileTest.send(command, file1, file2)
|
||||
else
|
||||
FileTest.send(command, file1)
|
||||
end
|
||||
end
|
||||
if command.size == 1
|
||||
if file2
|
||||
top_level_test(command, file1, file2)
|
||||
else
|
||||
top_level_test(command, file1)
|
||||
end
|
||||
else
|
||||
if file2
|
||||
FileTest.send(command, file1, file2)
|
||||
else
|
||||
FileTest.send(command, file1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
alias [] test
|
||||
|
@ -209,8 +209,8 @@ class Shell
|
|||
#--
|
||||
#
|
||||
# CommandProcessor#mkdir(*path)
|
||||
# path: String
|
||||
# same as Dir.mkdir()
|
||||
# path: String
|
||||
# same as Dir.mkdir()
|
||||
#
|
||||
def mkdir(*path)
|
||||
@shell.check_point
|
||||
|
@ -218,59 +218,59 @@ class Shell
|
|||
|
||||
perm = nil
|
||||
if path.last.kind_of?(Integer)
|
||||
perm = path.pop
|
||||
perm = path.pop
|
||||
end
|
||||
for dir in path
|
||||
d = expand_path(dir)
|
||||
if perm
|
||||
Dir.mkdir(d, perm)
|
||||
else
|
||||
Dir.mkdir(d)
|
||||
end
|
||||
File.chmod(d, 0666 & ~@shell.umask) if @shell.umask
|
||||
d = expand_path(dir)
|
||||
if perm
|
||||
Dir.mkdir(d, perm)
|
||||
else
|
||||
Dir.mkdir(d)
|
||||
end
|
||||
File.chmod(d, 0666 & ~@shell.umask) if @shell.umask
|
||||
end
|
||||
Void.new(@shell)
|
||||
end
|
||||
|
||||
#
|
||||
# CommandProcessor#rmdir(*path)
|
||||
# path: String
|
||||
# same as Dir.rmdir()
|
||||
# path: String
|
||||
# same as Dir.rmdir()
|
||||
#
|
||||
def rmdir(*path)
|
||||
@shell.check_point
|
||||
notify("rmdir #{path.join(' ')}")
|
||||
|
||||
for dir in path
|
||||
Dir.rmdir(expand_path(dir))
|
||||
Dir.rmdir(expand_path(dir))
|
||||
end
|
||||
Void.new(@shell)
|
||||
end
|
||||
|
||||
#
|
||||
# CommandProcessor#system(command, *opts)
|
||||
# command: String
|
||||
# opts: String
|
||||
# return: SystemCommand
|
||||
# Same as system() function
|
||||
# example:
|
||||
# print sh.system("ls", "-l")
|
||||
# sh.system("ls", "-l") | sh.head > STDOUT
|
||||
# command: String
|
||||
# opts: String
|
||||
# return: SystemCommand
|
||||
# Same as system() function
|
||||
# example:
|
||||
# print sh.system("ls", "-l")
|
||||
# sh.system("ls", "-l") | sh.head > STDOUT
|
||||
#
|
||||
def system(command, *opts)
|
||||
if opts.empty?
|
||||
if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
|
||||
return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
|
||||
else
|
||||
command, *opts = command.split(/\s+/)
|
||||
end
|
||||
if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
|
||||
return SystemCommand.new(@shell, find_system_command("sh"), "-c", command)
|
||||
else
|
||||
command, *opts = command.split(/\s+/)
|
||||
end
|
||||
end
|
||||
SystemCommand.new(@shell, find_system_command(command), *opts)
|
||||
end
|
||||
|
||||
#
|
||||
# ProcessCommand#rehash
|
||||
# clear command hash table.
|
||||
# clear command hash table.
|
||||
#
|
||||
def rehash
|
||||
@system_commands = {}
|
||||
|
@ -286,9 +286,9 @@ class Shell
|
|||
|
||||
def transact(&block)
|
||||
begin
|
||||
@shell.instance_eval(&block)
|
||||
@shell.instance_eval(&block)
|
||||
ensure
|
||||
check_point
|
||||
check_point
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -318,11 +318,11 @@ class Shell
|
|||
def append(to, filter)
|
||||
case to
|
||||
when String
|
||||
AppendFile.new(@shell, to, filter)
|
||||
AppendFile.new(@shell, to, filter)
|
||||
when IO
|
||||
AppendIO.new(@shell, to, filter)
|
||||
AppendIO.new(@shell, to, filter)
|
||||
else
|
||||
Shell.Fail Error::CantApplyMethod, "append", to.class
|
||||
Shell.Fail Error::CantApplyMethod, "append", to.class
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -337,10 +337,10 @@ class Shell
|
|||
# %pwd, %cwd -> @pwd
|
||||
def notify(*opts, &block)
|
||||
Shell.notify(*opts) {|mes|
|
||||
yield mes if iterator?
|
||||
yield mes if iterator?
|
||||
|
||||
mes.gsub!("%pwd", "#{@cwd}")
|
||||
mes.gsub!("%cwd", "#{@cwd}")
|
||||
mes.gsub!("%pwd", "#{@cwd}")
|
||||
mes.gsub!("%cwd", "#{@cwd}")
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -351,21 +351,21 @@ class Shell
|
|||
return command if /^\// =~ command
|
||||
case path = @system_commands[command]
|
||||
when String
|
||||
if exists?(path)
|
||||
return path
|
||||
else
|
||||
Shell.Fail Error::CommandNotFound, command
|
||||
end
|
||||
if exists?(path)
|
||||
return path
|
||||
else
|
||||
Shell.Fail Error::CommandNotFound, command
|
||||
end
|
||||
when false
|
||||
Shell.Fail Error::CommandNotFound, command
|
||||
Shell.Fail Error::CommandNotFound, command
|
||||
end
|
||||
|
||||
for p in @shell.system_path
|
||||
path = join(p, command)
|
||||
if FileTest.exist?(path)
|
||||
@system_commands[command] = path
|
||||
return path
|
||||
end
|
||||
path = join(p, command)
|
||||
if FileTest.exist?(path)
|
||||
@system_commands[command] = path
|
||||
return path
|
||||
end
|
||||
end
|
||||
@system_commands[command] = false
|
||||
Shell.Fail Error::CommandNotFound, command
|
||||
|
@ -373,21 +373,21 @@ class Shell
|
|||
|
||||
#
|
||||
# CommandProcessor.def_system_command(command, path)
|
||||
# command: String
|
||||
# path: String
|
||||
# define 'command()' method as method.
|
||||
# command: String
|
||||
# path: String
|
||||
# define 'command()' method as method.
|
||||
#
|
||||
def self.def_system_command(command, path = command)
|
||||
begin
|
||||
eval((d = %Q[def #{command}(*opts)
|
||||
SystemCommand.new(@shell, '#{path}', *opts)
|
||||
eval((d = %Q[def #{command}(*opts)
|
||||
SystemCommand.new(@shell, '#{path}', *opts)
|
||||
end]), nil, __FILE__, __LINE__ - 1)
|
||||
rescue SyntaxError
|
||||
Shell.notify "warn: Can't define #{command} path: #{path}."
|
||||
Shell.notify "warn: Can't define #{command} path: #{path}."
|
||||
end
|
||||
Shell.notify "Define #{command} path: #{path}.", Shell.debug?
|
||||
Shell.notify("Definition of #{command}: ", d,
|
||||
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
||||
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
||||
end
|
||||
|
||||
def self.undef_system_command(command)
|
||||
|
@ -411,28 +411,28 @@ class Shell
|
|||
ali = ali.id2name if ali.kind_of?(Symbol)
|
||||
command = command.id2name if command.kind_of?(Symbol)
|
||||
begin
|
||||
if iterator?
|
||||
@alias_map[ali.intern] = proc
|
||||
if iterator?
|
||||
@alias_map[ali.intern] = proc
|
||||
|
||||
eval((d = %Q[def #{ali}(*opts)
|
||||
eval((d = %Q[def #{ali}(*opts)
|
||||
@shell.__send__(:#{command},
|
||||
*(CommandProcessor.alias_map[:#{ali}].call *opts))
|
||||
end]), nil, __FILE__, __LINE__ - 1)
|
||||
end]), nil, __FILE__, __LINE__ - 1)
|
||||
|
||||
else
|
||||
args = opts.collect{|opt| '"' + opt + '"'}.join(",")
|
||||
eval((d = %Q[def #{ali}(*opts)
|
||||
else
|
||||
args = opts.collect{|opt| '"' + opt + '"'}.join(",")
|
||||
eval((d = %Q[def #{ali}(*opts)
|
||||
@shell.__send__(:#{command}, #{args}, *opts)
|
||||
end]), nil, __FILE__, __LINE__ - 1)
|
||||
end
|
||||
end
|
||||
rescue SyntaxError
|
||||
Shell.notify "warn: Can't alias #{ali} command: #{command}."
|
||||
Shell.notify("Definition of #{ali}: ", d)
|
||||
raise
|
||||
Shell.notify "warn: Can't alias #{ali} command: #{command}."
|
||||
Shell.notify("Definition of #{ali}: ", d)
|
||||
raise
|
||||
end
|
||||
Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
|
||||
Shell.notify("Definition of #{ali}: ", d,
|
||||
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
||||
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -444,43 +444,43 @@ class Shell
|
|||
|
||||
#
|
||||
# CommandProcessor.def_builtin_commands(delegation_class, command_specs)
|
||||
# delegation_class: Class or Module
|
||||
# command_specs: [[command_name, [argument,...]],...]
|
||||
# command_name: String
|
||||
# arguments: String
|
||||
# FILENAME?? -> expand_path(filename??)
|
||||
# *FILENAME?? -> filename??.collect{|f|expand_path(f)}.join(", ")
|
||||
# define command_name(argument,...) as
|
||||
# delegation_class.command_name(argument,...)
|
||||
# delegation_class: Class or Module
|
||||
# command_specs: [[command_name, [argument,...]],...]
|
||||
# command_name: String
|
||||
# arguments: String
|
||||
# FILENAME?? -> expand_path(filename??)
|
||||
# *FILENAME?? -> filename??.collect{|f|expand_path(f)}.join(", ")
|
||||
# define command_name(argument,...) as
|
||||
# delegation_class.command_name(argument,...)
|
||||
#
|
||||
def self.def_builtin_commands(delegation_class, command_specs)
|
||||
for meth, args in command_specs
|
||||
arg_str = args.collect{|arg| arg.downcase}.join(", ")
|
||||
call_arg_str = args.collect{
|
||||
|arg|
|
||||
case arg
|
||||
when /^(FILENAME.*)$/
|
||||
format("expand_path(%s)", $1.downcase)
|
||||
when /^(\*FILENAME.*)$/
|
||||
# \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ")
|
||||
$1.downcase + '.collect{|fn| expand_path(fn)}'
|
||||
else
|
||||
arg
|
||||
end
|
||||
}.join(", ")
|
||||
d = %Q[def #{meth}(#{arg_str})
|
||||
#{delegation_class}.#{meth}(#{call_arg_str})
|
||||
end]
|
||||
Shell.notify "Define #{meth}(#{arg_str})", Shell.debug?
|
||||
Shell.notify("Definition of #{meth}: ", d,
|
||||
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
||||
eval d
|
||||
arg_str = args.collect{|arg| arg.downcase}.join(", ")
|
||||
call_arg_str = args.collect{
|
||||
|arg|
|
||||
case arg
|
||||
when /^(FILENAME.*)$/
|
||||
format("expand_path(%s)", $1.downcase)
|
||||
when /^(\*FILENAME.*)$/
|
||||
# \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ")
|
||||
$1.downcase + '.collect{|fn| expand_path(fn)}'
|
||||
else
|
||||
arg
|
||||
end
|
||||
}.join(", ")
|
||||
d = %Q[def #{meth}(#{arg_str})
|
||||
#{delegation_class}.#{meth}(#{call_arg_str})
|
||||
end]
|
||||
Shell.notify "Define #{meth}(#{arg_str})", Shell.debug?
|
||||
Shell.notify("Definition of #{meth}: ", d,
|
||||
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
|
||||
eval d
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# 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
|
||||
# CommandProcessor.command(). It doesn't define already defined
|
||||
# methods twice. By default, "pre_" is prefixes to each method
|
||||
|
@ -490,24 +490,24 @@ class Shell
|
|||
def self.install_system_commands(pre = "sys_")
|
||||
defined_meth = {}
|
||||
for m in Shell.methods
|
||||
defined_meth[m] = true
|
||||
defined_meth[m] = true
|
||||
end
|
||||
sh = Shell.new
|
||||
for path in Shell.default_system_path
|
||||
next unless sh.directory? path
|
||||
sh.cd path
|
||||
sh.foreach do
|
||||
|cn|
|
||||
if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn)
|
||||
command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1')
|
||||
begin
|
||||
def_system_command(command, sh.expand_path(cn))
|
||||
rescue
|
||||
Shell.notify "warn: Can't define #{command} path: #{cn}"
|
||||
end
|
||||
defined_meth[command] = command
|
||||
end
|
||||
end
|
||||
next unless sh.directory? path
|
||||
sh.cd path
|
||||
sh.foreach do
|
||||
|cn|
|
||||
if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn)
|
||||
command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1')
|
||||
begin
|
||||
def_system_command(command, sh.expand_path(cn))
|
||||
rescue
|
||||
Shell.notify "warn: Can't define #{command} path: #{cn}"
|
||||
end
|
||||
defined_meth[command] = command
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -520,35 +520,35 @@ class Shell
|
|||
id = id.intern if id.kind_of?(String)
|
||||
name = id.id2name
|
||||
if Shell.method_defined?(id)
|
||||
Shell.notify "warn: override definition of Shell##{name}."
|
||||
Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n"
|
||||
Shell.module_eval "alias #{name}_org #{name}"
|
||||
Shell.notify "warn: override definition of Shell##{name}."
|
||||
Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n"
|
||||
Shell.module_eval "alias #{name}_org #{name}"
|
||||
end
|
||||
Shell.notify "method added: Shell##{name}.", Shell.debug?
|
||||
Shell.module_eval(%Q[def #{name}(*args, &block)
|
||||
begin
|
||||
@command_processor.__send__(:#{name}, *args, &block)
|
||||
rescue Exception
|
||||
$@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
|
||||
$@.delete_if{|s| /^\\(eval\\):/ =~ s}
|
||||
raise
|
||||
end
|
||||
begin
|
||||
@command_processor.__send__(:#{name}, *args, &block)
|
||||
rescue Exception
|
||||
$@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
|
||||
$@.delete_if{|s| /^\\(eval\\):/ =~ s}
|
||||
raise
|
||||
end
|
||||
end], __FILE__, __LINE__)
|
||||
|
||||
if Shell::Filter.method_defined?(id)
|
||||
Shell.notify "warn: override definition of Shell::Filter##{name}."
|
||||
Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org."
|
||||
Filter.module_eval "alias #{name}_org #{name}"
|
||||
end
|
||||
Shell.notify "method added: Shell::Filter##{name}.", Shell.debug?
|
||||
Filter.module_eval(%Q[def #{name}(*args, &block)
|
||||
begin
|
||||
self | @shell.__send__(:#{name}, *args, &block)
|
||||
rescue Exception
|
||||
$@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
|
||||
$@.delete_if{|s| /^\\(eval\\):/ =~ s}
|
||||
raise
|
||||
end
|
||||
if Shell::Filter.method_defined?(id)
|
||||
Shell.notify "warn: override definition of Shell::Filter##{name}."
|
||||
Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org."
|
||||
Filter.module_eval "alias #{name}_org #{name}"
|
||||
end
|
||||
Shell.notify "method added: Shell::Filter##{name}.", Shell.debug?
|
||||
Filter.module_eval(%Q[def #{name}(*args, &block)
|
||||
begin
|
||||
self | @shell.__send__(:#{name}, *args, &block)
|
||||
rescue Exception
|
||||
$@.delete_if{|s| /:in `__getobj__'$/ =~ s} #`
|
||||
$@.delete_if{|s| /^\\(eval\\):/ =~ s}
|
||||
raise
|
||||
end
|
||||
end], __FILE__, __LINE__)
|
||||
end
|
||||
|
||||
|
@ -557,35 +557,35 @@ class Shell
|
|||
#
|
||||
def self.install_builtin_commands
|
||||
# method related File.
|
||||
# (exclude open/foreach/unlink)
|
||||
# (exclude open/foreach/unlink)
|
||||
normal_delegation_file_methods = [
|
||||
["atime", ["FILENAME"]],
|
||||
["basename", ["fn", "*opts"]],
|
||||
["chmod", ["mode", "*FILENAMES"]],
|
||||
["chown", ["owner", "group", "*FILENAME"]],
|
||||
["ctime", ["FILENAMES"]],
|
||||
["delete", ["*FILENAMES"]],
|
||||
["dirname", ["FILENAME"]],
|
||||
["ftype", ["FILENAME"]],
|
||||
["join", ["*items"]],
|
||||
["link", ["FILENAME_O", "FILENAME_N"]],
|
||||
["lstat", ["FILENAME"]],
|
||||
["mtime", ["FILENAME"]],
|
||||
["readlink", ["FILENAME"]],
|
||||
["rename", ["FILENAME_FROM", "FILENAME_TO"]],
|
||||
# ["size", ["FILENAME"]],
|
||||
["split", ["pathname"]],
|
||||
["stat", ["FILENAME"]],
|
||||
["symlink", ["FILENAME_O", "FILENAME_N"]],
|
||||
["truncate", ["FILENAME", "length"]],
|
||||
["utime", ["atime", "mtime", "*FILENAMES"]]]
|
||||
["atime", ["FILENAME"]],
|
||||
["basename", ["fn", "*opts"]],
|
||||
["chmod", ["mode", "*FILENAMES"]],
|
||||
["chown", ["owner", "group", "*FILENAME"]],
|
||||
["ctime", ["FILENAMES"]],
|
||||
["delete", ["*FILENAMES"]],
|
||||
["dirname", ["FILENAME"]],
|
||||
["ftype", ["FILENAME"]],
|
||||
["join", ["*items"]],
|
||||
["link", ["FILENAME_O", "FILENAME_N"]],
|
||||
["lstat", ["FILENAME"]],
|
||||
["mtime", ["FILENAME"]],
|
||||
["readlink", ["FILENAME"]],
|
||||
["rename", ["FILENAME_FROM", "FILENAME_TO"]],
|
||||
# ["size", ["FILENAME"]],
|
||||
["split", ["pathname"]],
|
||||
["stat", ["FILENAME"]],
|
||||
["symlink", ["FILENAME_O", "FILENAME_N"]],
|
||||
["truncate", ["FILENAME", "length"]],
|
||||
["utime", ["atime", "mtime", "*FILENAMES"]]]
|
||||
|
||||
def_builtin_commands(File, normal_delegation_file_methods)
|
||||
alias_method :rm, :delete
|
||||
def_builtin_commands(File, normal_delegation_file_methods)
|
||||
alias_method :rm, :delete
|
||||
|
||||
# method related FileTest
|
||||
def_builtin_commands(FileTest,
|
||||
FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]})
|
||||
# method related FileTest
|
||||
def_builtin_commands(FileTest,
|
||||
FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]})
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# shell/error.rb -
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
#
|
||||
# --
|
||||
#
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# shell/filter.rb -
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
#
|
||||
# --
|
||||
#
|
||||
|
@ -19,8 +19,8 @@ class Shell
|
|||
include Enumerable
|
||||
|
||||
def initialize(sh)
|
||||
@shell = sh # parent shell
|
||||
@input = nil # input filter
|
||||
@shell = sh # parent shell
|
||||
@input = nil # input filter
|
||||
end
|
||||
|
||||
attr_reader :input
|
||||
|
@ -32,52 +32,52 @@ class Shell
|
|||
def each(rs = nil)
|
||||
rs = @shell.record_separator unless rs
|
||||
if @input
|
||||
@input.each(rs){|l| yield l}
|
||||
@input.each(rs){|l| yield l}
|
||||
end
|
||||
end
|
||||
|
||||
def < (src)
|
||||
case src
|
||||
when String
|
||||
cat = Cat.new(@shell, src)
|
||||
cat | self
|
||||
cat = Cat.new(@shell, src)
|
||||
cat | self
|
||||
when IO
|
||||
self.input = src
|
||||
self
|
||||
self.input = src
|
||||
self
|
||||
else
|
||||
Shell.Fail Error::CantApplyMethod, "<", to.class
|
||||
Shell.Fail Error::CantApplyMethod, "<", to.class
|
||||
end
|
||||
end
|
||||
|
||||
def > (to)
|
||||
case to
|
||||
when String
|
||||
dst = @shell.open(to, "w")
|
||||
begin
|
||||
each(){|l| dst << l}
|
||||
ensure
|
||||
dst.close
|
||||
end
|
||||
dst = @shell.open(to, "w")
|
||||
begin
|
||||
each(){|l| dst << l}
|
||||
ensure
|
||||
dst.close
|
||||
end
|
||||
when IO
|
||||
each(){|l| to << l}
|
||||
each(){|l| to << l}
|
||||
else
|
||||
Shell.Fail Error::CantApplyMethod, ">", to.class
|
||||
Shell.Fail Error::CantApplyMethod, ">", to.class
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def >> (to)
|
||||
begin
|
||||
Shell.cd(@shell.pwd).append(to, self)
|
||||
Shell.cd(@shell.pwd).append(to, self)
|
||||
rescue CantApplyMethod
|
||||
Shell.Fail Error::CantApplyMethod, ">>", to.class
|
||||
Shell.Fail Error::CantApplyMethod, ">>", to.class
|
||||
end
|
||||
end
|
||||
|
||||
def | (filter)
|
||||
filter.input = self
|
||||
if active?
|
||||
@shell.process_controller.start_job filter
|
||||
@shell.process_controller.start_job filter
|
||||
end
|
||||
filter
|
||||
end
|
||||
|
@ -100,9 +100,9 @@ class Shell
|
|||
|
||||
def inspect
|
||||
if @shell.debug.kind_of?(Integer) && @shell.debug > 2
|
||||
super
|
||||
super
|
||||
else
|
||||
to_s
|
||||
to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# shell/process-controller.rb -
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
#
|
||||
# --
|
||||
#
|
||||
|
@ -27,60 +27,60 @@ class Shell
|
|||
extend Forwardable
|
||||
|
||||
def_delegator("@ProcessControllersMonitor",
|
||||
"synchronize", "process_controllers_exclusive")
|
||||
"synchronize", "process_controllers_exclusive")
|
||||
|
||||
def active_process_controllers
|
||||
process_controllers_exclusive do
|
||||
@ProcessControllers.dup
|
||||
end
|
||||
process_controllers_exclusive do
|
||||
@ProcessControllers.dup
|
||||
end
|
||||
end
|
||||
|
||||
def activate(pc)
|
||||
process_controllers_exclusive do
|
||||
@ProcessControllers[pc] ||= 0
|
||||
@ProcessControllers[pc] += 1
|
||||
end
|
||||
process_controllers_exclusive do
|
||||
@ProcessControllers[pc] ||= 0
|
||||
@ProcessControllers[pc] += 1
|
||||
end
|
||||
end
|
||||
|
||||
def inactivate(pc)
|
||||
process_controllers_exclusive do
|
||||
if @ProcessControllers[pc]
|
||||
if (@ProcessControllers[pc] -= 1) == 0
|
||||
@ProcessControllers.delete(pc)
|
||||
@ProcessControllersCV.signal
|
||||
end
|
||||
end
|
||||
end
|
||||
process_controllers_exclusive do
|
||||
if @ProcessControllers[pc]
|
||||
if (@ProcessControllers[pc] -= 1) == 0
|
||||
@ProcessControllers.delete(pc)
|
||||
@ProcessControllersCV.signal
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def each_active_object
|
||||
process_controllers_exclusive do
|
||||
for ref in @ProcessControllers.keys
|
||||
yield ref
|
||||
end
|
||||
end
|
||||
process_controllers_exclusive do
|
||||
for ref in @ProcessControllers.keys
|
||||
yield ref
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def block_output_synchronize(&b)
|
||||
@BlockOutputMonitor.synchronize(&b)
|
||||
@BlockOutputMonitor.synchronize(&b)
|
||||
end
|
||||
|
||||
def wait_to_finish_all_process_controllers
|
||||
process_controllers_exclusive do
|
||||
while !@ProcessControllers.empty?
|
||||
Shell::notify("Process finishing, but active shell exists",
|
||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||
if Shell.debug?
|
||||
for pc in @ProcessControllers.keys
|
||||
Shell::notify(" Not finished jobs in "+pc.shell.to_s)
|
||||
for com in pc.jobs
|
||||
com.notify(" Jobs: %id")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ProcessControllersCV.wait(@ProcessControllersMonitor)
|
||||
end
|
||||
end
|
||||
process_controllers_exclusive do
|
||||
while !@ProcessControllers.empty?
|
||||
Shell::notify("Process finishing, but active shell exists",
|
||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||
if Shell.debug?
|
||||
for pc in @ProcessControllers.keys
|
||||
Shell::notify(" Not finished jobs in "+pc.shell.to_s)
|
||||
for com in pc.jobs
|
||||
com.notify(" Jobs: %id")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ProcessControllersCV.wait(@ProcessControllersMonitor)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -105,8 +105,8 @@ class Shell
|
|||
def jobs
|
||||
jobs = []
|
||||
@jobs_sync.synchronize(:SH) do
|
||||
jobs.concat @waiting_jobs
|
||||
jobs.concat @active_jobs
|
||||
jobs.concat @waiting_jobs
|
||||
jobs.concat @active_jobs
|
||||
end
|
||||
jobs
|
||||
end
|
||||
|
@ -121,115 +121,115 @@ class Shell
|
|||
|
||||
def jobs_exist?
|
||||
@jobs_sync.synchronize(:SH) do
|
||||
@active_jobs.empty? or @waiting_jobs.empty?
|
||||
@active_jobs.empty? or @waiting_jobs.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def active_jobs_exist?
|
||||
@jobs_sync.synchronize(:SH) do
|
||||
@active_jobs.empty?
|
||||
@active_jobs.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def waiting_jobs_exist?
|
||||
@jobs_sync.synchronize(:SH) do
|
||||
@waiting_jobs.empty?
|
||||
@waiting_jobs.empty?
|
||||
end
|
||||
end
|
||||
|
||||
# schedule a command
|
||||
def add_schedule(command)
|
||||
@jobs_sync.synchronize(:EX) do
|
||||
ProcessController.activate(self)
|
||||
if @active_jobs.empty?
|
||||
start_job command
|
||||
else
|
||||
@waiting_jobs.push(command)
|
||||
end
|
||||
ProcessController.activate(self)
|
||||
if @active_jobs.empty?
|
||||
start_job command
|
||||
else
|
||||
@waiting_jobs.push(command)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# start a job
|
||||
def start_job(command = nil)
|
||||
@jobs_sync.synchronize(:EX) do
|
||||
if command
|
||||
return if command.active?
|
||||
@waiting_jobs.delete command
|
||||
else
|
||||
command = @waiting_jobs.shift
|
||||
# command.notify "job(%id) pre-start.", @shell.debug?
|
||||
if command
|
||||
return if command.active?
|
||||
@waiting_jobs.delete command
|
||||
else
|
||||
command = @waiting_jobs.shift
|
||||
# command.notify "job(%id) pre-start.", @shell.debug?
|
||||
|
||||
return unless command
|
||||
end
|
||||
@active_jobs.push command
|
||||
command.start
|
||||
# command.notify "job(%id) post-start.", @shell.debug?
|
||||
return unless command
|
||||
end
|
||||
@active_jobs.push command
|
||||
command.start
|
||||
# command.notify "job(%id) post-start.", @shell.debug?
|
||||
|
||||
# start all jobs that input from the job
|
||||
for job in @waiting_jobs.dup
|
||||
start_job(job) if job.input == command
|
||||
end
|
||||
# command.notify "job(%id) post2-start.", @shell.debug?
|
||||
# start all jobs that input from the job
|
||||
for job in @waiting_jobs.dup
|
||||
start_job(job) if job.input == command
|
||||
end
|
||||
# command.notify "job(%id) post2-start.", @shell.debug?
|
||||
end
|
||||
end
|
||||
|
||||
def waiting_job?(job)
|
||||
@jobs_sync.synchronize(:SH) do
|
||||
@waiting_jobs.include?(job)
|
||||
@waiting_jobs.include?(job)
|
||||
end
|
||||
end
|
||||
|
||||
def active_job?(job)
|
||||
@jobs_sync.synchronize(:SH) do
|
||||
@active_jobs.include?(job)
|
||||
@active_jobs.include?(job)
|
||||
end
|
||||
end
|
||||
|
||||
# terminate a job
|
||||
def terminate_job(command)
|
||||
@jobs_sync.synchronize(:EX) do
|
||||
@active_jobs.delete command
|
||||
ProcessController.inactivate(self)
|
||||
if @active_jobs.empty?
|
||||
command.notify("start_job in terminate_job(%id)", Shell::debug?)
|
||||
start_job
|
||||
end
|
||||
@active_jobs.delete command
|
||||
ProcessController.inactivate(self)
|
||||
if @active_jobs.empty?
|
||||
command.notify("start_job in terminate_job(%id)", Shell::debug?)
|
||||
start_job
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# kill a job
|
||||
def kill_job(sig, command)
|
||||
@jobs_sync.synchronize(:EX) do
|
||||
if @waiting_jobs.delete command
|
||||
ProcessController.inactivate(self)
|
||||
return
|
||||
elsif @active_jobs.include?(command)
|
||||
begin
|
||||
r = command.kill(sig)
|
||||
ProcessController.inactivate(self)
|
||||
rescue
|
||||
print "Shell: Warn: $!\n" if @shell.verbose?
|
||||
return nil
|
||||
end
|
||||
@active_jobs.delete command
|
||||
r
|
||||
end
|
||||
if @waiting_jobs.delete command
|
||||
ProcessController.inactivate(self)
|
||||
return
|
||||
elsif @active_jobs.include?(command)
|
||||
begin
|
||||
r = command.kill(sig)
|
||||
ProcessController.inactivate(self)
|
||||
rescue
|
||||
print "Shell: Warn: $!\n" if @shell.verbose?
|
||||
return nil
|
||||
end
|
||||
@active_jobs.delete command
|
||||
r
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# wait for all jobs to terminate
|
||||
def wait_all_jobs_execution
|
||||
@job_monitor.synchronize do
|
||||
begin
|
||||
while !jobs.empty?
|
||||
@job_condition.wait(@job_monitor)
|
||||
for job in jobs
|
||||
job.notify("waiting job(%id)", Shell::debug?)
|
||||
end
|
||||
end
|
||||
ensure
|
||||
redo unless jobs.empty?
|
||||
end
|
||||
begin
|
||||
while !jobs.empty?
|
||||
@job_condition.wait(@job_monitor)
|
||||
for job in jobs
|
||||
job.notify("waiting job(%id)", Shell::debug?)
|
||||
end
|
||||
end
|
||||
ensure
|
||||
redo unless jobs.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -244,73 +244,73 @@ class Shell
|
|||
pid_cv = ConditionVariable.new
|
||||
|
||||
Thread.start do
|
||||
ProcessController.block_output_synchronize do
|
||||
STDOUT.flush
|
||||
ProcessController.each_active_object do |pc|
|
||||
for jobs in pc.active_jobs
|
||||
jobs.flush
|
||||
end
|
||||
end
|
||||
ProcessController.block_output_synchronize do
|
||||
STDOUT.flush
|
||||
ProcessController.each_active_object do |pc|
|
||||
for jobs in pc.active_jobs
|
||||
jobs.flush
|
||||
end
|
||||
end
|
||||
|
||||
pid = fork {
|
||||
Thread.list.each do |th|
|
||||
# th.kill unless [Thread.main, Thread.current].include?(th)
|
||||
th.kill unless Thread.current == th
|
||||
end
|
||||
pid = fork {
|
||||
Thread.list.each do |th|
|
||||
# th.kill unless [Thread.main, Thread.current].include?(th)
|
||||
th.kill unless Thread.current == th
|
||||
end
|
||||
|
||||
STDIN.reopen(pipe_peer_in)
|
||||
STDOUT.reopen(pipe_peer_out)
|
||||
STDIN.reopen(pipe_peer_in)
|
||||
STDOUT.reopen(pipe_peer_out)
|
||||
|
||||
ObjectSpace.each_object(IO) do |io|
|
||||
if ![STDIN, STDOUT, STDERR].include?(io)
|
||||
io.close unless io.closed?
|
||||
end
|
||||
end
|
||||
ObjectSpace.each_object(IO) do |io|
|
||||
if ![STDIN, STDOUT, STDERR].include?(io)
|
||||
io.close unless io.closed?
|
||||
end
|
||||
end
|
||||
|
||||
yield
|
||||
}
|
||||
end
|
||||
pid_cv.signal
|
||||
yield
|
||||
}
|
||||
end
|
||||
pid_cv.signal
|
||||
|
||||
pipe_peer_in.close
|
||||
pipe_peer_out.close
|
||||
command.notify "job(%name:##{pid}) start", @shell.debug?
|
||||
pipe_peer_in.close
|
||||
pipe_peer_out.close
|
||||
command.notify "job(%name:##{pid}) start", @shell.debug?
|
||||
|
||||
begin
|
||||
_pid = nil
|
||||
command.notify("job(%id) start to waiting finish.", @shell.debug?)
|
||||
_pid = Process.waitpid(pid, nil)
|
||||
rescue Errno::ECHILD
|
||||
command.notify "warn: job(%id) was done already waitpid."
|
||||
_pid = true
|
||||
# rescue
|
||||
# STDERR.puts $!
|
||||
ensure
|
||||
command.notify("Job(%id): Wait to finish when Process finished.", @shell.debug?)
|
||||
# when the process ends, wait until the command terminates
|
||||
if USING_AT_EXIT_WHEN_PROCESS_EXIT or _pid
|
||||
else
|
||||
command.notify("notice: Process finishing...",
|
||||
"wait for Job[%id] to finish.",
|
||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||
redo
|
||||
end
|
||||
begin
|
||||
_pid = nil
|
||||
command.notify("job(%id) start to waiting finish.", @shell.debug?)
|
||||
_pid = Process.waitpid(pid, nil)
|
||||
rescue Errno::ECHILD
|
||||
command.notify "warn: job(%id) was done already waitpid."
|
||||
_pid = true
|
||||
# rescue
|
||||
# STDERR.puts $!
|
||||
ensure
|
||||
command.notify("Job(%id): Wait to finish when Process finished.", @shell.debug?)
|
||||
# when the process ends, wait until the command terminates
|
||||
if USING_AT_EXIT_WHEN_PROCESS_EXIT or _pid
|
||||
else
|
||||
command.notify("notice: Process finishing...",
|
||||
"wait for Job[%id] to finish.",
|
||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||
redo
|
||||
end
|
||||
|
||||
# command.notify "job(%id) pre-pre-finish.", @shell.debug?
|
||||
@job_monitor.synchronize do
|
||||
# command.notify "job(%id) pre-finish.", @shell.debug?
|
||||
terminate_job(command)
|
||||
# command.notify "job(%id) pre-finish2.", @shell.debug?
|
||||
@job_condition.signal
|
||||
command.notify "job(%id) finish.", @shell.debug?
|
||||
end
|
||||
end
|
||||
# command.notify "job(%id) pre-pre-finish.", @shell.debug?
|
||||
@job_monitor.synchronize do
|
||||
# command.notify "job(%id) pre-finish.", @shell.debug?
|
||||
terminate_job(command)
|
||||
# command.notify "job(%id) pre-finish2.", @shell.debug?
|
||||
@job_condition.signal
|
||||
command.notify "job(%id) finish.", @shell.debug?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pid_mutex.synchronize do
|
||||
while !pid
|
||||
pid_cv.wait(pid_mutex)
|
||||
end
|
||||
while !pid
|
||||
pid_cv.wait(pid_mutex)
|
||||
end
|
||||
end
|
||||
|
||||
return pid, pipe_me_in, pipe_me_out
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# shell/system-command.rb -
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
# $Release Version: 0.7 $
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
#
|
||||
# --
|
||||
#
|
||||
|
@ -15,7 +15,7 @@ class Shell
|
|||
class SystemCommand < Filter
|
||||
def initialize(sh, command, *opts)
|
||||
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
|
||||
super(sh)
|
||||
@command = command
|
||||
|
@ -41,7 +41,7 @@ class Shell
|
|||
def input=(inp)
|
||||
super
|
||||
if active?
|
||||
start_export
|
||||
start_export
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -49,12 +49,12 @@ class Shell
|
|||
notify([@command, *@opts].join(" "))
|
||||
|
||||
@pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {
|
||||
Dir.chdir @shell.pwd
|
||||
$0 = @command
|
||||
exec(@command, *@opts)
|
||||
Dir.chdir @shell.pwd
|
||||
$0 = @command
|
||||
exec(@command, *@opts)
|
||||
}
|
||||
if @input
|
||||
start_export
|
||||
start_export
|
||||
end
|
||||
start_import
|
||||
end
|
||||
|
@ -65,18 +65,18 @@ class Shell
|
|||
|
||||
def terminate
|
||||
begin
|
||||
@pipe_in.close
|
||||
@pipe_in.close
|
||||
rescue IOError
|
||||
end
|
||||
begin
|
||||
@pipe_out.close
|
||||
@pipe_out.close
|
||||
rescue IOError
|
||||
end
|
||||
end
|
||||
|
||||
def kill(sig)
|
||||
if @pid
|
||||
Process.kill(sig, @pid)
|
||||
Process.kill(sig, @pid)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -85,24 +85,24 @@ class Shell
|
|||
rs = @shell.record_separator unless rs
|
||||
_eop = true
|
||||
Thread.start {
|
||||
begin
|
||||
while l = @pipe_in.gets
|
||||
@input_queue.push l
|
||||
end
|
||||
_eop = false
|
||||
rescue Errno::EPIPE
|
||||
_eop = false
|
||||
ensure
|
||||
if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
|
||||
notify("warn: Process finishing...",
|
||||
"wait for Job[%id] to finish pipe importing.",
|
||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||
redo
|
||||
end
|
||||
notify "job(%id}) close imp-pipe.", @shell.debug?
|
||||
@input_queue.push :EOF
|
||||
@pipe_in.close
|
||||
end
|
||||
begin
|
||||
while l = @pipe_in.gets
|
||||
@input_queue.push l
|
||||
end
|
||||
_eop = false
|
||||
rescue Errno::EPIPE
|
||||
_eop = false
|
||||
ensure
|
||||
if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
|
||||
notify("warn: Process finishing...",
|
||||
"wait for Job[%id] to finish pipe importing.",
|
||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||
redo
|
||||
end
|
||||
notify "job(%id}) close imp-pipe.", @shell.debug?
|
||||
@input_queue.push :EOF
|
||||
@pipe_in.close
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -110,49 +110,49 @@ class Shell
|
|||
notify "job(%id) start exp-pipe.", @shell.debug?
|
||||
_eop = true
|
||||
Thread.start{
|
||||
begin
|
||||
@input.each do |l|
|
||||
ProcessController::block_output_synchronize do
|
||||
@pipe_out.print l
|
||||
end
|
||||
end
|
||||
_eop = false
|
||||
rescue Errno::EPIPE, Errno::EIO
|
||||
_eop = false
|
||||
ensure
|
||||
if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
|
||||
notify("shell: warn: Process finishing...",
|
||||
"wait for Job(%id) to finish pipe exporting.",
|
||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||
redo
|
||||
end
|
||||
notify "job(%id) close exp-pipe.", @shell.debug?
|
||||
@pipe_out.close
|
||||
end
|
||||
begin
|
||||
@input.each do |l|
|
||||
ProcessController::block_output_synchronize do
|
||||
@pipe_out.print l
|
||||
end
|
||||
end
|
||||
_eop = false
|
||||
rescue Errno::EPIPE, Errno::EIO
|
||||
_eop = false
|
||||
ensure
|
||||
if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
|
||||
notify("shell: warn: Process finishing...",
|
||||
"wait for Job(%id) to finish pipe exporting.",
|
||||
"You can use Shell#transact or Shell#check_point for more safe execution.")
|
||||
redo
|
||||
end
|
||||
notify "job(%id) close exp-pipe.", @shell.debug?
|
||||
@pipe_out.close
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
alias super_each each
|
||||
def each(rs = nil)
|
||||
while (l = @input_queue.pop) != :EOF
|
||||
yield l
|
||||
yield l
|
||||
end
|
||||
end
|
||||
|
||||
# ex)
|
||||
# if you wish to output:
|
||||
# "shell: job(#{@command}:#{@pid}) close pipe-out."
|
||||
# then
|
||||
# mes: "job(%id) close pipe-out."
|
||||
# "shell: job(#{@command}:#{@pid}) close pipe-out."
|
||||
# then
|
||||
# mes: "job(%id) close pipe-out."
|
||||
# yorn: Boolean(@shell.debug? or @shell.verbose?)
|
||||
def notify(*opts, &block)
|
||||
@shell.notify(*opts) do |mes|
|
||||
yield mes if iterator?
|
||||
yield mes if iterator?
|
||||
|
||||
mes.gsub!("%id", "#{@command}:##{@pid}")
|
||||
mes.gsub!("%name", "#{@command}")
|
||||
mes.gsub!("%pid", "#{@pid}")
|
||||
mes
|
||||
mes.gsub!("%id", "#{@command}:##{@pid}")
|
||||
mes.gsub!("%name", "#{@command}")
|
||||
mes.gsub!("%pid", "#{@pid}")
|
||||
mes
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# version.rb - shell version definition file
|
||||
# $Release Version: 0.7$
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
||||
# $Release Version: 0.7$
|
||||
# $Revision$
|
||||
# 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
|
||||
# $Release Version: 1.0$
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||
# $Release Version: 1.0$
|
||||
# $Revision$
|
||||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||||
#
|
||||
# --
|
||||
# Sync_m, Synchronizer_m
|
||||
|
@ -10,8 +10,8 @@
|
|||
# obj.extend(Sync_m)
|
||||
# or
|
||||
# class Foo
|
||||
# include Sync_m
|
||||
# :
|
||||
# include Sync_m
|
||||
# :
|
||||
# end
|
||||
#
|
||||
# Sync_m#sync_mode
|
||||
|
@ -58,17 +58,17 @@ module Sync_m
|
|||
class UnknownLocker < Err
|
||||
Message = "Thread(%s) not locked."
|
||||
def UnknownLocker.Fail(th)
|
||||
super(th.inspect)
|
||||
super(th.inspect)
|
||||
end
|
||||
end
|
||||
|
||||
class LockModeFailer < Err
|
||||
Message = "Unknown lock mode(%s)"
|
||||
def LockModeFailer.Fail(mode)
|
||||
if mode.id2name
|
||||
mode = id2name
|
||||
end
|
||||
super(mode)
|
||||
if mode.id2name
|
||||
mode = id2name
|
||||
end
|
||||
super(mode)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -100,12 +100,12 @@ module Sync_m
|
|||
|
||||
def sync_extend
|
||||
unless (defined? locked? and
|
||||
defined? shared? and
|
||||
defined? exclusive? and
|
||||
defined? lock and
|
||||
defined? unlock and
|
||||
defined? try_lock and
|
||||
defined? synchronize)
|
||||
defined? shared? and
|
||||
defined? exclusive? and
|
||||
defined? lock and
|
||||
defined? unlock and
|
||||
defined? try_lock and
|
||||
defined? synchronize)
|
||||
Sync_m.define_aliases(singleton_class)
|
||||
end
|
||||
sync_initialize
|
||||
|
@ -137,17 +137,17 @@ module Sync_m
|
|||
|
||||
while true
|
||||
@sync_mutex.synchronize do
|
||||
if sync_try_lock_sub(m)
|
||||
return self
|
||||
else
|
||||
if sync_sh_locker[Thread.current]
|
||||
sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
|
||||
sync_sh_locker.delete(Thread.current)
|
||||
else
|
||||
sync_waiting.push Thread.current
|
||||
end
|
||||
@sync_mutex.sleep
|
||||
end
|
||||
if sync_try_lock_sub(m)
|
||||
return self
|
||||
else
|
||||
if sync_sh_locker[Thread.current]
|
||||
sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
|
||||
sync_sh_locker.delete(Thread.current)
|
||||
else
|
||||
sync_waiting.push Thread.current
|
||||
end
|
||||
@sync_mutex.sleep
|
||||
end
|
||||
end
|
||||
end
|
||||
self
|
||||
|
@ -157,7 +157,7 @@ module Sync_m
|
|||
wakeup_threads = []
|
||||
@sync_mutex.synchronize do
|
||||
if sync_mode == UN
|
||||
Err::UnknownLocker.Fail(Thread.current)
|
||||
Err::UnknownLocker.Fail(Thread.current)
|
||||
end
|
||||
|
||||
m = sync_mode if m == EX and sync_mode == SH
|
||||
|
@ -165,51 +165,51 @@ module Sync_m
|
|||
runnable = false
|
||||
case m
|
||||
when UN
|
||||
Err::UnknownLocker.Fail(Thread.current)
|
||||
Err::UnknownLocker.Fail(Thread.current)
|
||||
|
||||
when EX
|
||||
if sync_ex_locker == Thread.current
|
||||
if (self.sync_ex_count = sync_ex_count - 1) == 0
|
||||
self.sync_ex_locker = nil
|
||||
if sync_sh_locker.include?(Thread.current)
|
||||
self.sync_mode = SH
|
||||
else
|
||||
self.sync_mode = UN
|
||||
end
|
||||
runnable = true
|
||||
end
|
||||
else
|
||||
Err::UnknownLocker.Fail(Thread.current)
|
||||
end
|
||||
if sync_ex_locker == Thread.current
|
||||
if (self.sync_ex_count = sync_ex_count - 1) == 0
|
||||
self.sync_ex_locker = nil
|
||||
if sync_sh_locker.include?(Thread.current)
|
||||
self.sync_mode = SH
|
||||
else
|
||||
self.sync_mode = UN
|
||||
end
|
||||
runnable = true
|
||||
end
|
||||
else
|
||||
Err::UnknownLocker.Fail(Thread.current)
|
||||
end
|
||||
|
||||
when SH
|
||||
if (count = sync_sh_locker[Thread.current]).nil?
|
||||
Err::UnknownLocker.Fail(Thread.current)
|
||||
else
|
||||
if (sync_sh_locker[Thread.current] = count - 1) == 0
|
||||
sync_sh_locker.delete(Thread.current)
|
||||
if sync_sh_locker.empty? and sync_ex_count == 0
|
||||
self.sync_mode = UN
|
||||
runnable = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if (count = sync_sh_locker[Thread.current]).nil?
|
||||
Err::UnknownLocker.Fail(Thread.current)
|
||||
else
|
||||
if (sync_sh_locker[Thread.current] = count - 1) == 0
|
||||
sync_sh_locker.delete(Thread.current)
|
||||
if sync_sh_locker.empty? and sync_ex_count == 0
|
||||
self.sync_mode = UN
|
||||
runnable = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if runnable
|
||||
if sync_upgrade_waiting.size > 0
|
||||
th, count = sync_upgrade_waiting.shift
|
||||
sync_sh_locker[th] = count
|
||||
th.wakeup
|
||||
wakeup_threads.push th
|
||||
else
|
||||
wait = sync_waiting
|
||||
self.sync_waiting = []
|
||||
for th in wait
|
||||
th.wakeup
|
||||
wakeup_threads.push th
|
||||
end
|
||||
end
|
||||
if sync_upgrade_waiting.size > 0
|
||||
th, count = sync_upgrade_waiting.shift
|
||||
sync_sh_locker[th] = count
|
||||
th.wakeup
|
||||
wakeup_threads.push th
|
||||
else
|
||||
wait = sync_waiting
|
||||
self.sync_waiting = []
|
||||
for th in wait
|
||||
th.wakeup
|
||||
wakeup_threads.push th
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for th in wakeup_threads
|
||||
|
@ -263,34 +263,34 @@ module Sync_m
|
|||
when SH
|
||||
case sync_mode
|
||||
when UN
|
||||
self.sync_mode = m
|
||||
sync_sh_locker[Thread.current] = 1
|
||||
ret = true
|
||||
self.sync_mode = m
|
||||
sync_sh_locker[Thread.current] = 1
|
||||
ret = true
|
||||
when SH
|
||||
count = 0 unless count = sync_sh_locker[Thread.current]
|
||||
sync_sh_locker[Thread.current] = count + 1
|
||||
ret = true
|
||||
count = 0 unless count = sync_sh_locker[Thread.current]
|
||||
sync_sh_locker[Thread.current] = count + 1
|
||||
ret = true
|
||||
when EX
|
||||
# in EX mode, lock will upgrade to EX lock
|
||||
if sync_ex_locker == Thread.current
|
||||
self.sync_ex_count = sync_ex_count + 1
|
||||
ret = true
|
||||
else
|
||||
ret = false
|
||||
end
|
||||
# in EX mode, lock will upgrade to EX lock
|
||||
if sync_ex_locker == Thread.current
|
||||
self.sync_ex_count = sync_ex_count + 1
|
||||
ret = true
|
||||
else
|
||||
ret = false
|
||||
end
|
||||
end
|
||||
when EX
|
||||
if sync_mode == UN or
|
||||
sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current)
|
||||
self.sync_mode = m
|
||||
self.sync_ex_locker = Thread.current
|
||||
self.sync_ex_count = 1
|
||||
ret = true
|
||||
sync_mode == SH && sync_sh_locker.size == 1 && sync_sh_locker.include?(Thread.current)
|
||||
self.sync_mode = m
|
||||
self.sync_ex_locker = Thread.current
|
||||
self.sync_ex_count = 1
|
||||
ret = true
|
||||
elsif sync_mode == EX && sync_ex_locker == Thread.current
|
||||
self.sync_ex_count = sync_ex_count + 1
|
||||
ret = true
|
||||
self.sync_ex_count = sync_ex_count + 1
|
||||
ret = true
|
||||
else
|
||||
ret = false
|
||||
ret = false
|
||||
end
|
||||
else
|
||||
Err::LockModeFailer.Fail mode
|
||||
|
|
|
@ -165,7 +165,7 @@ class Tempfile < DelegateClass(File)
|
|||
__setobj__(@tmpfile)
|
||||
end
|
||||
|
||||
def _close # :nodoc:
|
||||
def _close # :nodoc:
|
||||
@tmpfile.close if @tmpfile
|
||||
@tmpfile = nil
|
||||
@data[1] = nil if @data
|
||||
|
@ -316,13 +316,13 @@ class Tempfile < DelegateClass(File)
|
|||
tempfile = new(*args)
|
||||
|
||||
if block_given?
|
||||
begin
|
||||
yield(tempfile)
|
||||
ensure
|
||||
tempfile.close
|
||||
end
|
||||
begin
|
||||
yield(tempfile)
|
||||
ensure
|
||||
tempfile.close
|
||||
end
|
||||
else
|
||||
tempfile
|
||||
tempfile
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#
|
||||
# thread.rb - thread support classes
|
||||
# by Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
# thread.rb - thread support classes
|
||||
# by Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
#
|
||||
# Copyright (C) 2001 Yukihiro Matsumoto
|
||||
# Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
|
||||
|
@ -144,7 +144,7 @@ class Queue
|
|||
def initialize
|
||||
@que = []
|
||||
@waiting = []
|
||||
@que.taint # enable tainted comunication
|
||||
@que.taint # enable tainted comunication
|
||||
@waiting.taint
|
||||
self.taint
|
||||
@mutex = Mutex.new
|
||||
|
@ -252,7 +252,7 @@ class SizedQueue < Queue
|
|||
raise ArgumentError, "queue size must be positive" unless max > 0
|
||||
@max = max
|
||||
@queue_wait = []
|
||||
@queue_wait.taint # enable tainted comunication
|
||||
@queue_wait.taint # enable tainted comunication
|
||||
super()
|
||||
end
|
||||
|
||||
|
@ -278,12 +278,12 @@ class SizedQueue < Queue
|
|||
}
|
||||
if diff
|
||||
diff.times do
|
||||
begin
|
||||
t = @queue_wait.shift
|
||||
t.run if t
|
||||
rescue ThreadError
|
||||
retry
|
||||
end
|
||||
begin
|
||||
t = @queue_wait.shift
|
||||
t.run if t
|
||||
rescue ThreadError
|
||||
retry
|
||||
end
|
||||
end
|
||||
end
|
||||
max
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#
|
||||
# thwait.rb - thread synchronization class
|
||||
# $Release Version: 0.9 $
|
||||
# $Revision: 1.3 $
|
||||
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd.)
|
||||
# $Release Version: 0.9 $
|
||||
# $Revision: 1.3 $
|
||||
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd.)
|
||||
|
||||
require "thread.rb"
|
||||
require "e2mmap.rb"
|
||||
|
@ -39,7 +39,7 @@ class ThreadsWait
|
|||
tw = ThreadsWait.new(*threads)
|
||||
if block_given?
|
||||
tw.all_waits do |th|
|
||||
yield th
|
||||
yield th
|
||||
end
|
||||
else
|
||||
tw.all_waits
|
||||
|
@ -91,11 +91,11 @@ class ThreadsWait
|
|||
@threads.concat threads
|
||||
for th in threads
|
||||
Thread.start(th) do |t|
|
||||
begin
|
||||
t.join
|
||||
ensure
|
||||
@wait_queue.push t
|
||||
end
|
||||
begin
|
||||
t.join
|
||||
ensure
|
||||
@wait_queue.push t
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,10 +23,10 @@ class Dir
|
|||
tmp = @@systmpdir
|
||||
else
|
||||
for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], @@systmpdir, '/tmp']
|
||||
if dir and stat = File.stat(dir) and stat.directory? and stat.writable?
|
||||
tmp = dir
|
||||
break
|
||||
end rescue nil
|
||||
if dir and stat = File.stat(dir) and stat.directory? and stat.writable?
|
||||
tmp = dir
|
||||
break
|
||||
end rescue nil
|
||||
end
|
||||
File.expand_path(tmp)
|
||||
end
|
||||
|
|
|
@ -130,9 +130,9 @@ class Tracer
|
|||
if block_given?
|
||||
on
|
||||
begin
|
||||
yield
|
||||
yield
|
||||
ensure
|
||||
off
|
||||
off
|
||||
end
|
||||
else
|
||||
set_trace_func method(:trace_func).to_proc
|
||||
|
@ -160,14 +160,14 @@ class Tracer
|
|||
|
||||
unless list = SCRIPT_LINES__[file]
|
||||
begin
|
||||
f = File::open(file)
|
||||
begin
|
||||
SCRIPT_LINES__[file] = list = f.readlines
|
||||
ensure
|
||||
f.close
|
||||
end
|
||||
f = File::open(file)
|
||||
begin
|
||||
SCRIPT_LINES__[file] = list = f.readlines
|
||||
ensure
|
||||
f.close
|
||||
end
|
||||
rescue
|
||||
SCRIPT_LINES__[file] = list = []
|
||||
SCRIPT_LINES__[file] = list = []
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -198,19 +198,19 @@ class Tracer
|
|||
|
||||
Tracer::stdout_mutex.synchronize do
|
||||
if EVENT_SYMBOL[event]
|
||||
stdout.printf("<%d>", $$) if Tracer::display_process_id?
|
||||
stdout.printf("#%d:", get_thread_no) if Tracer::display_thread_id?
|
||||
if line == 0
|
||||
source = "?\n"
|
||||
else
|
||||
source = get_line(file, line)
|
||||
end
|
||||
printf("%s:%d:%s:%s: %s",
|
||||
file,
|
||||
line,
|
||||
klass || '',
|
||||
EVENT_SYMBOL[event],
|
||||
source)
|
||||
stdout.printf("<%d>", $$) if Tracer::display_process_id?
|
||||
stdout.printf("#%d:", get_thread_no) if Tracer::display_thread_id?
|
||||
if line == 0
|
||||
source = "?\n"
|
||||
else
|
||||
source = get_line(file, line)
|
||||
end
|
||||
printf("%s:%d:%s:%s: %s",
|
||||
file,
|
||||
line,
|
||||
klass || '',
|
||||
EVENT_SYMBOL[event],
|
||||
source)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
74
lib/un.rb
74
lib/un.rb
|
@ -69,9 +69,9 @@ end
|
|||
#
|
||||
# ruby -run -e cp -- [OPTION] SOURCE DEST
|
||||
#
|
||||
# -p preserve file attributes if possible
|
||||
# -r copy recursively
|
||||
# -v verbose
|
||||
# -p preserve file attributes if possible
|
||||
# -r copy recursively
|
||||
# -v verbose
|
||||
#
|
||||
|
||||
def cp
|
||||
|
@ -90,9 +90,9 @@ end
|
|||
#
|
||||
# ruby -run -e ln -- [OPTION] TARGET LINK_NAME
|
||||
#
|
||||
# -s make symbolic links instead of hard links
|
||||
# -f remove existing destination files
|
||||
# -v verbose
|
||||
# -s make symbolic links instead of hard links
|
||||
# -f remove existing destination files
|
||||
# -v verbose
|
||||
#
|
||||
|
||||
def ln
|
||||
|
@ -111,7 +111,7 @@ end
|
|||
#
|
||||
# ruby -run -e mv -- [OPTION] SOURCE DEST
|
||||
#
|
||||
# -v verbose
|
||||
# -v verbose
|
||||
#
|
||||
|
||||
def mv
|
||||
|
@ -127,9 +127,9 @@ end
|
|||
#
|
||||
# ruby -run -e rm -- [OPTION] FILE
|
||||
#
|
||||
# -f ignore nonexistent files
|
||||
# -r remove the contents of directories recursively
|
||||
# -v verbose
|
||||
# -f ignore nonexistent files
|
||||
# -r remove the contents of directories recursively
|
||||
# -v verbose
|
||||
#
|
||||
|
||||
def rm
|
||||
|
@ -146,8 +146,8 @@ end
|
|||
#
|
||||
# ruby -run -e mkdir -- [OPTION] DIR
|
||||
#
|
||||
# -p no error if existing, make parent directories as needed
|
||||
# -v verbose
|
||||
# -p no error if existing, make parent directories as needed
|
||||
# -v verbose
|
||||
#
|
||||
|
||||
def mkdir
|
||||
|
@ -163,8 +163,8 @@ end
|
|||
#
|
||||
# ruby -run -e rmdir -- [OPTION] DIR
|
||||
#
|
||||
# -p remove DIRECTORY and its ancestors.
|
||||
# -v verbose
|
||||
# -p remove DIRECTORY and its ancestors.
|
||||
# -v verbose
|
||||
#
|
||||
|
||||
def rmdir
|
||||
|
@ -179,10 +179,10 @@ end
|
|||
#
|
||||
# ruby -run -e install -- [OPTION] SOURCE DEST
|
||||
#
|
||||
# -p apply access/modification times of SOURCE files to
|
||||
# corresponding destination files
|
||||
# -m set permission mode (as in chmod), instead of 0755
|
||||
# -v verbose
|
||||
# -p apply access/modification times of SOURCE files to
|
||||
# corresponding destination files
|
||||
# -m set permission mode (as in chmod), instead of 0755
|
||||
# -v verbose
|
||||
#
|
||||
|
||||
def install
|
||||
|
@ -200,7 +200,7 @@ end
|
|||
#
|
||||
# ruby -run -e chmod -- [OPTION] OCTAL-MODE FILE
|
||||
#
|
||||
# -v verbose
|
||||
# -v verbose
|
||||
#
|
||||
|
||||
def chmod
|
||||
|
@ -215,7 +215,7 @@ end
|
|||
#
|
||||
# ruby -run -e touch -- [OPTION] FILE
|
||||
#
|
||||
# -v verbose
|
||||
# -v verbose
|
||||
#
|
||||
|
||||
def touch
|
||||
|
@ -229,9 +229,9 @@ end
|
|||
#
|
||||
# ruby -run -e wait_writable -- [OPTION] FILE
|
||||
#
|
||||
# -n RETRY count to retry
|
||||
# -w SEC each wait time in seconds
|
||||
# -v verbose
|
||||
# -n RETRY count to retry
|
||||
# -w SEC each wait time in seconds
|
||||
# -v verbose
|
||||
#
|
||||
|
||||
def wait_writable
|
||||
|
@ -260,15 +260,15 @@ end
|
|||
#
|
||||
# ruby -run -e mkmf -- [OPTION] EXTNAME [OPTION]
|
||||
#
|
||||
# -d ARGS run dir_config
|
||||
# -h ARGS run have_header
|
||||
# -l ARGS run have_library
|
||||
# -f ARGS run have_func
|
||||
# -v ARGS run have_var
|
||||
# -t ARGS run have_type
|
||||
# -m ARGS run have_macro
|
||||
# -c ARGS run have_const
|
||||
# --vendor install to vendor_ruby
|
||||
# -d ARGS run dir_config
|
||||
# -h ARGS run have_header
|
||||
# -l ARGS run have_library
|
||||
# -f ARGS run have_func
|
||||
# -v ARGS run have_var
|
||||
# -t ARGS run have_type
|
||||
# -m ARGS run have_macro
|
||||
# -c ARGS run have_const
|
||||
# --vendor install to vendor_ruby
|
||||
#
|
||||
|
||||
def mkmf
|
||||
|
@ -337,11 +337,11 @@ def help
|
|||
all = argv.empty?
|
||||
open(__FILE__) do |me|
|
||||
while me.gets("##\n")
|
||||
if help = me.gets("\n\n")
|
||||
if all or argv.delete help[/-e \w+/].sub(/-e /, "")
|
||||
print help.gsub(/^# ?/, "")
|
||||
end
|
||||
end
|
||||
if help = me.gets("\n\n")
|
||||
if all or argv.delete help[/-e \w+/].sub(/-e /, "")
|
||||
print help.gsub(/^# ?/, "")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -120,71 +120,71 @@ module URI
|
|||
def split(uri)
|
||||
case uri
|
||||
when ''
|
||||
# null uri
|
||||
# null uri
|
||||
|
||||
when @regexp[:ABS_URI]
|
||||
scheme, opaque, userinfo, host, port,
|
||||
registry, path, query, fragment = $~[1..-1]
|
||||
scheme, opaque, userinfo, host, port,
|
||||
registry, path, query, fragment = $~[1..-1]
|
||||
|
||||
# URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
|
||||
# URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
|
||||
|
||||
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
||||
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
||||
# opaque_part = uric_no_slash *uric
|
||||
# absoluteURI = scheme ":" ( hier_part | opaque_part )
|
||||
# hier_part = ( net_path | abs_path ) [ "?" query ]
|
||||
# opaque_part = uric_no_slash *uric
|
||||
|
||||
# abs_path = "/" path_segments
|
||||
# net_path = "//" authority [ abs_path ]
|
||||
# abs_path = "/" path_segments
|
||||
# net_path = "//" authority [ abs_path ]
|
||||
|
||||
# authority = server | reg_name
|
||||
# server = [ [ userinfo "@" ] hostport ]
|
||||
# authority = server | reg_name
|
||||
# server = [ [ userinfo "@" ] hostport ]
|
||||
|
||||
if !scheme
|
||||
raise InvalidURIError,
|
||||
"bad URI(absolute but no scheme): #{uri}"
|
||||
end
|
||||
if !opaque && (!path && (!host && !registry))
|
||||
raise InvalidURIError,
|
||||
"bad URI(absolute but no path): #{uri}"
|
||||
end
|
||||
if !scheme
|
||||
raise InvalidURIError,
|
||||
"bad URI(absolute but no scheme): #{uri}"
|
||||
end
|
||||
if !opaque && (!path && (!host && !registry))
|
||||
raise InvalidURIError,
|
||||
"bad URI(absolute but no path): #{uri}"
|
||||
end
|
||||
|
||||
when @regexp[:REL_URI]
|
||||
scheme = nil
|
||||
opaque = nil
|
||||
scheme = nil
|
||||
opaque = nil
|
||||
|
||||
userinfo, host, port, registry,
|
||||
rel_segment, abs_path, query, fragment = $~[1..-1]
|
||||
if rel_segment && abs_path
|
||||
path = rel_segment + abs_path
|
||||
elsif rel_segment
|
||||
path = rel_segment
|
||||
elsif abs_path
|
||||
path = abs_path
|
||||
end
|
||||
userinfo, host, port, registry,
|
||||
rel_segment, abs_path, query, fragment = $~[1..-1]
|
||||
if rel_segment && abs_path
|
||||
path = rel_segment + abs_path
|
||||
elsif rel_segment
|
||||
path = rel_segment
|
||||
elsif abs_path
|
||||
path = abs_path
|
||||
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 ]
|
||||
# abs_path = "/" path_segments
|
||||
# rel_path = rel_segment [ abs_path ]
|
||||
# net_path = "//" authority [ abs_path ]
|
||||
# abs_path = "/" path_segments
|
||||
# rel_path = rel_segment [ abs_path ]
|
||||
|
||||
# authority = server | reg_name
|
||||
# server = [ [ userinfo "@" ] hostport ]
|
||||
# authority = server | reg_name
|
||||
# server = [ [ userinfo "@" ] hostport ]
|
||||
|
||||
else
|
||||
raise InvalidURIError, "bad URI(is not URI?): #{uri}"
|
||||
raise InvalidURIError, "bad URI(is not URI?): #{uri}"
|
||||
end
|
||||
|
||||
path = '' if !path && !opaque # (see RFC2396 Section 5.2)
|
||||
ret = [
|
||||
scheme,
|
||||
userinfo, host, port, # X
|
||||
registry, # X
|
||||
path, # Y
|
||||
opaque, # Y
|
||||
query,
|
||||
fragment
|
||||
scheme,
|
||||
userinfo, host, port, # X
|
||||
registry, # X
|
||||
path, # Y
|
||||
opaque, # Y
|
||||
query,
|
||||
fragment
|
||||
]
|
||||
return ret
|
||||
end
|
||||
|
@ -202,22 +202,22 @@ module URI
|
|||
#
|
||||
# == Usage
|
||||
#
|
||||
# p = URI::Parser.new
|
||||
# p.parse("ldap://ldap.example.com/dc=example?user=john")
|
||||
# #=> #<URI::LDAP:0x00000000b9e7e8 URL:ldap://ldap.example.com/dc=example?user=john>
|
||||
# p = URI::Parser.new
|
||||
# p.parse("ldap://ldap.example.com/dc=example?user=john")
|
||||
# #=> #<URI::LDAP:0x00000000b9e7e8 URL:ldap://ldap.example.com/dc=example?user=john>
|
||||
#
|
||||
def parse(uri)
|
||||
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)
|
||||
URI.scheme_list[scheme.upcase].new(scheme, userinfo, host, port,
|
||||
URI.scheme_list[scheme.upcase].new(scheme, userinfo, host, port,
|
||||
registry, path, opaque, query,
|
||||
fragment, self)
|
||||
else
|
||||
Generic.new(scheme, userinfo, host, port,
|
||||
registry, path, opaque, query,
|
||||
fragment, self)
|
||||
Generic.new(scheme, userinfo, host, port,
|
||||
registry, path, opaque, query,
|
||||
fragment, self)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -239,9 +239,9 @@ module URI
|
|||
|
||||
#
|
||||
# :call-seq:
|
||||
# extract( str )
|
||||
# extract( str, schemes )
|
||||
# extract( str, schemes ) {|item| block }
|
||||
# extract( str )
|
||||
# extract( str, schemes )
|
||||
# extract( str, schemes ) {|item| block }
|
||||
#
|
||||
# == Args
|
||||
#
|
||||
|
@ -260,12 +260,12 @@ module URI
|
|||
#
|
||||
def extract(str, schemes = nil, &block)
|
||||
if block_given?
|
||||
str.scan(make_regexp(schemes)) { yield $& }
|
||||
nil
|
||||
str.scan(make_regexp(schemes)) { yield $& }
|
||||
nil
|
||||
else
|
||||
result = []
|
||||
str.scan(make_regexp(schemes)) { result.push $& }
|
||||
result
|
||||
result = []
|
||||
str.scan(make_regexp(schemes)) { result.push $& }
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -273,16 +273,16 @@ module URI
|
|||
# unless +schemes+ is provided. Then it is a Regexp.union with self.pattern[:X_ABS_URI]
|
||||
def make_regexp(schemes = nil)
|
||||
unless schemes
|
||||
@regexp[:ABS_URI_REF]
|
||||
@regexp[:ABS_URI_REF]
|
||||
else
|
||||
/(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/x
|
||||
/(?=#{Regexp.union(*schemes)}:)#{@pattern[:X_ABS_URI]}/x
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# :call-seq:
|
||||
# escape( str )
|
||||
# escape( str, unsafe )
|
||||
# escape( str )
|
||||
# escape( str, unsafe )
|
||||
#
|
||||
# == Args
|
||||
#
|
||||
|
@ -313,8 +313,8 @@ module URI
|
|||
|
||||
#
|
||||
# :call-seq:
|
||||
# unescape( str )
|
||||
# unescape( str, unsafe )
|
||||
# unescape( str )
|
||||
# unescape( str, unsafe )
|
||||
#
|
||||
# == Args
|
||||
#
|
||||
|
@ -365,7 +365,7 @@ module URI
|
|||
# hostname = *( domainlabel "." ) toplabel [ "." ]
|
||||
# reg-name = *( unreserved / pct-encoded / sub-delims ) # RFC3986
|
||||
unless hostname
|
||||
ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-.]|%\\h\\h)+"
|
||||
ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-.]|%\\h\\h)+"
|
||||
end
|
||||
|
||||
# RFC 2373, APPENDIX B:
|
||||
|
|
|
@ -174,7 +174,7 @@ module URI
|
|||
path, opaque,
|
||||
query,
|
||||
fragment,
|
||||
parser = DEFAULT_PARSER,
|
||||
parser = DEFAULT_PARSER,
|
||||
arg_check = false)
|
||||
@scheme = nil
|
||||
@user = nil
|
||||
|
@ -1321,11 +1321,13 @@ module URI
|
|||
self.query, self.fragment, parser)
|
||||
|
||||
if rel.userinfo != oth.userinfo ||
|
||||
rel.host.to_s.downcase != oth.host.to_s.downcase ||
|
||||
rel.port != oth.port
|
||||
if self.userinfo.nil? && self.host.nil?
|
||||
return self, self.dup
|
||||
end
|
||||
rel.host.to_s.downcase != oth.host.to_s.downcase ||
|
||||
rel.port != oth.port
|
||||
|
||||
if self.userinfo.nil? && self.host.nil?
|
||||
return self, self.dup
|
||||
end
|
||||
|
||||
rel.set_port(nil) if rel.port == oth.default_port
|
||||
return rel, rel
|
||||
end
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
# Usage:
|
||||
# foo = Object.new
|
||||
# foo = Object.new
|
||||
# p foo.to_s # original's class
|
||||
# p foo.to_s # original's class
|
||||
# foo = WeakRef.new(foo)
|
||||
# p foo.to_s # should be same class
|
||||
# p foo.to_s # should be same class
|
||||
# ObjectSpace.garbage_collect
|
||||
# p foo.to_s # should raise exception (recycled)
|
||||
# p foo.to_s # should raise exception (recycled)
|
||||
|
||||
require "delegate"
|
||||
require 'thread'
|
||||
|
@ -24,16 +24,16 @@ class WeakRef < Delegator
|
|||
@@mutex.synchronize {
|
||||
rids = @@id_map[id]
|
||||
if rids
|
||||
for rid in rids
|
||||
@@id_rev_map.delete(rid)
|
||||
end
|
||||
@@id_map.delete(id)
|
||||
for rid in rids
|
||||
@@id_rev_map.delete(rid)
|
||||
end
|
||||
@@id_map.delete(id)
|
||||
end
|
||||
rid = @@id_rev_map[id]
|
||||
if rid
|
||||
@@id_rev_map.delete(id)
|
||||
@@id_map[rid].delete(id)
|
||||
@@id_map.delete(rid) if @@id_map[rid].empty?
|
||||
@@id_rev_map.delete(id)
|
||||
@@id_map[rid].delete(id)
|
||||
@@id_map.delete(rid) if @@id_map[rid].empty?
|
||||
end
|
||||
}
|
||||
}
|
||||
|
@ -71,10 +71,10 @@ end
|
|||
if __FILE__ == $0
|
||||
# require 'thread'
|
||||
foo = Object.new
|
||||
p foo.to_s # original's class
|
||||
p foo.to_s # original's class
|
||||
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)
|
||||
end
|
||||
|
|
|
@ -743,7 +743,7 @@ module XMLRPC
|
|||
end
|
||||
|
||||
alias :on_stag :startElement
|
||||
alias :on_etag :endElement
|
||||
alias :on_etag :endElement
|
||||
|
||||
def on_stag_end(name); end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue