1
0
Fork 0
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:
drbrain 2011-05-18 21:19:18 +00:00
parent 34276148c4
commit 7bbf2f3085
67 changed files with 3823 additions and 3814 deletions

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,6 +1,6 @@
=begin
external service
Copyright (c) 2000,2002 Masatoshi SEKI
Copyright (c) 2000,2002 Masatoshi SEKI
=end
require 'drb/drb'

View file

@ -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}")

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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 &gt; 0 &amp; a &lt; 10?
# is a &gt; 0 &amp; a &lt; 10?
#
def html_escape(s)
s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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
#

View file

@ -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

View file

@ -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")

View file

@ -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

View file

@ -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")

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
#

View file

@ -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.

View file

@ -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 )

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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?

View file

@ -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 ]

View file

@ -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]}

View file

@ -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 ]

View file

@ -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 )

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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?

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)
#
# --
#

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)
#
# --
#

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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