summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/base64.rb45
-rw-r--r--lib/cgi-lib.rb39
-rw-r--r--lib/complex.rb14
-rw-r--r--lib/date.rb91
-rw-r--r--lib/debug.rb12
-rw-r--r--lib/delegate.rb100
-rw-r--r--lib/e2mmap.rb77
-rw-r--r--lib/eregex.rb11
-rw-r--r--lib/finalize.rb66
-rw-r--r--lib/find.rb4
-rw-r--r--lib/ftools.rb31
-rw-r--r--lib/ftplib.rb1123
-rw-r--r--lib/getopts.rb3
-rw-r--r--lib/importenv.rb15
-rw-r--r--lib/jcode.rb23
-rw-r--r--lib/mailread.rb5
-rw-r--r--lib/mathn.rb5
-rw-r--r--lib/matrix.rb239
-rw-r--r--lib/mkmf.rb144
-rw-r--r--lib/mutex_m.rb60
-rw-r--r--lib/observer.rb8
-rw-r--r--lib/parsearg.rb5
-rw-r--r--lib/parsedate.rb81
-rw-r--r--lib/ping.rb33
-rw-r--r--lib/pstore.rb39
-rw-r--r--lib/rational.rb9
-rw-r--r--lib/shellwords.rb16
-rw-r--r--lib/sync.rb13
-rw-r--r--lib/thread.rb163
-rw-r--r--lib/thwait.rb113
-rw-r--r--lib/tracer.rb147
-rw-r--r--lib/weakref.rb39
32 files changed, 1715 insertions, 1058 deletions
diff --git a/lib/base64.rb b/lib/base64.rb
index 96208a6..d7461d8 100644
--- a/lib/base64.rb
+++ b/lib/base64.rb
@@ -1,50 +1,25 @@
-def decode64(str)
- string = ''
- for line in str.split("\n")
- line.delete!('^A-Za-z0-9+/') # remove non-base64 chars
- line.tr!('A-Za-z0-9+/', ' -_') # convert to uuencoded format
- len = ["#{32 + line.length * 3 / 4}"].pack("c")
- # compute length byte
- string += "#{len}#{line}".unpack("u") # uudecode and concatenate
- end
- return string
-end
+require "kconv"
-def j2e(str)
- while str =~ /\033\$B([^\033]*)\033\(B/
- s = $1
- pre, post = $`, $'
- s.gsub!(/./) { |ch|
- (ch[0]|0x80).chr
- }
- str = pre + s + post
- end
-# str.gsub!(/\033\$B([^\033]*)\033\(B/) {
-# $1.gsub!(/./) { |ch|
-# (ch[0]|0x80).chr
-# }
-# }
- str
+def decode64(str)
+ str.unpack("m")[0]
end
def decode_b(str)
str.gsub!(/=\?ISO-2022-JP\?B\?([!->@-~]+)\?=/i) {
decode64($1)
}
+ str = Kconv::toeuc(str)
+ str.gsub!(/=\?SHIFT_JIS\?B\?([!->@-~]+)\?=/i) {
+ decode64($1)
+ }
+ str = Kconv::toeuc(str)
str.gsub!(/\n/, ' ')
str.gsub!(/\0/, '')
- j2e(str)
+ str
end
def encode64(bin)
- encode = ""
- pad = 0
- [bin].pack("u").each do |uu|
- len = (2 + (uu[0] - 32)* 4) / 3
- encode << uu[1, len].tr('` -_', 'AA-Za-z0-9+/')
- pad += uu.length - 2 - len
- end
- encode + "=" * (pad % 3)
+ [bin].pack("m")
end
def b64encode(bin, len = 60)
diff --git a/lib/cgi-lib.rb b/lib/cgi-lib.rb
index 5234e04..7033f0f 100644
--- a/lib/cgi-lib.rb
+++ b/lib/cgi-lib.rb
@@ -1,4 +1,3 @@
-#!/usr/local/bin/ruby
#
# Get CGI String
#
@@ -7,26 +6,26 @@
# foo = CGI.new
# foo['field'] <== value of 'field'
# foo.keys <== array of fields
-# foo.inputs <== hash of { <field> => <value> }
+# and foo has Hash class methods
# if running on Windows(IIS or PWS) then change cwd.
if ENV['SERVER_SOFTWARE'] =~ /^Microsoft-/ then
Dir.chdir ENV['PATH_TRANSLATED'].sub(/[^\\]+$/, '')
end
-require "shellwords.rb"
+require "delegate"
-class CGI
- include Shellwords
+class CGI < SimpleDelegator
attr("inputs")
# original is CGI.pm
def read_from_cmdline
- words = shellwords(if not ARGV.empty? then
+ require "shellwords.rb"
+ words = Shellwords.shellwords(if not ARGV.empty? then
ARGV.join(' ')
else
- print "(offline mode: enter name=value pairs on standard input)\n"
+ STDERR.print "(offline mode: enter name=value pairs on standard input)\n" if STDIN.tty?
readlines.join(' ').gsub(/\n/, '')
end.gsub(/\\=/, '%3D').gsub(/\\&/, '%26'))
@@ -47,32 +46,32 @@ class CGI
end
module_function :escape, :unescape
- def initialize
- # exception messages should be printed to stdout.
- STDERR.reopen(STDOUT)
+ def initialize(input = $stdin)
@inputs = {}
case ENV['REQUEST_METHOD']
when "GET"
+ # exception messages should be printed to stdout.
+ STDERR.reopen(STDOUT)
ENV['QUERY_STRING'] or ""
when "POST"
- $stdin.read ENV['CONTENT_LENGTH'].to_i
+ # exception messages should be printed to stdout.
+ STDERR.reopen(STDOUT)
+ input.read Integer(ENV['CONTENT_LENGTH'])
else
read_from_cmdline
end.split(/&/).each do |x|
key, val = x.split(/=/,2).collect{|x|unescape(x)}
- @inputs[key] += ("\0" if @inputs[key]) + (val or "")
+ if @inputs.include?(key)
+ @inputs[key] += "\0" + (val or "")
+ else
+ @inputs[key] = (val or "")
+ end
end
- end
- def keys
- @inputs.keys
+ super(@inputs)
end
- def [](key)
- @inputs[key]
- end
-
def CGI.message(msg, title = "")
print "Content-type: text/html\n\n"
print "<html><head><title>"
@@ -84,7 +83,7 @@ class CGI
end
def CGI.error
- m = $!.dup
+ m = $!.to_s.dup
m.gsub!(/&/, '&amp;')
m.gsub!(/</, '&lt;')
m.gsub!(/>/, '&gt;')
diff --git a/lib/complex.rb b/lib/complex.rb
index aa5d219..59caad6 100644
--- a/lib/complex.rb
+++ b/lib/complex.rb
@@ -1,8 +1,8 @@
#
# complex.rb -
# $Release Version: 0.5 $
-# $Revision: 1.1 $
-# $Date: 1996/11/11 04:25:19 $
+# $Revision: 1.3 $
+# $Date: 1998/07/08 10:05:28 $
# by Keiju ISHITSUKA(SHL Japan Inc.)
#
# --
@@ -59,6 +59,7 @@ def Complex(a, b = 0)
end
class Complex < Numeric
+ @RCS_ID='-$Id: complex.rb,v 1.3 1998/07/08 10:05:28 keiju Exp keiju $-'
def Complex.generic?(other)
other.kind_of?(Integer) or
@@ -284,6 +285,11 @@ class Complex < Numeric
@real ^ @image
end
+ def inspect
+ sprintf("Complex(%s, %s)", @real.inspect, @image.inspect)
+ end
+
+
I = Complex(0,1)
attr :real
@@ -396,7 +402,7 @@ module Math
cos!(z)
else
Complex(cos!(z.real)*cosh!(z.image),
- sin!(z.real)*sinh!(z.image))
+ -sin!(z.real)*sinh!(z.image))
end
end
@@ -405,7 +411,7 @@ module Math
sin!(z)
else
Complex(sin!(z.real)*cosh!(z.image),
- -cos!(z.real)*sinh!(z.image))
+ cos!(z.real)*sinh!(z.image))
end
end
diff --git a/lib/date.rb b/lib/date.rb
index 998c2e8..9de49bc 100644
--- a/lib/date.rb
+++ b/lib/date.rb
@@ -1,8 +1,8 @@
#
# Date.rb -
# $Release Version: $
-# $Revision: 1.2 $
-# $Date: 1997/02/14 11:05:29 $
+# $Revision: 1.1.1.1.4.5 $
+# $Date: 1998/03/03 02:39:34 $
# by Yasuo OHBA(SHL Japan Inc. Technology Dept.)
#
# --
@@ -17,15 +17,34 @@
class Date
include Comparable
+ Weektag = [
+ "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
+ ]
+
+ Monthtag = [
+ "January","February","March","April", "May", "June","July",
+ "August", "September", "October", "November", "December"
+ ]
+
+ Monthtab = {
+ "jan"=>1, "feb"=>2, "mar"=>3, "apr"=>4, "may"=>5, "jun"=>6,
+ "jul"=>7, "aug"=>8, "sep"=>9, "oct"=>10, "nov"=>11, "dec"=>12
+ }
+
def initialize(y = 1, m = 1, d = 1)
- if y.kind_of?(String) && y.size == 8
- @year = y[0,4].to_i
- @month = y[4,2].to_i
- @day = y[6,2].to_i
+ if y.kind_of?(String)
+ case y
+ when /(\d\d\d\d)-?(?:(\d\d)-?(\d\d)?)?/
+ @year = $1.to_i
+ @month = if $2 then $2.to_i else 1 end
+ @day = if $3 then $3.to_i else 1 end
+ else
+ require 'parsedate'
+ @year, @month, @day = ParseDate.parsedate(y)
+ end
else
if m.kind_of?(String)
- ml = {"jan"=>1, "feb"=>2, "mar"=>3, "apr"=>4, "may"=>5, "jun"=>6, "jul"=>7, "aug"=>8, "sep"=>9, "oct"=>10, "nov"=>11, "dec"=>12}
- m = ml[m.downcase]
+ m = Monthtab[m.downcase]
if m.nil?
raise ArgumentError, "Wrong argument. (month)"
end
@@ -53,25 +72,35 @@ class Date
def period
return Date.period!(@year, @month, @day)
end
-
+
+ def jd
+ return period + 1721423
+ end
+
+ def mjd
+ return jd - 2400000.5
+ end
+
+ def to_s
+ format("%.3s, %.3s %2d %4d", name_of_week, name_of_month, @day, @year)
+ end
+
+ def inspect
+ to_s
+ end
+
def day_of_week
- dl = Date.daylist(@year)
- d = Date.jan1!(@year)
- for m in 1..(@month - 1)
- d += dl[m]
- end
- d += @day - 1
- if @year == 1752 && @month == 9 && @day >= 14
- d -= (14 - 3)
- end
- return (d % 7)
+ return (period + 5) % 7
end
- Weektag = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
def name_of_week
return Weektag[self.day_of_week]
end
+ def name_of_month
+ return Monthtag[@month-1]
+ end
+
def +(o)
if o.kind_of?(Numeric)
d = Integer(self.period + o)
@@ -80,6 +109,9 @@ class Date
else
raise TypeError, "Illegal type. (Integer or Date)"
end
+ if d <= 0
+ raise ArgumentError, "argument out of range. (self > other)"
+ end
return Date.at(d)
end
@@ -117,14 +149,13 @@ class Date
end
def leapyear?
- if Date.leapyear(@year) == 1
- return FALSE
- else
- return TRUE
- end
+ Date.leapyear(@year) != 1
end
def _check_date
+ if @year == nil or @month == nil or @day == nil
+ raise ArgumentError, "argument contains nil"
+ end
m = Date.daylist(@year)
if @month < 1 || @month > 12
raise ArgumentError, "argument(month) out of range."
@@ -151,7 +182,7 @@ end
def Date.at(d)
if d.kind_of? Time
- return Date.new(1900+d.year, d.mon+1, d.mday)
+ return Date.new(d.year, d.mon, d.mday)
end
if d.kind_of? Date
return Date.at(d.period)
@@ -189,10 +220,10 @@ def Date.period!(y, m, d)
p += dl[mm]
end
p += (y - 1) * 365 + ((y - 1) / 4.0).to_i
- if (y - 1) > 1752
- p -= ((y - 1 - 1752) / 100.0).to_i
- p += ((y - 1 - 1752) / 400.0).to_i
- p -= (14 - 3)
+ if y > 1752
+ p -= ((y - 1) / 100.0).to_i
+ p += ((y - 1) / 400.0).to_i
+ p += 2
elsif y == 1752 && m == 9 && d >= 14 && d <= 30
p -= (14 - 3)
end
diff --git a/lib/debug.rb b/lib/debug.rb
index 432c7b4..90270a3 100644
--- a/lib/debug.rb
+++ b/lib/debug.rb
@@ -11,6 +11,8 @@ class DEBUGGER__
@scripts = {}
end
+ DEBUG_LAST_CMD = []
+
def interrupt
@stop_next = 1
end
@@ -40,6 +42,11 @@ class DEBUGGER__
STDOUT.flush
while input = STDIN.gets
input.chop!
+ if input == ""
+ input = DEBUG_LAST_CMD[0]
+ else
+ DEBUG_LAST_CMD[0] = input
+ end
case input
when /^b(reak)?\s+(([^:\n]+:)?.+)/
pos = $2
@@ -169,7 +176,7 @@ class DEBUGGER__
printf "no sourcefile available for %s\n", file
end
when /^p\s+/
- p debug_eval($', binding)
+ p debug_eval($', binding) #'
else
v = debug_eval(input, binding)
p v unless v == nil
@@ -187,10 +194,13 @@ class DEBUGGER__
return "\n" unless line
return line
end
+ save = $DEBUG
begin
+ $DEBUG = FALSE
f = open(file)
lines = @scripts[file] = f.readlines
rescue
+ $DEBUG = save
@scripts[file] = TRUE
return "\n"
end
diff --git a/lib/delegate.rb b/lib/delegate.rb
index e5943ce..0771f2f 100644
--- a/lib/delegate.rb
+++ b/lib/delegate.rb
@@ -1,26 +1,51 @@
# Delegation class that delegates even methods defined in super class,
# which can not be covered with normal method_missing hack.
#
-# Delegater is the abstract delegation class. Need to redefine
-# `__getobj__' method in the subclass. SimpleDelegater is the
+# Delegator is the abstract delegation class. Need to redefine
+# `__getobj__' method in the subclass. SimpleDelegator is the
# concrete subclass for simple delegation.
#
# Usage:
# foo = Object.new
-# foo = SimpleDelegater.new(foo)
-# foo.type # => Object
+# foo2 = SimpleDelegator.new(foo)
+# foo.hash == foo2.hash # => true
+#
+# Foo = DelegateClass(Array)
+#
+# class ExtArray<DelegateClass(Array)
+# ...
+# end
-class Delegater
+class Delegator
def initialize(obj)
- preserved = ["id", "equal?", "__getobj__"]
+ preserved = ::Kernel.instance_methods
+ preserved -= ["to_s","to_a","inspect","==","=~","==="]
for t in self.type.ancestors
preserved |= t.instance_methods
- break if t == Delegater
+ preserved |= t.private_instance_methods
+ preserved |= t.protected_instance_methods
+ break if t == Delegator
end
for method in obj.methods
next if preserved.include? method
- eval "def self.#{method}(*args); __getobj__.send :#{method}, *args; end"
+ eval <<-EOS
+ def self.#{method}(*args, &block)
+ begin
+ __getobj__.__send__(:#{method}, *args, &block)
+ rescue Exception
+ c = -caller(0).size
+ if /:in `__getobj__'$/ =~ $@[c-1] #`
+ n = 1
+ else
+ c -= 1
+ n = 2
+ end
+ $@[c,n] = nil
+ raise
+ end
+ end
+ EOS
end
end
@@ -30,7 +55,7 @@ class Delegater
end
-class SimpleDelegater<Delegater
+class SimpleDelegator<Delegator
def initialize(obj)
super
@@ -41,4 +66,61 @@ class SimpleDelegater<Delegater
@obj
end
+ def __setobj__(obj)
+ @obj = obj
+ end
+end
+
+# backward compatibility ^_^;;;
+Delegater = Delegator
+SimpleDelegater = SimpleDelegator
+
+#
+def DelegateClass(superclass)
+ klass = Class.new
+ methods = superclass.instance_methods
+ methods -= ::Kernel.instance_methods
+ methods |= ["to_s","to_a","inspect","==","=~","==="]
+ klass.module_eval <<-EOS
+ def initialize(obj)
+ @obj = obj
+ end
+ EOS
+ for method in methods
+ klass.module_eval <<-EOS
+ def #{method}(*args, &block)
+ begin
+ @obj.__send__(:#{method}, *args, &block)
+ rescue
+ $@[0,2] = nil
+ raise
+ end
+ end
+ EOS
+ end
+ return klass;
+ end
+
+if __FILE__ == $0
+ class ExtArray<DelegateClass(Array)
+ def initialize()
+ super([])
+ end
+ end
+
+ ary = ExtArray.new
+ p ary.type
+ ary.push 25
+ p ary
+
+ foo = Object.new
+ def foo.test
+ 25
+ end
+ def foo.error
+ raise 'this is OK'
+ end
+ foo2 = SimpleDelegator.new(foo)
+ p foo.test == foo2.test # => true
+ foo2.error # raise error!
end
diff --git a/lib/e2mmap.rb b/lib/e2mmap.rb
index d10657b..bf860dc 100644
--- a/lib/e2mmap.rb
+++ b/lib/e2mmap.rb
@@ -1,11 +1,22 @@
#
# e2mmap.rb - for ruby 1.1
-# $Release Version: 1.1$
-# $Revision: 1.4 $
-# $Date: 1997/08/18 07:12:12 $
+# $Release Version: 1.2$
+# $Revision: 1.8 $
+# $Date: 1998/08/19 15:22:22 $
# by Keiju ISHITSUKA
#
# --
+# Usage:
+#
+# class Foo
+# extend Exception2MassageMapper
+# def_exception :NewExceptionClass, "message..."[, superclass]
+# def_e2meggage ExistingExceptionClass, "message..."
+# ...
+# end
+#
+# Foo.Fail NewExceptionClass, arg...
+# Foo.Fail ExistingExceptionClass, arg...
#
#
if VERSION < "1.1"
@@ -13,40 +24,60 @@ if VERSION < "1.1"
else
module Exception2MessageMapper
- RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/e2mmap.rb,v 1.4 1997/08/18 07:12:12 keiju Exp keiju $-'
+ @RCS_ID='-$Id: e2mmap.rb,v 1.8 1998/08/19 15:22:22 keiju Exp keiju $-'
E2MM = Exception2MessageMapper
-
+
def E2MM.extend_object(cl)
super
cl.bind(self)
end
- # 以前との互換性のために残してある.
+ # backward compatibility
def E2MM.extend_to(b)
c = eval("self", b)
c.extend(self)
end
-# public :fail
- # alias e2mm_fail fail
+ # public :fail
+ alias fail! fail
+
+ #def fail(err = nil, *rest)
+ # super
+ #end
- def fail(err = nil, *rest)
- Exception2MessageMapper.fail Exception2MessageMapper::ErrNotRegisteredException, err.to_s
+ def Fail(err = nil, *rest)
+ Exception2MessageMapper.Fail Exception2MessageMapper::ErrNotRegisteredException, err.inspect
end
def bind(cl)
self.module_eval %q^
- E2MM_ErrorMSG = {}
+ E2MM_ErrorMSG = {} unless self.const_defined?(:E2MM_ErrorMSG)
# fail(err, *rest)
- # err: 例外
- # rest: メッセージに渡すパラメータ
+ # err: Exception
+ # rest: Parameter accompanied with the exception
#
+ def self.Fail(err = nil, *rest)
+ if form = E2MM_ErrorMSG[err]
+ $! = err.new(sprintf(form, *rest))
+ $@ = caller(0) if $@.nil?
+ $@.shift
+ # e2mm_fail()
+ raise()
+# elsif self == Exception2MessageMapper
+# fail Exception2MessageMapper::ErrNotRegisteredException, err.to_s
+ else
+# print "super\n"
+ super
+ end
+ end
+
+ # 過去の互換性のため
def self.fail(err = nil, *rest)
- $@ = caller(0) if $@.nil?
- $@.shift
if form = E2MM_ErrorMSG[err]
$! = err.new(sprintf(form, *rest))
+ $@ = caller(0) if $@.nil?
+ $@.shift
# e2mm_fail()
raise()
# elsif self == Exception2MessageMapper
@@ -63,7 +94,6 @@ else
# def_exception(c, m)
# c: exception
# m: message_form
- # 例外cのメッセージをmとする.
#
def self.def_e2message(c, m)
E2MM_ErrorMSG[c] = m
@@ -72,13 +102,21 @@ else
# def_exception(c, m)
# n: exception_name
# m: message_form
- # s: 例外スーパークラス(デフォルト: Exception)
- # 例外名``c''をもつ例外を定義し, そのメッセージをmとする.
+ # s: superclass_of_exception (default: Exception)
+ # defines excaption named ``c'', whose message is ``m''.
#
#def def_exception(n, m)
- def self.def_exception(n, m, s = Exception)
+ def self.def_exception(n, m, s = nil)
n = n.id2name if n.kind_of?(Fixnum)
+ unless s
+ if defined?(StandardError)
+ s = StandardError
+ else
+ s = Exception
+ end
+ end
e = Class.new(s)
+
const_set(n, e)
E2MM_ErrorMSG[e] = m
# const_get(:E2MM_ErrorMSG)[e] = m
@@ -91,4 +129,3 @@ else
def_exception(:ErrNotRegisteredException, "not registerd exception(%s)")
end
end
-
diff --git a/lib/eregex.rb b/lib/eregex.rb
index f214f6a..384d531 100644
--- a/lib/eregex.rb
+++ b/lib/eregex.rb
@@ -30,10 +30,7 @@ class Regexp
end
end
-p "abc" =~ /b/|/c/
-p "abc" =~ /b/&/c/
-
-
-
-
-
+if __FILE__ == $0
+ p "abc" =~ /b/|/c/
+ p "abc" =~ /b/&/c/
+end
diff --git a/lib/finalize.rb b/lib/finalize.rb
index 9b2ffef..a07e67d 100644
--- a/lib/finalize.rb
+++ b/lib/finalize.rb
@@ -1,8 +1,8 @@
#
# finalizer.rb -
-# $Release Version: 0.2$
-# $Revision: 1.3 $
-# $Date: 1998/01/09 08:09:49 $
+# $Release Version: 0.3$
+# $Revision: 1.4 $
+# $Date: 1998/02/27 05:34:33 $
# by Keiju ISHITSUKA
#
# --
@@ -11,44 +11,42 @@
#
# add(obj, dependant, method = :finalize, *opt)
# add_dependency(obj, dependant, method = :finalize, *opt)
-# 依存関係 R_method(obj, dependant) の追加
+# add dependency R_method(obj, dependant)
#
# delete(obj_or_id, dependant, method = :finalize)
# delete_dependency(obj_or_id, dependant, method = :finalize)
-# 依存関係 R_method(obj, dependant) の削除
+# delete dependency R_method(obj, dependant)
# delete_all_dependency(obj_or_id, dependant)
-# 依存関係 R_*(obj, dependant) の削除
+# delete dependency R_*(obj, dependant)
# delete_by_dependant(dependant, method = :finalize)
-# 依存関係 R_method(*, dependant) の削除
+# delete dependency R_method(*, dependant)
# delete_all_by_dependant(dependant)
-# 依存関係 R_*(*, dependant) の削除
+# delete dependency R_*(*, dependant)
# delete_all
-# 全ての依存関係の削除.
+# delete all dependency R_*(*, *)
#
# finalize(obj_or_id, dependant, method = :finalize)
# finalize_dependency(obj_or_id, dependant, method = :finalize)
-# 依存関連 R_method(obj, dependtant) で結ばれるdependantを
-# finalizeする.
+# finalize the dependant connected by dependency R_method(obj, dependtant).
# finalize_all_dependency(obj_or_id, dependant)
-# 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする.
+# finalize all dependants connected by dependency R_*(obj, dependtant).
# finalize_by_dependant(dependant, method = :finalize)
-# 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする.
+# finalize the dependant connected by dependency R_method(*, dependtant).
# fainalize_all_by_dependant(dependant)
-# 依存関連 R_*(*, dependtant) で結ばれるdependantをfinalizeする.
+# finalize all dependants connected by dependency R_*(*, dependant).
# finalize_all
-# Finalizerに登録される全てのdependantをfinalizeする
+# finalize all dependency registered to the Finalizer.
#
# safe{..}
-# gc時にFinalizerが起動するのを止める.
-#
+# stop invoking Finalizer on GC.
#
module Finalizer
- RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/finalize.rb,v 1.3 1998/01/09 08:09:49 keiju Exp keiju $-'
+ RCS_ID='-$Id: finalize.rb,v 1.4 1998/02/27 05:34:33 keiju Exp keiju $-'
# @dependency: {id => [[dependant, method, *opt], ...], ...}
- # 依存関係 R_method(obj, dependant) の追加
+ # add dependency R_method(obj, dependant)
def add_dependency(obj, dependant, method = :finalize, *opt)
ObjectSpace.call_finalizer(obj)
method = method.intern unless method.kind_of?(Integer)
@@ -61,7 +59,7 @@ module Finalizer
end
alias add add_dependency
- # 依存関係 R_method(obj, dependant) の削除
+ # delete dependency R_method(obj, dependant)
def delete_dependency(id, dependant, method = :finalize)
id = id.id unless id.kind_of?(Integer)
method = method.intern unless method.kind_of?(Integer)
@@ -75,7 +73,7 @@ module Finalizer
end
alias delete delete_dependency
- # 依存関係 R_*(obj, dependant) の削除
+ # delete dependency R_*(obj, dependant)
def delete_all_dependency(id, dependant)
id = id.id unless id.kind_of?(Integer)
method = method.intern unless method.kind_of?(Integer)
@@ -88,30 +86,29 @@ module Finalizer
end
end
- # 依存関係 R_method(*, dependant) の削除
+ # delete dependency R_method(*, dependant)
def delete_by_dependant(dependant, method = :finalize)
method = method.intern unless method.kind_of?(Integer)
- for id in Dependency.keys
+ for id in @dependency.keys
delete(id, dependant, method)
end
end
- # 依存関係 R_*(*, dependant) の削除
+ # delete dependency R_*(*, dependant)
def delete_all_by_dependant(dependant)
for id in @dependency.keys
delete_all_dependency(id, dependant)
end
end
- # 依存関連 R_method(obj, dependtant) で結ばれるdependantをfinalizeす
- # る.
+ # finalize the depandant connected by dependency R_method(obj, dependtant)
def finalize_dependency(id, dependant, method = :finalize)
id = id.id unless id.kind_of?(Integer)
method = method.intern unless method.kind_of?(Integer)
for assocs in @dependency[id]
assocs.delete_if do
|d, m, *o|
- d.send(m, *o) if ret = d == dependant && m == method
+ d.send(m, id, *o) if ret = d == dependant && m == method
ret
end
@dependency.delete(id) if assoc.empty?
@@ -119,20 +116,20 @@ module Finalizer
end
alias finalize finalize_dependency
- # 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする.
+ # finalize all dependants connected by dependency R_*(obj, dependtant)
def finalize_all_dependency(id, dependant)
id = id.id unless id.kind_of?(Integer)
method = method.intern unless method.kind_of?(Integer)
for assoc in @dependency[id]
assoc.delete_if do
|d, m, *o|
- d.send(m, *o) if ret = d == dependant
+ d.send(m, id, *o) if ret = d == dependant
end
@dependency.delete(id) if assoc.empty?
end
end
- # 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする.
+ # finalize the dependant connected by dependency R_method(*, dependtant)
def finalize_by_dependant(dependant, method = :finalize)
method = method.intern unless method.kind_of?(Integer)
for id in @dependency.keys
@@ -140,14 +137,14 @@ module Finalizer
end
end
- # 依存関連 R_*(*, dependtant) で結ばれるdependantをfinalizeする.
+ # finalize all dependants connected by dependency R_*(*, dependtant)
def fainalize_all_by_dependant(dependant)
for id in @dependency.keys
finalize_all_dependency(id, dependant)
end
end
- # Finalizerに登録されている全てのdependantをfinalizeする
+ # finalize all dependants registered to the Finalizer.
def finalize_all
for id, assocs in @dependency
for dependant, method, *opt in assocs
@@ -157,7 +154,7 @@ module Finalizer
end
end
- # finalize_* を安全に呼び出すためのイテレータ
+ # method to call finalize_* safely.
def safe
old_status = Thread.critical
Thread.critical = TRUE
@@ -167,7 +164,7 @@ module Finalizer
Thread.critical = old_status
end
- # ObjectSpace#add_finalizerへの登録関数
+ # registering function to ObjectSpace#add_finalizer
def final_of(id)
if assocs = @dependency.delete(id)
for dependant, method, *opt in assocs
@@ -202,4 +199,3 @@ module Finalizer
private_class_method :final_of
end
-
diff --git a/lib/find.rb b/lib/find.rb
index 5ecc543..3f1b82d 100644
--- a/lib/find.rb
+++ b/lib/find.rb
@@ -1,5 +1,5 @@
# Usage:
-# require "find.rb"
+# require "find"
#
# Find.find('/foo','/bar') {|f| ...}
# or
@@ -12,7 +12,7 @@ module Find
while file = path.shift
catch(:prune) {
yield file
- if File.directory? file and not File.symlink? file then
+ if File.directory? file then
d = Dir.open(file)
begin
for f in d
diff --git a/lib/ftools.rb b/lib/ftools.rb
index 59bc81b..7ccc7a4 100644
--- a/lib/ftools.rb
+++ b/lib/ftools.rb
@@ -30,7 +30,7 @@ class << File
to.binmode
begin
- while TRUE
+ while true
r = from.sysread(fsize)
rsize = r.size
w = 0
@@ -40,9 +40,9 @@ class << File
end
end
rescue EOFError
- ret = TRUE
+ ret = true
rescue
- ret = FALSE
+ ret = false
ensure
to.close
from.close
@@ -50,7 +50,7 @@ class << File
ret
end
- def copy from, to, verbose = FALSE
+ def copy from, to, verbose = false
$stderr.print from, " -> ", catname(from, to), "\n" if verbose
syscopy from, to
end
@@ -59,11 +59,11 @@ class << File
# move file
- def move from, to, verbose = FALSE
+ def move from, to, verbose = false
to = catname(from, to)
$stderr.print from, " -> ", to, "\n" if verbose
- if PLATFORM =~ /djgpp|cygwin32|mswin32/ and FileTest.file? to
+ if PLATFORM =~ /djgpp|cygwin|mswin32/ and FileTest.file? to
unlink to
end
begin
@@ -76,10 +76,10 @@ class << File
alias mv move
# compare two files
-# TRUE: identical
-# FALSE: not identical
+# true: identical
+# false: not identical
- def compare from, to, verbose = FALSE
+ def compare from, to, verbose = false
$stderr.print from, " <=> ", to, "\n" if verbose
fsize = size(from)
fsize = 1024 if fsize < 512
@@ -90,7 +90,7 @@ class << File
to = open(to, "r")
to.binmode
- ret = FALSE
+ ret = false
fr = tr = ''
begin
@@ -103,7 +103,7 @@ class << File
end
end
rescue
- ret = FALSE
+ ret = false
ensure
to.close
from.close
@@ -116,7 +116,7 @@ class << File
# unlink files safely
def safe_unlink(*files)
- verbose = if files[-1].is_a? String then FALSE else files.pop end
+ verbose = if files[-1].is_a? String then false else files.pop end
begin
$stderr.print files.join(" "), "\n" if verbose
chmod 0777, *files
@@ -129,7 +129,7 @@ class << File
alias rm_f safe_unlink
def makedirs(*dirs)
- verbose = if dirs[-1].is_a? String then FALSE else dirs.pop end
+ verbose = if dirs[-1].is_a? String then false else dirs.pop end
# mode = if dirs[-1].is_a? Fixnum then dirs.pop else 0755 end
mode = 0755
for dir in dirs
@@ -146,14 +146,15 @@ class << File
alias o_chmod chmod
def chmod(mode, *files)
- verbose = if files[-1].is_a? String then FALSE else files.pop end
+ verbose = if files[-1].is_a? String then false else files.pop end
$stderr.printf "chmod %04o %s\n", mode, files.join(" ") if verbose
o_chmod mode, *files
end
- def install(from, to, mode, verbose)
+ def install(from, to, mode = nil, verbose = false)
to = catname(from, to)
unless FileTest.exist? to and cmp from, to
+ unlink to if FileTest.exist? to
cp from, to, verbose
chmod mode, to, verbose if mode
end
diff --git a/lib/ftplib.rb b/lib/ftplib.rb
index 34ee2f8..617d858 100644
--- a/lib/ftplib.rb
+++ b/lib/ftplib.rb
@@ -1,617 +1,574 @@
-### ftplib.rb -*- Mode: ruby; tab-width: 8; -*-
+## ftplib.rb
-## $Revision: 1.5 $
-## $Date: 1997/09/16 08:03:31 $
-## by maeda shugo <shugo@po.aianet.ne.jp>
+# Author: Shugo Maeda <shugo@po.aianet.ne.jp>
+# Version: $Revision: 1.7 $
-### Code:
+## Code:
require "socket"
-require "sync" if defined? Thread
+require "monitor"
-class FTPError < Exception; end
+class FTPError < StandardError; end
class FTPReplyError < FTPError; end
class FTPTempError < FTPError; end
class FTPPermError < FTPError; end
class FTPProtoError < FTPError; end
class FTP
-
- RCS_ID = '$Id: ftplib.rb,v 1.5 1997/09/16 08:03:31 shugo Exp $'
-
- FTP_PORT = 21
- CRLF = "\r\n"
-
- attr :passive, TRUE
- attr :return_code, TRUE
- attr :debug_mode, TRUE
- attr :welcome
- attr :lastresp
-
- THREAD_SAFE = defined?(Thread) != FALSE
-
- if THREAD_SAFE
- def synchronize(mode = :EX)
- if @sync
- @sync.synchronize(mode) do
- yield
- end
- end
- end
-
- def sock_synchronize(mode = :EX)
- if @sock
- @sock.synchronize(mode) do
- yield
- end
- end
- end
- else
- def synchronize(mode = :EX)
- yield
- end
-
- def sock_synchronize(mode = :EX)
- yield
- end
- end
- private :sock_synchronize
-
- def FTP.open(host, user = nil, passwd = nil, acct = nil)
- new(host, user, passwd, acct)
- end
+
+ RCS_ID = %q$Id: ftplib.rb,v 1.7 1998/04/13 12:34:24 shugo Exp shugo $
+
+ include MonitorMixin
+
+ FTP_PORT = 21
+ CRLF = "\r\n"
+
+ attr_accessor :passive, :return_code, :debug_mode
+ attr_reader :welcome, :lastresp
+
+ def FTP.open(host, user = nil, passwd = nil, acct = nil)
+ new(host, user, passwd, acct)
+ end
- def initialize(host = nil, user = nil,
- passwd = nil, acct = nil)
- if THREAD_SAFE
- @sync = Sync.new
- end
- @passive = FALSE
- @return_code = "\n"
- @debug_mode = FALSE
- if host
- connect(host)
- if user
- login(user, passwd, acct)
- end
- end
- end
-
- def open_socket(host, port)
- if defined? SOCKSsocket and ENV["SOCKS_SERVER"]
- @passive = TRUE
- SOCKSsocket.open(host, port)
- else
- TCPsocket.open(host, port)
- end
- end
- private :open_socket
-
- def connect(host, port = FTP_PORT)
- if @debug_mode
- print "connect: ", host, ", ", port, "\n"
- end
- synchronize do
- @sock = open_socket(host, port)
- if THREAD_SAFE
- @sock.extend Sync_m
- end
- voidresp
- end
- end
-
- def sanitize(s)
- if s =~ /^PASS /i
- s[0, 5] + "*" * (s.length - 5)
- else
- s
- end
- end
- private :sanitize
-
- def putline(line)
- if @debug_mode
- print "put: ", sanitize(line), "\n"
- end
- line = line + CRLF
- @sock.write(line)
- end
- private :putline
-
- def getline
- line = @sock.readline # if get EOF, raise EOFError
- if line[-2, 2] == CRLF
- line = line[0 .. -3]
- elsif line[-1] == ?\r or
- line[-1] == ?\n
- line = line[0 .. -2]
- end
- if @debug_mode
- print "get: ", sanitize(line), "\n"
- end
- line
- end
- private :getline
-
- def getmultiline
- 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] != ?-
- end
- buff << "\n"
- end
- private :getmultiline
-
- def getresp
- resp = getmultiline
- @lastresp = resp[0, 3]
- c = resp[0]
- case c
- when ?1, ?2, ?3
- return resp
- when ?4
- raise FTPTempError, resp
- when ?5
- raise FTPPermError, resp
- else
- raise FTPProtoError, resp
- end
- end
- private :getresp
-
- def voidresp
- resp = getresp
- if resp[0] != ?2
- raise FTPReplyError, resp
- end
- end
- private :voidresp
-
- def sendcmd(cmd)
- synchronize do
- sock_synchronize do
- putline(cmd)
- getresp
- end
- end
- end
-
- def voidcmd(cmd)
- synchronize do
- sock_synchronize do
- putline(cmd)
- voidresp
- end
- end
- nil
- end
-
- def sendport(host, port)
- hbytes = host.split(".")
- pbytes = [port / 256, port % 256]
- bytes = hbytes + pbytes
- cmd = "PORT " + bytes.join(",")
- voidcmd(cmd)
- end
- private :sendport
-
- def makeport
- sock = TCPserver.open(0)
- port = sock.addr[1]
- host = TCPsocket.getaddress(@sock.addr[2])
- resp = sendport(host, port)
- sock
- end
- private :makeport
-
- def transfercmd(cmd)
- if @passive
- host, port = parse227(sendcmd("PASV"))
- conn = open_socket(host, port)
- resp = sendcmd(cmd)
- if resp[0] != ?1
- raise FTPReplyError, resp
- end
- else
- sock = makeport
- resp = sendcmd(cmd)
- if resp[0] != ?1
- raise FTPReplyError, resp
- end
- conn = sock.accept
- end
- conn
- end
- private :transfercmd
-
- def getaddress
- thishost = Socket.gethostname
- if not thishost.index(".")
- thishost = Socket.gethostbyname(thishost)[0]
- end
- if ENV.has_key?("LOGNAME")
- realuser = ENV["LOGNAME"]
- elsif ENV.has_key?("USER")
- realuser = ENV["USER"]
- else
- realuser = "anonymous"
- end
- realuser + "@" + thishost
- end
- private :getaddress
-
- def login(user = "anonymous", passwd = nil, acct = nil)
- if user == "anonymous" and passwd == nil
- passwd = getaddress
- end
-
- resp = ""
- synchronize do
- resp = sendcmd('USER ' + user)
- if resp[0] == ?3
- resp = sendcmd('PASS ' + passwd)
- end
- if resp[0] == ?3
- resp = sendcmd('ACCT ' + acct)
- end
- end
- if resp[0] != ?2
- raise FTPReplyError, resp
- end
- @welcome = resp
- end
+ def initialize(host = nil, user = nil, passwd = nil, acct = nil)
+ super
+ @passive = false
+ @return_code = "\n"
+ @debug_mode = false
+ if host
+ connect(host)
+ if user
+ login(user, passwd, acct)
+ end
+ end
+ end
+
+ def open_socket(host, port)
+ if defined? SOCKSsocket and ENV["SOCKS_SERVER"]
+ @passive = true
+ return SOCKSsocket.open(host, port)
+ else
+ return TCPsocket.open(host, port)
+ end
+ end
+ private :open_socket
+
+ def connect(host, port = FTP_PORT)
+ if @debug_mode
+ print "connect: ", host, ", ", port, "\n"
+ end
+ synchronize do
+ @sock = open_socket(host, port)
+ voidresp
+ end
+ end
+
+ def sanitize(s)
+ if s =~ /^PASS /i
+ return s[0, 5] + "*" * (s.length - 5)
+ else
+ return s
+ end
+ end
+ private :sanitize
+
+ def putline(line)
+ if @debug_mode
+ print "put: ", sanitize(line), "\n"
+ end
+ line = line + CRLF
+ @sock.write(line)
+ end
+ private :putline
+
+ def getline
+ line = @sock.readline # if get EOF, raise EOFError
+ if line[-2, 2] == CRLF
+ line = line[0 .. -3]
+ elsif line[-1] == ?\r or
+ line[-1] == ?\n
+ line = line[0 .. -2]
+ end
+ if @debug_mode
+ print "get: ", sanitize(line), "\n"
+ end
+ return line
+ end
+ private :getline
+
+ def getmultiline
+ 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] != ?-
+ end
+ return buff << "\n"
+ end
+ private :getmultiline
+
+ def getresp
+ resp = getmultiline
+ @lastresp = resp[0, 3]
+ c = resp[0]
+ case c
+ when ?1, ?2, ?3
+ return resp
+ when ?4
+ raise FTPTempError, resp
+ when ?5
+ raise FTPPermError, resp
+ else
+ raise FTPProtoError, resp
+ end
+ end
+ private :getresp
+
+ def voidresp
+ resp = getresp
+ if resp[0] != ?2
+ raise FTPReplyError, resp
+ end
+ end
+ private :voidresp
+
+ def sendcmd(cmd)
+ synchronize do
+ putline(cmd)
+ return getresp
+ end
+ end
- def retrbinary(cmd, blocksize, callback = Proc.new)
- synchronize do
- voidcmd("TYPE I")
- conn = transfercmd(cmd)
- while TRUE
- data = conn.read(blocksize)
- break if data == nil
- callback.call(data)
- end
- conn.close
- voidresp
- end
- end
+ def voidcmd(cmd)
+ synchronize do
+ putline(cmd)
+ voidresp
+ end
+ end
- def retrlines(cmd, callback = nil)
- if iterator?
- callback = Proc.new
- elsif not callback.is_a?(Proc)
- callback = Proc.new {|line| print line, "\n"}
- end
- synchronize do
- voidcmd("TYPE A")
- conn = transfercmd(cmd)
- while TRUE
- line = conn.gets
- break if line == nil
- if line[-2, 2] == CRLF
- line = line[0 .. -3]
- elsif line[-1] == ?\n
- line = line[0 .. -2]
- end
- callback.call(line)
- end
- conn.close
- voidresp
- end
- end
+ def sendport(host, port)
+ hbytes = host.split(".")
+ pbytes = [port / 256, port % 256]
+ bytes = hbytes + pbytes
+ cmd = "PORT " + bytes.join(",")
+ voidcmd(cmd)
+ end
+ private :sendport
+
+ def makeport
+ sock = TCPserver.open(0)
+ port = sock.addr[1]
+ host = TCPsocket.getaddress(@sock.addr[2])
+ resp = sendport(host, port)
+ return sock
+ end
+ private :makeport
+
+ def transfercmd(cmd)
+ if @passive
+ host, port = parse227(sendcmd("PASV"))
+ conn = open_socket(host, port)
+ resp = sendcmd(cmd)
+ if resp[0] != ?1
+ raise FTPReplyError, resp
+ end
+ else
+ sock = makeport
+ resp = sendcmd(cmd)
+ if resp[0] != ?1
+ raise FTPReplyError, resp
+ end
+ conn = sock.accept
+ end
+ return conn
+ end
+ private :transfercmd
+
+ def getaddress
+ thishost = Socket.gethostname
+ if not thishost.index(".")
+ thishost = Socket.gethostbyname(thishost)[0]
+ end
+ if ENV.has_key?("LOGNAME")
+ realuser = ENV["LOGNAME"]
+ elsif ENV.has_key?("USER")
+ realuser = ENV["USER"]
+ else
+ realuser = "anonymous"
+ end
+ return realuser + "@" + thishost
+ end
+ private :getaddress
- def storbinary(cmd, file, blocksize, callback = nil)
- if iterator?
- callback = Proc.new
- end
- use_callback = callback.is_a?(Proc)
- synchronize do
- voidcmd("TYPE I")
- conn = transfercmd(cmd)
- while TRUE
- buf = file.read(blocksize)
- break if buf == nil
- conn.write(buf)
- if use_callback
- callback.call(buf)
- end
- end
- conn.close
- voidresp
- end
- end
+ def login(user = "anonymous", passwd = nil, acct = nil)
+ if user == "anonymous" and passwd == nil
+ passwd = getaddress
+ end
+
+ resp = ""
+ synchronize do
+ resp = sendcmd('USER ' + user)
+ if resp[0] == ?3
+ resp = sendcmd('PASS ' + passwd)
+ end
+ if resp[0] == ?3
+ resp = sendcmd('ACCT ' + acct)
+ end
+ end
+ if resp[0] != ?2
+ raise FTPReplyError, resp
+ end
+ @welcome = resp
+ end
+
+ def retrbinary(cmd, blocksize, callback = Proc.new)
+ synchronize do
+ voidcmd("TYPE I")
+ conn = transfercmd(cmd)
+ loop do
+ data = conn.read(blocksize)
+ break if data == nil
+ callback.call(data)
+ end
+ conn.close
+ voidresp
+ end
+ end
- def storlines(cmd, file, callback = nil)
- if iterator?
- callback = Proc.new
- end
- use_callback = callback.is_a?(Proc)
- synchronize do
- voidcmd("TYPE A")
- conn = transfercmd(cmd)
- while TRUE
- buf = file.gets
- break if buf == nil
- if buf[-2, 2] != CRLF
- if buf[-1] == ?\r or
- buf[-1] == ?\n
- buf = buf[0 .. -2]
- end
- buf = buf + CRLF
- end
- conn.write(buf)
- if use_callback
- callback.call(buf)
- end
- end
- conn.close
- voidresp
- end
- end
+ def retrlines(cmd, callback = nil)
+ if iterator?
+ callback = Proc.new
+ elsif not callback.is_a?(Proc)
+ callback = Proc.new {|line| print line, "\n"}
+ end
+ synchronize do
+ voidcmd("TYPE A")
+ conn = transfercmd(cmd)
+ loop do
+ line = conn.gets
+ break if line == nil
+ if line[-2, 2] == CRLF
+ line = line[0 .. -3]
+ elsif line[-1] == ?\n
+ line = line[0 .. -2]
+ end
+ callback.call(line)
+ end
+ conn.close
+ voidresp
+ end
+ end
+
+ def storbinary(cmd, file, blocksize, callback = nil)
+ if iterator?
+ callback = Proc.new
+ end
+ use_callback = callback.is_a?(Proc)
+ synchronize do
+ voidcmd("TYPE I")
+ conn = transfercmd(cmd)
+ loop do
+ buf = file.read(blocksize)
+ break if buf == nil
+ conn.write(buf)
+ callback.call(buf) if use_callback
+ end
+ conn.close
+ voidresp
+ end
+ end
- def getbinaryfile(remotefile, localfile,
- blocksize, callback = nil)
- if iterator?
- callback = Proc.new
- end
- use_callback = callback.is_a?(Proc)
- f = open(localfile, "w")
- begin
+ def storlines(cmd, file, callback = nil)
+ if iterator?
+ callback = Proc.new
+ end
+ use_callback = callback.is_a?(Proc)
+ synchronize do
+ voidcmd("TYPE A")
+ conn = transfercmd(cmd)
+ loop do
+ buf = file.gets
+ break if buf == nil
+ if buf[-2, 2] != CRLF
+ if buf[-1] == ?\r or
+ buf[-1] == ?\n
+ buf = buf[0 .. -2]
+ end
+ buf = buf + CRLF
+ end
+ conn.write(buf)
+ callback.call(buf) if use_callback
+ end
+ conn.close
+ voidresp
+ end
+ end
+
+ def getbinaryfile(remotefile, localfile, blocksize, callback = nil)
+ if iterator?
+ callback = Proc.new
+ end
+ use_callback = callback.is_a?(Proc)
+ f = open(localfile, "w")
+ begin
f.binmode
- retrbinary("RETR " + remotefile, blocksize) do |data|
- f.write(data)
- if use_callback
- callback.call(data)
- end
- end
- ensure
- f.close
+ retrbinary("RETR " + remotefile, blocksize) do |data|
+ f.write(data)
+ callback.call(data) if use_callback
end
- end
+ ensure
+ f.close
+ end
+ end
- def gettextfile(remotefile, localfile, callback = nil)
- if iterator?
- callback = Proc.new
- end
- use_callback = callback.is_a?(Proc)
- f = open(localfile, "w")
- begin
- retrlines("RETR " + remotefile) do |line|
- line = line + @return_code
- f.write(line)
- if use_callback
- callback.call(line)
- end
- end
- ensure
- f.close
- end
- end
+ def gettextfile(remotefile, localfile, callback = nil)
+ if iterator?
+ callback = Proc.new
+ end
+ use_callback = callback.is_a?(Proc)
+ f = open(localfile, "w")
+ begin
+ retrlines("RETR " + remotefile) do |line|
+ line = line + @return_code
+ f.write(line)
+ callback.call(line) if use_callback
+ end
+ ensure
+ f.close
+ end
+ end
- def putbinaryfile(localfile, remotefile,
- blocksize, callback = nil)
- if iterator?
- callback = Proc.new
- end
- use_callback = callback.is_a?(Proc)
- f = open(localfile)
- begin
+ def putbinaryfile(localfile, remotefile, blocksize, callback = nil)
+ if iterator?
+ callback = Proc.new
+ end
+ use_callback = callback.is_a?(Proc)
+ f = open(localfile)
+ begin
f.binmode
- storbinary("STOR " + remotefile, f, blocksize) do |data|
- if use_callback
- callback.call(data)
- end
- end
- ensure
- f.close
+ storbinary("STOR " + remotefile, f, blocksize) do |data|
+ callback.call(data) if use_callback
end
- end
-
- def puttextfile(localfile, remotefile, callback = nil)
- if iterator?
- callback = Proc.new
- end
- use_callback = callback.is_a?(Proc)
- f = open(localfile)
- begin
- storlines("STOR " + remotefile, f) do |line|
- if use_callback
- callback.call(line)
- end
- end
- ensure
- f.close
- end
- end
-
- def acct(account)
- cmd = "ACCT " + account
- voidcmd(cmd)
- end
+ ensure
+ f.close
+ end
+ end
+
+ def puttextfile(localfile, remotefile, callback = nil)
+ if iterator?
+ callback = Proc.new
+ end
+ use_callback = callback.is_a?(Proc)
+ f = open(localfile)
+ begin
+ storlines("STOR " + remotefile, f) do |line|
+ callback.call(line) if use_callback
+ end
+ ensure
+ f.close
+ end
+ end
- def nlst(dir = nil)
- cmd = "NLST"
- if dir
- cmd = cmd + " " + dir
- end
- files = []
+ def acct(account)
+ cmd = "ACCT " + account
+ voidcmd(cmd)
+ end
+
+ def nlst(dir = nil)
+ cmd = "NLST"
+ if dir
+ cmd = cmd + " " + dir
+ end
+ files = []
+ retrlines(cmd) do |line|
+ files.push(line)
+ end
+ return files
+ end
+
+ def list(*args, &block)
+ cmd = "LIST"
+ args.each do |arg|
+ cmd = cmd + " " + arg
+ end
+ if block
+ retrlines(cmd, &block)
+ else
+ lines = []
retrlines(cmd) do |line|
- files.push(line)
+ lines << line
end
- files
- end
-
- def list(*args)
- cmd = "LIST"
- if iterator?
- callback = Proc.new
- elsif args[-1].is_a?(Proc)
- callback = args.pop
- else
- callback = nil
- end
- args.each do |arg|
- cmd = cmd + " " + arg
- end
- retrlines(cmd, callback)
- end
- alias ls list
- alias dir list
-
- def rename(fromname, toname)
- resp = sendcmd("RNFR " + fromname)
- if resp[0] != ?3
- raise FTPReplyError, resp
- end
- voidcmd("RNTO " + toname)
- end
-
- def delete(filename)
- resp = sendcmd("DELE " + filename)
- if resp[0, 3] == "250"
- return
- elsif resp[0] == ?5
- raise FTPPermError, resp
- else
- raise FTPReplyError, resp
- end
- end
-
- def chdir(dirname)
- if dirname == ".."
- begin
- voidcmd("CDUP")
- return
- rescue FTPPermError
- if $![0, 3] != "500"
- raise FTPPermError, $!
- end
- end
- end
- cmd = "CWD " + dirname
- voidcmd(cmd)
- end
-
- def size(filename)
- resp = sendcmd("SIZE " + filename)
- if resp[0, 3] == "213"
- return Integer(resp[3 .. -1].strip)
- end
- end
-
- def mkdir(dirname)
- resp = sendcmd("MKD " + dirname)
- return parse257(resp)
- end
-
- def rmdir(dirname)
- voidcmd("RMD " + dirname)
- end
+ return lines
+ end
+ end
+ alias ls list
+ alias dir list
+
+ def rename(fromname, toname)
+ resp = sendcmd("RNFR " + fromname)
+ if resp[0] != ?3
+ raise FTPReplyError, resp
+ end
+ voidcmd("RNTO " + toname)
+ end
+
+ def delete(filename)
+ resp = sendcmd("DELE " + filename)
+ if resp[0, 3] == "250"
+ return
+ elsif resp[0] == ?5
+ raise FTPPermError, resp
+ else
+ raise FTPReplyError, resp
+ end
+ end
+
+ def chdir(dirname)
+ if dirname == ".."
+ begin
+ voidcmd("CDUP")
+ return
+ rescue FTPPermError
+ if $![0, 3] != "500"
+ raise FTPPermError, $!
+ end
+ end
+ end
+ cmd = "CWD " + dirname
+ voidcmd(cmd)
+ end
- def pwd
- resp = sendcmd("PWD")
+ def size(filename)
+ voidcmd("TYPE I")
+ resp = sendcmd("SIZE " + filename)
+ if resp[0, 3] != "213"
+ raise FTPReplyError, resp
+ end
+ return resp[3..-1].strip
+ end
+
+ MDTM_REGEXP = /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/
+
+ 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
+
+ def mkdir(dirname)
+ resp = sendcmd("MKD " + dirname)
+ return parse257(resp)
+ end
+
+ def rmdir(dirname)
+ voidcmd("RMD " + dirname)
+ end
+
+ def pwd
+ resp = sendcmd("PWD")
return parse257(resp)
- end
- alias getdir pwd
-
- def system
- resp = sendcmd("SYST")
- if resp[0, 3] != "215"
- raise FTPReplyError, resp
- end
- return resp[4 .. -1]
- end
-
- def abort
- line = "ABOR" + CRLF
- resp = ""
- sock_synchronize do
- print "put: ABOR\n" if @debug_mode
- @sock.send(line, Socket::MSG_OOB)
- resp = getmultiline
- end
- unless ["426", "226", "225"].include?(resp[0, 3])
- raise FTPProtoError, resp
- end
- resp
- end
-
- def status
- line = "STAT" + CRLF
- resp = ""
- sock_synchronize do
- print "put: STAT\n" if @debug_mode
- @sock.send(line, Socket::MSG_OOB)
- resp = getresp
- end
- resp
- end
-
- def help(arg = nil)
- cmd = "HELP"
- if arg
- cmd = cmd + " " + arg
- end
- sendcmd(cmd)
- end
-
- def quit
- voidcmd("QUIT")
- end
-
- def close
- @sock.close if @sock and not @sock.closed?
- end
+ end
+ alias getdir pwd
+
+ def system
+ resp = sendcmd("SYST")
+ if resp[0, 3] != "215"
+ raise FTPReplyError, resp
+ end
+ return resp[4 .. -1]
+ end
+
+ def abort
+ line = "ABOR" + CRLF
+ print "put: ABOR\n" if @debug_mode
+ @sock.send(line, Socket::MSG_OOB)
+ resp = getmultiline
+ unless ["426", "226", "225"].include?(resp[0, 3])
+ raise FTPProtoError, resp
+ end
+ return resp
+ end
+ def status
+ line = "STAT" + CRLF
+ print "put: STAT\n" if @debug_mode
+ @sock.send(line, Socket::MSG_OOB)
+ return getresp
+ end
+
+ def mdtm(filename)
+ resp = sendcmd("MDTM " + filename)
+ if resp[0, 3] == "213"
+ return resp[3 .. -1].strip
+ end
+ end
+
+ def help(arg = nil)
+ cmd = "HELP"
+ if arg
+ cmd = cmd + " " + arg
+ end
+ sendcmd(cmd)
+ end
+
+ def quit
+ voidcmd("QUIT")
+ end
+
+ def close
+ @sock.close if @sock and not @sock.closed?
+ end
+
def closed?
@sock == nil or @sock.closed?
end
- def parse227(resp)
- if resp[0, 3] != "227"
- raise FTPReplyError, resp
- end
- left = resp.index("(")
- right = resp.index(")")
- if left == nil or right == nil
- raise FTPProtoError, resp
- end
- numbers = resp[left + 1 .. right - 1].split(",")
- if numbers.length != 6
- raise FTPProtoError, resp
- end
- host = numbers[0, 4].join(".")
- port = (Integer(numbers[4]) << 8) + Integer(numbers[5])
- return host, port
- end
- private :parse227
-
- def parse257(resp)
- if resp[0, 3] != "257"
- raise FTPReplyError, resp
- end
- if resp[3, 2] != ' "'
- 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
- end
- return dirname
- end
- private :parse257
+ def parse227(resp)
+ if resp[0, 3] != "227"
+ raise FTPReplyError, resp
+ end
+ left = resp.index("(")
+ right = resp.index(")")
+ if left == nil or right == nil
+ raise FTPProtoError, resp
+ end
+ numbers = resp[left + 1 .. right - 1].split(",")
+ if numbers.length != 6
+ raise FTPProtoError, resp
+ end
+ host = numbers[0, 4].join(".")
+ port = (numbers[4].to_i << 8) + numbers[5].to_i
+ return host, port
+ end
+ private :parse227
+
+ def parse257(resp)
+ if resp[0, 3] != "257"
+ raise FTPReplyError, resp
+ end
+ if resp[3, 2] != ' "'
+ 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
+ end
+ return dirname
+ end
+ private :parse257
end
+
+## ftplib.rb ends here
diff --git a/lib/getopts.rb b/lib/getopts.rb
index 6929f7e..9e1e8a2 100644
--- a/lib/getopts.rb
+++ b/lib/getopts.rb
@@ -1,4 +1,3 @@
-#!/usr/local/bin/ruby
#
# getopts.rb -
# $Release Version: $
@@ -11,7 +10,7 @@
#
#
-$RCS_ID="$Header$"
+$RCS_ID=%q$Header$
def isSingle(lopt)
if lopt.index(":")
diff --git a/lib/importenv.rb b/lib/importenv.rb
index 4125376..10b2891 100644
--- a/lib/importenv.rb
+++ b/lib/importenv.rb
@@ -21,9 +21,12 @@ for k,v in ENV
EOS
end
-p $TERM
-$TERM = nil
-p $TERM
-p ENV["TERM"]
-$TERM = "foo"
-p ENV["TERM"]
+if __FILE__ == $0
+ p $TERM
+ $TERM = nil
+ p $TERM
+ p ENV["TERM"]
+ $TERM = "foo"
+ p ENV["TERM"]
+end
+
diff --git a/lib/jcode.rb b/lib/jcode.rb
index 40ab48d..50b7bee 100644
--- a/lib/jcode.rb
+++ b/lib/jcode.rb
@@ -11,13 +11,13 @@ class String
alias original_succ succ
private :original_succ
- def mbchar?(c)
+ def mbchar?
if $KCODE =~ /^s/i
- c =~ /[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc]/n
+ self =~ /[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc]/n
elsif $KCODE =~ /^e/i
- c =~ /[\xa1-\xfe][\xa1-\xfe]/n
+ self =~ /[\xa1-\xfe][\xa1-\xfe]/n
else
- FALSE
+ false
end
end
@@ -25,12 +25,13 @@ class String
if self[-2] && self[-2] & 0x80 != 0
s = self.dup
s[-1] += 1
- s[-1] += 1 if !mbchar?(s)
+ s[-1] += 1 if !s.mbchar?
return s
else
original_succ
end
end
+ alias next succ
def upto(to)
return if self > to
@@ -41,7 +42,7 @@ class String
if self[0..-2] == to[0..-2]
first = self[-2].chr
for c in self[-1] .. to[-1]
- if mbchar?(first+c.chr)
+ if (first+c.chr).mbchar?
yield self[0..-2]+c.chr
end
end
@@ -103,7 +104,7 @@ class String
end
def tr(from, to)
- self.dup.tr!(from, to)
+ (str = self.dup).tr!(from, to) or str
end
def delete!(del)
@@ -126,7 +127,7 @@ class String
end
def delete(del)
- self.dup.delete!(del)
+ (str = self.dup).delete!(del) or str
end
def squeeze!(del=nil)
@@ -154,7 +155,7 @@ class String
end
def squeeze(del=nil)
- self.dup.squeeze!(del)
+ (str = self.dup).squeeze!(del) or str
end
def tr_s!(from, to)
@@ -187,7 +188,7 @@ class String
end
def tr_s(from, to)
- self.dup.tr_s!(from,to)
+ (str = self.dup).tr_s!(from,to) or str
end
alias original_chop! chop!
@@ -201,7 +202,7 @@ class String
end
def chop
- self.dup.chop!
+ (str = self.dup).chop! or str
end
end
$VERBOSE = $vsave
diff --git a/lib/mailread.rb b/lib/mailread.rb
index a5d60c8..5e46606 100644
--- a/lib/mailread.rb
+++ b/lib/mailread.rb
@@ -1,7 +1,7 @@
class Mail
def initialize(f)
- unless f.kind_of?(IO)
+ unless defined? f.gets
f = open(f, "r")
opened = true
end
@@ -15,7 +15,8 @@ class Mail
break if /^$/ # end of header
if /^(\S+):\s*(.*)/
- @header[attr = $1.capitalize!] = $2
+ (attr = $1).capitalize!
+ @header[attr] = $2
elsif attr
sub!(/^\s*/, '')
@header[attr] += "\n" + $_
diff --git a/lib/mathn.rb b/lib/mathn.rb
index fdf27f6..265ef13 100644
--- a/lib/mathn.rb
+++ b/lib/mathn.rb
@@ -1,8 +1,8 @@
#
# mathn.rb -
# $Release Version: 0.5 $
-# $Revision: 1.1 $
-# $Date: 1997/07/03 04:43:47 $
+# $Revision: 1.1.1.1.4.1 $
+# $Date: 1998/01/16 12:36:05 $
# by Keiju ISHITSUKA(SHL Japan Inc.)
#
# --
@@ -96,6 +96,7 @@ class Prime
@counts.push @seed + @seed
return @seed
end
+ alias next succ
def each
loop do
diff --git a/lib/matrix.rb b/lib/matrix.rb
index 394c66f..64b0738 100644
--- a/lib/matrix.rb
+++ b/lib/matrix.rb
@@ -1,9 +1,8 @@
-#!/usr/local/bin/ruby
#
# matrix.rb -
# $Release Version: 1.0$
-# $Revision: 1.0 $
-# $Date: 97/05/23 11:35:28 $
+# $Revision: 1.6 $
+# $Date: 1998/07/31 03:39:49 $
# Original Version from Smalltalk-80 version
# on July 23, 1985 at 8:37:17 am
# by Keiju ISHITSUKA
@@ -18,9 +17,158 @@
# :
# rown]
#
-# column: 列
-# row: 行
#
+# module ExceptionForMatrix::
+# Exceptions:
+# ErrDimensionMismatch
+# number of column/row do not match
+# ErrNotRegular
+# not a regular matrix
+# ErrOperationNotDefined
+# specified operator is not defined (yet)
+#
+# class Matrix
+# include ExceptionForMatrix
+#
+# Methods:
+# class methods:
+# Matrix.[](*rows)
+# creates a matrix where `rows' indicates rows.
+# `rows' is an array of arrays,
+# e.g, Matrix[[11, 12], [21, 22]]
+# Matrix.rows(rows, copy = TRUE)
+# creates a matrix where `rows' indicates rows.
+# if optional argument `copy' is false, use the array as
+# internal structure of the metrix without copying.
+# Matrix.columns(columns)
+# creates a new matrix using `columns` as set of colums vectors.
+# Matrix.diagonal(*values)
+# creates a matrix where `columns' indicates columns.
+# Matrix.scalar(n, value)
+# creates a diagonal matrix such that the diagal compornents is
+# given by `values'.
+# Matrix.scalar(n, value)
+# creates an n-by-n scalar matrix such that the diagal compornent is
+# given by `value'.
+# Matrix.identity(n)
+# Matrix.unit(n)
+# Matrix.I(n)
+# creates an n-by-n unit matrix.
+# Matrix.zero(n)
+# creates an n-by-n zero matrix.
+# Matrix.row_vector(row)
+# creates a 1-by-n matrix such the row vector is `row'.
+# `row' is specifed as a Vector or an Array.
+# Matrix.column_vector(column)
+# creates a 1-by-n matrix such that column vector is `column'.
+# `column' is specifed as a Vector or an Array.
+# accessing:
+# [](i, j)
+# returns (i,j) compornent
+# row_size
+# returns the number of rows
+# column_size
+# returns the number of columns
+# row(i)
+# returns the i-th row vector.
+# when the block is supplied for the method, the block is iterated
+# over all row vectors.
+# column(j)
+# returns the jth column vector.
+# when the block is supplied for the method, the block is iterated
+# over all column vectors.
+# collect
+# map
+# creates a matrix which is the result of iteration of given
+# block over all compornents.
+# minor(*param)
+# returns sub matrix. parameter is specified as the following:
+# 1. from_row, row_size, from_col, size_col
+# 2. from_row..to_row, from_col..to_col
+# TESTING:
+# regular?
+# Is regular?
+# singular?
+# Is singular? i.e. Is non-regular?
+# square?
+# Is square?
+# ARITHMETIC:
+# *(m)
+# times
+# +(m)
+# plus
+# -(m)
+# minus
+# /(m)
+# self * m.inv
+# inverse
+# inv
+# inverse
+# **
+# power
+# Matrix functions:
+# determinant
+# det
+# returns the determinant
+# rank
+# returns the rank
+# trace
+# tr
+# returns the trace
+# transpose
+# t
+# returns the transposed
+# CONVERTING:
+# coerce(other)
+# row_vectors
+# array of row vectors
+# column_vectors
+# array of column vectors
+# to_a
+# converts each element to Array
+# to_f
+# converts each element to Float
+# to_i
+# converts each element to Integer
+# to_r
+# converts each element to Rational
+# PRINTING:
+# to_s
+# returns string representation
+# inspect
+#
+# class Vector
+# include ExceptionForMatrix
+#
+# INSTANCE CREATION:
+# Vector.[](*array)
+# Vector.elements(array, copy = TRUE)
+# ACCSESSING:
+# [](i)
+# size
+# ENUMRATIONS:
+# each2(v)
+# collect2(v)
+# ARITHMETIC:
+# *(x) "is matrix or number"
+# +(v)
+# -(v)
+# VECTOR FUNCTIONS:
+# inner_product(v)
+# collect
+# map
+# map2(v)
+# r
+# CONVERTING:
+# covector
+# to_a
+# to_f
+# to_i
+# to_r
+# coerce(other)
+# PRINTING:
+# to_s
+# inspect
require "e2mmap.rb"
@@ -36,8 +184,8 @@ module ExceptionForMatrix
end
class Matrix
- RCS_ID='-$Header: ruby-mode,v 1.2 91/04/20 17:24:57 keiju Locked $-'
-
+ @RCS_ID='-$Id: matrix.rb,v 1.6 1998/07/31 03:39:49 keiju Exp keiju $-'
+
include ExceptionForMatrix
# instance creations
@@ -144,6 +292,7 @@ class Matrix
if iterator?
for e in @rows[i]
yield e
+
end
else
Vector.elements(@rows[i])
@@ -211,6 +360,38 @@ class Matrix
column_size == row_size
end
+ # COMPARING
+ def ==(other)
+ return FALSE unless Matrix === other
+
+ other.compare_by_row_vectors(@rows)
+ end
+ alias eql? ==
+
+ def compare_by_row_vectors(rows)
+ return FALSE unless @rows.size == rows.size
+
+ 0.upto(@rows.size - 1) do
+ |i|
+ return FALSE unless @rows[i] == rows[i]
+ end
+ TRUE
+ end
+
+ def clone
+ Matrix.rows(@rows)
+ end
+
+ def hash
+ value = 0
+ for row in @rows
+ for e in row
+ value ^= e.hash
+ end
+ end
+ return value
+ end
+
# ARITHMETIC
def *(m) #is matrix or vector or number"
@@ -297,6 +478,25 @@ class Matrix
}
Matrix.rows(rows, FALSE)
end
+
+ def /(other)
+ case other
+ when Numeric
+ rows = @rows.collect {
+ |row|
+ row.collect {
+ |e|
+ e / other
+ }
+ }
+ return Matrix.rows(rows, FALSE)
+ when Matrix
+ return self * other.inverse
+ else
+ x, y = other.coerce(self)
+ rerurn x / y
+ end
+ end
def inverse
Matrix.fail ErrDimensionMismatch unless square?
@@ -597,13 +797,12 @@ end
#----------------------------------------------------------------------
class Vector
include ExceptionForMatrix
-
#INSTANCE CREATION
private_class_method :new
def Vector.[](*array)
- new(:init_elements, array, copy = FALSE)
+ new(:init_elements, array, FALSE)
end
def Vector.elements(array, copy = TRUE)
@@ -649,6 +848,26 @@ class Vector
end
end
+ # COMPARING
+ def ==(other)
+ return FALSE unless Vector === other
+
+ other.compare_by(@elements)
+ end
+ alias eqn? ==
+
+ def compare_by(elements)
+ @elements == elements
+ end
+
+ def clone
+ Vector.elements(@elements)
+ end
+
+ def hash
+ @elements.hash
+ end
+
# ARITHMETIC
def *(x) "is matrix or number"
@@ -733,7 +952,7 @@ class Vector
for e in @elements
v += e*e
end
- return v.sqrt
+ return Math.sqrt(v)
end
# CONVERTING
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 2bf3684..7e131fe 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -1,7 +1,8 @@
-# module to create Makefile for extention modules
+# module to create Makefile for extension modules
# invoke like: ruby -r mkmf extconf.rb
require 'rbconfig'
+require 'find'
include Config
@@ -36,6 +37,7 @@ $install = CONFIG["INSTALL_PROGRAM"]
$install_data = CONFIG["INSTALL_DATA"]
if $install !~ /^\// then
$install = CONFIG["srcdir"]+"/"+$install
+ $install_data = CONFIG["srcdir"]+"/"+$install_data
end
if File.exist? $archdir + "/ruby.h"
@@ -47,28 +49,60 @@ else
exit 1
end
-nul = "> /dev/null"
-
CFLAGS = CONFIG["CFLAGS"]
if PLATFORM == "m68k-human"
- nul = "> nul"
CFLAGS.gsub!(/-c..-stack=[0-9]+ */, '')
end
-if $DEBUG
- nul = ""
+if /win32|djgpp|mingw32|m68k-human/i =~ PLATFORM
+ $null = open("nul", "w")
+else
+ $null = open("/dev/null", "w")
+end
+LINK = "#{CONFIG['CC']} -o conftest -I#{$srcdir} -I#{CONFIG['includedir']} #{CFLAGS} %s #{CONFIG['LDFLAGS']} %s conftest.c #{CONFIG['LIBS']} %s"
+CPP = "#{CONFIG['CPP']} -E -I#{$srcdir} -I#{CONFIG['includedir']} #{CFLAGS} %s conftest.c"
+
+$orgerr = $stderr.dup
+$orgout = $stdout.dup
+def xsystem command
+ if $DEBUG
+ print command, "\n"
+ return system(command)
+ end
+ $stderr.reopen($null)
+ $stdout.reopen($null)
+ r = system(command)
+ $stderr.reopen($orgerr)
+ $stdout.reopen($orgout)
+ return r
end
-LINK = CONFIG["CC"]+" -o conftest -I#{$srcdir} " + CFLAGS + " %s " + CONFIG["LDFLAGS"] + " %s conftest.c " + CONFIG["LIBS"] + "%s " + nul + " 2>&1"
-CPP = CONFIG["CPP"] + " -E -I#{$srcdir} " + CFLAGS + " %s conftest.c " + nul + " 2>&1"
def try_link(libs)
- system(format(LINK, $CFLAGS, $LDFLAGS, libs))
+ xsystem(format(LINK, $CFLAGS, $LDFLAGS, libs))
end
def try_cpp
- system(format(CPP, $CFLAGS))
+ xsystem(format(CPP, $CFLAGS))
+end
+
+def install_rb(mfile)
+ path = []
+ dir = []
+ Find.find("lib") do |f|
+ next unless /\.rb$/ =~ f
+ f = f[4..-1]
+ path.push f
+ dir |= File.dirname(f)
+ end
+ for f in dir
+ next if f == "."
+ mfile.printf "\t@test -d $(libdir)/%s || mkdir $(libdir)/%s\n", f, f
+ end
+ for f in path
+ mfile.printf "\t$(INSTALL_DATA) lib/%s $(libdir)/%s\n", f, f
+ end
end
-def have_library(lib, func)
+def have_library(lib, func="main")
printf "checking for %s() in -l%s... ", func, lib
STDOUT.flush
if $lib_cache[lib]
@@ -86,32 +120,40 @@ def have_library(lib, func)
end
end
- cfile = open("conftest.c", "w")
- cfile.printf "\
+ if func && func != ""
+ cfile = open("conftest.c", "w")
+ cfile.printf "\
int main() { return 0; }
int t() { %s(); return 0; }
", func
- cfile.close
+ cfile.close
- begin
+ begin
+ if $libs
+ libs = "-l" + lib + " " + $libs
+ else
+ libs = "-l" + lib
+ end
+ unless try_link(libs)
+ $lib_cache[lib] = 'no'
+ $cache_mod = TRUE
+ print "no\n"
+ return FALSE
+ end
+ ensure
+ system "rm -f conftest*"
+ end
+ else
if $libs
libs = "-l" + lib + " " + $libs
else
libs = "-l" + lib
end
- unless try_link(libs)
- $lib_found[lib] = 'no'
- $found = TRUE
- print "no\n"
- return FALSE
- end
- ensure
- system "rm -f conftest*"
end
$libs = libs
- $lib_found[lib] = 'yes'
- $found = TRUE
+ $lib_cache[lib] = 'yes'
+ $cache_mod = TRUE
print "yes\n"
return TRUE
end
@@ -221,9 +263,15 @@ def create_makefile(target)
$defs.push(format("-DEXTLIB='%s'", libs.join(",")))
end
$libs = "" unless $libs
+ $DLDFLAGS = CONFIG["DLDFLAGS"]
+
+ if PLATFORM =~ /beos/
+ $libs = $libs + " -lruby"
+ $DLDFLAGS = $DLDFLAGS + " -L" + CONFIG["prefix"] + "/lib"
+ end
- if !$objs then
- $objs = Dir["*.c"]
+ unless $objs then
+ $objs = Dir["*.{c,cc}"]
for f in $objs
f.sub!(/\.(c|cc)$/, ".o")
end
@@ -239,15 +287,18 @@ SHELL = /bin/sh
srcdir = #{$srcdir}
hdrdir = #{$hdrdir}
-CC = gcc
+CC = #{CONFIG["CC"]}
-CFLAGS = #{CONFIG["CCDLFLAGS"]} -I#{$hdrdir} #{CFLAGS} #{$CFLAGS} #{$defs.join(" ")}
-DLDFLAGS = #{CONFIG["DLDFLAGS"]} #{$LDFLAGS}
+prefix = #{CONFIG["prefix"]}
+CFLAGS = #{CONFIG["CCDLFLAGS"]} -I$(hdrdir) -I#{CONFIG["includedir"]} #{CFLAGS} #{$CFLAGS} #{$defs.join(" ")}
+CXXFLAGS = $(CFLAGS)
+DLDFLAGS = #{$DLDFLAGS} #{$LDFLAGS}
LDSHARED = #{CONFIG["LDSHARED"]}
prefix = #{CONFIG["prefix"]}
exec_prefix = #{CONFIG["exec_prefix"]}
-libdir = #{$archdir}
+libdir = #{$libdir}
+archdir = #{$archdir}
#### End of system configuration section. ####
@@ -258,6 +309,7 @@ OBJS = #{$objs}
TARGET = #{target}.#{CONFIG["DLEXT"]}
INSTALL = #{$install}
+INSTALL_DATA = #{$install_data}
binsuffix = #{CONFIG["binsuffix"]}
@@ -269,21 +321,20 @@ clean:; @rm -f *.o *.so *.sl
realclean: clean
-install: $(libdir)/$(TARGET)
+install: $(archdir)/$(TARGET)
-$(libdir)/$(TARGET): $(TARGET)
+$(archdir)/$(TARGET): $(TARGET)
@test -d $(libdir) || mkdir $(libdir)
- $(INSTALL) $(TARGET) $(libdir)/$(TARGET)
+ @test -d $(archdir) || mkdir $(archdir)
+ $(INSTALL) $(TARGET) $(archdir)/$(TARGET)
EOMF
- for rb in Dir["lib/*.rb"]
- mfile.printf "\t$(INSTALL) %s %s\n", rb, $libdir
- end
+ install_rb(mfile)
mfile.printf "\n"
if CONFIG["DLEXT"] != "o"
mfile.printf <<EOMF
$(TARGET): $(OBJS)
- $(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LOCAL_LIBS) $(LIBS)
+ $(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) $(LOCAL_LIBS)
EOMF
elsif not File.exist?(target + ".c") and not File.exist?(target + ".cc") or
mfile.print "$(TARGET): $(OBJS)\n"
@@ -332,12 +383,19 @@ EOMF
rescue
end
end
+
+ if PLATFORM =~ /beos/
+ print "creating ruby.def\n"
+ open("ruby.def", "w") do |file|
+ file.print("EXPORTS\n") if PLATFORM =~ /^i/
+ file.print("Init_#{target}\n")
+ end
+ end
end
-$local_libs = nil
-$libs = nil
+$libs = PLATFORM =~ /cygwin32|beos/ ? nil : "-lc"
$objs = nil
-$CFLAGS = nil
-$LDFLAGS = nil
+$local_libs = ""
+$CFLAGS = ""
+$LDFLAGS = ""
$defs = []
-
diff --git a/lib/mutex_m.rb b/lib/mutex_m.rb
index 823888e..4b8d644 100644
--- a/lib/mutex_m.rb
+++ b/lib/mutex_m.rb
@@ -1,8 +1,8 @@
#
# mutex_m.rb -
# $Release Version: 2.0$
-# $Revision: 1.2 $
-# $Date: 1997/07/25 02:43:21 $
+# $Revision: 1.7 $
+# $Date: 1998/02/27 04:28:57 $
# Original from mutex.rb
# by Keiju ISHITSUKA(SHL Japan Inc.)
#
@@ -18,21 +18,50 @@
require "finalize"
module Mutex_m
- def Mutex_m.extend_object(obj)
+ def Mutex_m.extendable_module(obj)
if Fixnum === obj or TRUE === obj or FALSE === obj or nil == obj
raise TypeError, "Mutex_m can't extend to this class(#{obj.type})"
else
begin
- eval "class << obj
- @mu_locked
- end"
- obj.extend(For_primitive_object)
+ obj.instance_eval "@mu_locked"
+ For_general_object
rescue TypeError
- obj.extend(For_general_object)
+ For_primitive_object
end
end
end
+ def Mutex_m.includable_module(cl)
+ begin
+ dummy = cl.new
+ Mutex_m.extendable_module(dummy)
+ rescue NameError
+ # newが定義されていない時は, DATAとみなす.
+ For_primitive_object
+ end
+ end
+
+ def Mutex_m.extend_class(cl)
+ return super if cl.instance_of?(Module)
+
+ # モジュールの時は何もしない. クラスの場合, 適切なモジュールの決定
+ # とaliasを行う.
+ real = includable_module(cl)
+ cl.module_eval %q{
+ include real
+
+ alias locked? mu_locked?
+ alias lock mu_lock
+ alias unlock mu_unlock
+ alias try_lock mu_try_lock
+ alias synchronize mu_synchronize
+ }
+ end
+
+ def Mutex_m.extend_object(obj)
+ obj.extend(Mutex_m.extendable_module(obj))
+ end
+
def mu_extended
unless (defined? locked? and
defined? lock and
@@ -40,7 +69,7 @@ module Mutex_m
defined? try_lock and
defined? synchronize)
eval "class << self
- alias locked mu_locked?
+ alias locked? mu_locked?
alias lock mu_lock
alias unlock mu_unlock
alias try_lock mu_try_lock
@@ -49,6 +78,7 @@ module Mutex_m
end
end
+ # locking
def mu_synchronize
begin
mu_lock
@@ -58,6 +88,7 @@ module Mutex_m
end
end
+ # internal class
module For_general_object
include Mutex_m
@@ -118,10 +149,16 @@ module Mutex_m
def For_primitive_object.extend_object(obj)
super
+
obj.mu_extended
Finalizer.add(obj, For_primitive_object, :mu_finalize)
end
+ def mu_extended
+ super
+ initialize
+ end
+
def For_primitive_object.mu_finalize(id)
Thread.critical = TRUE
if wait = Mu_Locked.delete(id)
@@ -146,7 +183,7 @@ module Mutex_m
ret = FALSE
else
Mu_Locked[self.id] = []
- Finalizer.set(self, For_primitive_object, :mu_delete_Locked)
+ Finalizer.add(self, For_primitive_object, :mu_finalize)
ret = TRUE
end
Thread.critical = FALSE
@@ -159,7 +196,7 @@ module Mutex_m
Thread.stop
end
Mu_Locked[self.id] = []
- Finalizer.add(self, For_primitive_object, :mu_delete_Locked)
+ Finalizer.add(self, For_primitive_object, :mu_finalize)
Thread.critical = FALSE
self
end
@@ -180,4 +217,3 @@ module Mutex_m
end
end
-
diff --git a/lib/observer.rb b/lib/observer.rb
index b802dac..5928367 100644
--- a/lib/observer.rb
+++ b/lib/observer.rb
@@ -30,9 +30,11 @@ module Observable
@observer_state
end
def notify_observers(*arg)
- if @observer_peers and @observer_state
- for i in @observer_peers
- i.update(*arg)
+ if @observer_state
+ if @observer_peers
+ for i in @observer_peers
+ i.update(*arg)
+ end
end
@observer_state = FALSE
end
diff --git a/lib/parsearg.rb b/lib/parsearg.rb
index a0ef90f..b9f41d5 100644
--- a/lib/parsearg.rb
+++ b/lib/parsearg.rb
@@ -1,4 +1,3 @@
-#!/usr/local/bin/ruby
#
# parsearg.rb - parse arguments
# $Release Version: $
@@ -11,9 +10,9 @@
#
#
-$RCS_ID="$Header$"
+$RCS_ID=%q$Header$
-load("getopts.rb")
+require "getopts"
def printUsageAndExit()
if $USAGE
diff --git a/lib/parsedate.rb b/lib/parsedate.rb
index 1c1dda7..68550c6 100644
--- a/lib/parsedate.rb
+++ b/lib/parsedate.rb
@@ -4,39 +4,68 @@ module ParseDate
'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12 }
MONTHPAT = MONTHS.keys.join('|')
- DAYPAT = 'mon|tue|wed|thu|fri|sat|sun'
+ DAYS = {
+ 'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3,
+ 'thu' => 4, 'fri' => 5, 'sat' => 6 }
+ DAYPAT = DAYS.keys.join('|')
def parsedate(date)
- if date.sub!(/(#{DAYPAT})/i, ' ')
- dayofweek = $1
+ # part of ISO 8601
+ # yyyy-mm-dd | yyyy-mm | yyyy
+ # date hh:mm:ss | date Thh:mm:ss
+ if date =~ /^(\d\d\d\d)-?(?:(\d\d)-?(\d\d)?)? *T?(?:(\d\d):?(\d\d):?(\d\d)?)?$/
+ return $1.to_i,
+ if $2 then $2.to_i else 1 end,
+ if $3 then $3.to_i else 1 end,
+ if $4 then $4.to_i end,
+ if $5 then $5.to_i end,
+ if $6 then $6.to_i end,
+ nil,
+ nil
end
- if date.sub!(/\s+(\d+:\d+(:\d+)?)/, ' ')
- time = $1
+ date = date.dup
+ if date.sub!(/(#{DAYPAT})[a-z]*,?/i, ' ')
+ wday = DAYS[$1.downcase]
end
- if date =~ /19(\d\d)/
- year = Integer($1)
+ if date.sub!(/(\d+):(\d+)(?::(\d+))?\s*(am|pm)?\s*(?:\s+([a-z]{1,4}(?:\s+[a-z]{1,4})?|[-+]\d{4}))?/i, ' ')
+ hour = $1.to_i
+ min = $2.to_i
+ if $3
+ sec = $3.to_i
+ end
+ if $4 == 'pm'
+ hour += 12
+ end
+ if $5
+ zone = $5
+ end
end
- if date.sub!(/\s*(\d+)\s+(#{MONTHPAT})\S*\s+/i, ' ')
- dayofmonth = $1.to_i
- monthname = $2
- elsif date.sub!(/\s*(#{MONTHPAT})\S*\s+(\d+)\s+/i, ' ')
- monthname = $1
- dayofmonth = $2.to_i
- elsif date.sub!(/\s*(#{MONTHPAT})\S*\s+(\d+)\D+/i, ' ')
- monthname = $1
- dayofmonth = $2.to_i
- elsif date.sub!(/\s*(\d\d?)\/(\d\d?)/, ' ')
- month = $1
- dayofmonth = $2.to_i
+ if date.sub!(/(\d+)\S*\s+(#{MONTHPAT})\S*(?:\s+(\d+))?/i, ' ')
+ mday = $1.to_i
+ mon = MONTHS[$2.downcase]
+ if $3
+ year = $3.to_i
+ end
+ elsif date.sub!(/(#{MONTHPAT})\S*\s+(\d+)\S*\s*,?(?:\s+(\d+))?/i, ' ')
+ mon = MONTHS[$1.downcase]
+ mday = $2.to_i
+ if $3
+ year = $3.to_i
+ end
+ elsif date.sub!(/(\d+)\/(\d+)(?:\/(\d+))/, ' ')
+ mon = $1.to_i
+ mday = $2.to_i
+ if $3
+ year = $3.to_i
+ end
end
- if monthname
- month = MONTHS[monthname.downcase]
- end
- if ! year && date =~ /\d\d/
- year = Integer($&)
- end
- return year, month, dayofmonth
+ return year, mon, mday, hour, min, sec, zone, wday
end
module_function :parsedate
end
+
+if __FILE__ == $0
+ p Time.now.asctime
+ p ParseDate.parsedate(Time.now.asctime)
+end
diff --git a/lib/ping.rb b/lib/ping.rb
index d742a50..065b1d2 100644
--- a/lib/ping.rb
+++ b/lib/ping.rb
@@ -26,6 +26,10 @@
#
# The timeout in seconds. If not specified it will default to 5 seconds.
#
+# : service
+#
+# The service port to connect. The default is "echo".
+#
#= WARNING
#
# pingecho() uses user-level thread to implement the timeout, so it may block
@@ -33,23 +37,26 @@
#
#=end
+require 'timeout'
+
module Ping
require "socket"
- def pingecho(host, timeout=5)
+ def pingecho(host, timeout=5, service="echo")
begin
- x = Thread.current
- y = Thread.start {
- sleep timeout
- x.raise RuntimeError if x.status
- }
- s = TCPsocket.new(host, "echo")
- s.close
- return TRUE
+ timeout(timeout) do
+ s = TCPsocket.new(host, service)
+ s.close
+ end
rescue
- return FALSE;
- ensure
- Thread.kill y if y.status
+ return false
end
+ return true
end
- module_function "pingecho"
+ module_function :pingecho
+end
+
+if $0 == __FILE__
+ host = ARGV[0]
+ host ||= "localhost"
+ printf("%s alive? - %s\n", host, Ping::pingecho(host, 5))
end
diff --git a/lib/pstore.rb b/lib/pstore.rb
index 86f086d..2aa9864 100644
--- a/lib/pstore.rb
+++ b/lib/pstore.rb
@@ -1,5 +1,4 @@
-#!/usr/local/bin/ruby
-
+#
# How to use:
#
# db = PStore.new("/tmp/foo")
@@ -16,7 +15,8 @@
require "marshal"
class PStore
- Exception(:Error)
+ class Error < StandardError
+ end
def initialize(file)
dir = File::dirname(file)
@@ -89,33 +89,46 @@ class PStore
catch(:pstore_abort_transaction) do
value = yield(self)
end
+ rescue Exception
+ @abort = true
+ raise
ensure
unless @abort
- File::rename @filename, @filename+"~"
+ begin
+ File::rename @filename, @filename+"~"
+ rescue Errno::ENOENT
+ no_orig = true
+ end
begin
File::open(@filename, "w") do |file|
Marshal::dump(@table, file)
end
rescue
- File::rename @filename+"~", @filename
+ File::rename @filename+"~", @filename unless no_orig
end
end
@abort = false
end
ensure
+ @table = nil
@transaction = false
end
value
end
end
-db = PStore.new("/tmp/foo")
-db.transaction do
- p db.roots
- ary = db["root"] = [1,2,3,4]
- ary[0] = [1,1.5]
-end
+if __FILE__ == $0
+ db = PStore.new("/tmp/foo")
+ db.transaction do
+ p db.roots
+ ary = db["root"] = [1,2,3,4]
+ ary[1] = [1,1.5]
+ end
-db.transaction do
- p db["root"]
+ 1000.times do
+ db.transaction do
+ db["root"][0] += 1
+ p db["root"][0]
+ end
+ end
end
diff --git a/lib/rational.rb b/lib/rational.rb
index d4112c2..1282f56 100644
--- a/lib/rational.rb
+++ b/lib/rational.rb
@@ -1,8 +1,8 @@
#
# rational.rb -
# $Release Version: 0.5 $
-# $Revision: 1.1 $
-# $Date: 1996/11/11 04:25:14 $
+# $Revision: 1.3 $
+# $Date: 1998/03/11 14:09:03 $
# by Keiju ISHITSUKA(SHL Japan Inc.)
#
# --
@@ -44,7 +44,11 @@ def Rational(a, b = 1)
end
class Rational < Numeric
+ @RCS_ID='-$Id: rational.rb,v 1.3 1998/03/11 14:09:03 keiju Exp keiju $-'
+
def Rational.reduce(num, den = 1)
+ raise ZeroDivisionError, "denometor is 0" if den == 0
+
if den < 0
num = -num
den = -den
@@ -128,6 +132,7 @@ class Rational < Numeric
den = @denominator * a.numerator
Rational(num, den)
elsif a.kind_of?(Integer)
+ raise ZeroDivisionError, "devided by 0" if a == 0
self / Rational.new!(a, 1)
elsif a.kind_of?(Float)
Float(self) / a
diff --git a/lib/shellwords.rb b/lib/shellwords.rb
index 9632f12..9154cd8 100644
--- a/lib/shellwords.rb
+++ b/lib/shellwords.rb
@@ -18,21 +18,19 @@ module Shellwords
while line != ''
field = ''
while TRUE
- if line.sub! /^"(([^"\\]|\\.)*)"/, '' then
+ if line.sub! /^"(([^"\\]|\\.)*)"/, '' then #"
snippet = $1
snippet.gsub! /\\(.)/, '\1'
- elsif line =~ /^"/ then
- STDOUT.print "Unmatched double quote: $_\n"
- exit
- elsif line.sub! /^'(([^'\\]|\\.)*)'/, '' then
+ elsif line =~ /^"/ then #"
+ raise ArgError, "Unmatched double quote: #{line}"
+ elsif line.sub! /^'(([^'\\]|\\.)*)'/, '' then #'
snippet = $1
snippet.gsub! /\\(.)/, '\1'
- elsif line =~ /^'/ then
- STDOUT.print "Unmatched single quote: $_\n"
- exit
+ elsif line =~ /^'/ then #'
+ raise ArgError, "Unmatched single quote: #{line}"
elsif line.sub! /^\\(.)/, '' then
snippet = $1
- elsif line.sub! /^([^\s\\'"]+)/, '' then
+ elsif line.sub! /^([^\s\\'"]+)/, '' then #'
snippet = $1
else
line.sub! /^\s+/, ''
diff --git a/lib/sync.rb b/lib/sync.rb
index b5a3fc3..9f9706d 100644
--- a/lib/sync.rb
+++ b/lib/sync.rb
@@ -4,6 +4,7 @@
# $Revision$
# $Date$
# by Keiju ISHITSUKA
+# modified by matz
#
# --
# Sync_m, Synchronizer_m
@@ -43,7 +44,7 @@ unless defined? Thread
fail "Thread not available for this ruby interpreter"
end
-require "finalize"
+require "final"
module Sync_m
RCS_ID='-$Header$-'
@@ -54,7 +55,7 @@ module Sync_m
EX = :EX
# 例外定義
- class Err < Exception
+ class Err < StandardError
def Err.Fail(*opt)
fail self, sprintf(self::Message, *opt)
end
@@ -296,8 +297,8 @@ module Sync_m
private :sync_try_lock_sub
def sync_synchronize(mode = EX)
+ sync_lock(mode)
begin
- sync_lock(mode)
yield
ensure
sync_unlock
@@ -321,7 +322,11 @@ module Sync_m
def For_primitive_object.extend_object(obj)
super
obj.sync_extended
- Finalizer.add(obj, For_primitive_object, :sync_finalize)
+ # Changed to use `final.rb'.
+ # Finalizer.add(obj, For_primitive_object, :sync_finalize)
+ ObjectSpace.define_finalizer(obj) do |id|
+ For_primitive_object.sync_finalize(id)
+ end
end
def initialize
diff --git a/lib/thread.rb b/lib/thread.rb
index 4f294cc..ec75144 100644
--- a/lib/thread.rb
+++ b/lib/thread.rb
@@ -9,14 +9,20 @@ unless defined? Thread
end
unless defined? ThreadError
- class ThreadError<Exception
+ class ThreadError<StandardError
end
end
+if $DEBUG
+ Thread.abort_on_exception = true
+end
+
class Mutex
def initialize
@waiting = []
- @locked = FALSE;
+ @locked = false;
+ @waiting.taint # enable tainted comunication
+ self.taint
end
def locked?
@@ -24,42 +30,39 @@ class Mutex
end
def try_lock
- result = FALSE
- Thread.critical = TRUE
+ result = false
+ Thread.critical = true
unless @locked
- @locked = TRUE
- result = TRUE
+ @locked = true
+ result = true
end
- Thread.critical = FALSE
+ Thread.critical = false
result
end
def lock
- while (Thread.critical = TRUE; @locked)
+ while (Thread.critical = true; @locked)
@waiting.push Thread.current
Thread.stop
end
- @locked = TRUE
- Thread.critical = FALSE
+ @locked = true
+ Thread.critical = false
self
end
def unlock
return unless @locked
Thread.critical = TRUE
- wait = @waiting
- @waiting = []
+ t = @waiting.shift
@locked = FALSE
Thread.critical = FALSE
- for w in wait
- w.run
- end
+ t.run if t
self
end
def synchronize
+ lock
begin
- lock
yield
ensure
unlock
@@ -67,37 +70,74 @@ class Mutex
end
end
+class ConditionVariable
+ def initialize
+ @waiters = []
+ @waiters_mutex = Mutex.new
+ @waiters.taint # enable tainted comunication
+ self.taint
+ end
+
+ def wait(mutex)
+ mutex.unlock
+ @waiters_mutex.synchronize {
+ @waiters.push(Thread.current)
+ }
+ Thread.stop
+ mutex.lock
+ end
+
+ def signal
+ @waiters_mutex.synchronize {
+ t = @waiters.shift
+ t.run if t
+ }
+ end
+
+ def broadcast
+ @waiters_mutex.synchronize {
+ for t in @waiters
+ t.run
+ end
+ @waiters.clear
+ }
+ end
+end
+
class Queue
def initialize
@que = []
@waiting = []
+ @que.taint # enable tainted comunication
+ @waiting.taint
+ self.taint
end
def push(obj)
- Thread.critical = TRUE
+ Thread.critical = true
@que.push obj
t = @waiting.shift
- Thread.critical = FALSE
+ Thread.critical = false
t.run if t
end
- def pop non_block=FALSE
- item = nil
- until item
- Thread.critical = TRUE
- if @que.length == 0
- if non_block
- Thread.critical = FALSE
- raise ThreadError, "queue empty"
+ def pop non_block=false
+ Thread.critical = true
+ begin
+ loop do
+ if @que.length == 0
+ if non_block
+ raise ThreadError, "queue empty"
+ end
+ @waiting.push Thread.current
+ Thread.stop
+ else
+ return @que.shift
end
- @waiting.push Thread.current
- Thread.stop
- else
- item = @que.shift
end
+ ensure
+ Thread.critical = false
end
- Thread.critical = FALSE
- item
end
def empty?
@@ -107,4 +147,63 @@ class Queue
def length
@que.length
end
+ alias size length
+
+
+ def num_waiting
+ @waiting.size
+ end
+end
+
+class SizedQueue<Queue
+ def initialize(max)
+ @max = max
+ @queue_wait = []
+ @queue_wait.taint # enable tainted comunication
+ super()
+ end
+
+ def max
+ @max
+ end
+
+ def max=(max)
+ Thread.critical = TRUE
+ if @max >= max
+ @max = max
+ Thread.critical = FALSE
+ else
+ diff = max - @max
+ @max = max
+ Thread.critical = FALSE
+ diff.times do
+ t = @queue_wait.shift
+ t.run if t
+ end
+ end
+ max
+ end
+
+ def push(obj)
+ Thread.critical = true
+ while @que.length >= @max
+ @queue_wait.push Thread.current
+ Thread.stop
+ Thread.critical = true
+ end
+ super
+ end
+
+ def pop(*args)
+ Thread.critical = true
+ if @que.length < @max
+ t = @queue_wait.shift
+ t.run if t
+ end
+ super
+ end
+
+ def num_waiting
+ @waiting.size + @queue_wait.size
+ end
end
diff --git a/lib/thwait.rb b/lib/thwait.rb
index c638335..958163e 100644
--- a/lib/thwait.rb
+++ b/lib/thwait.rb
@@ -1,34 +1,53 @@
#
-# thwait.rb -
-# $Release Version: $
-# $Revision: 1.1 $
-# $Date: 1997/08/18 03:13:14 $
-# by Keiju ISHITSUKA(Nippon Rational Inc.)
+# thwait.rb - thread synchronization class
+# $Release Version: 0.9 $
+# $Revision: 1.3 $
+# $Date: 1998/06/26 03:19:34 $
+# by Keiju ISHITSUKA(Nihpon Rational Software Co.,Ltd.)
#
# --
+# feature:
+# provides synchronization for multiple threads.
#
-#
+# class methods:
+# * ThreadsWait.all_waits(thread1,...)
+# waits until all of specified threads are terminated.
+# if a block is supplied for the method, evaluates it for
+# each thread termination.
+# * th = ThreadsWait.new(thread1,...)
+# creates synchronization object, specifying thread(s) to wait.
+#
+# methods:
+# * th.threads
+# list threads to be synchronized
+# * th.empty?
+# is there any thread to be synchronized.
+# * th.finished?
+# is there already terminated thread.
+# * th.join(thread1,...)
+# wait for specified thread(s).
+# * th.join_nowait(threa1,...)
+# specifies thread(s) to wait. non-blocking.
+# * th.next_wait
+# waits until any of specified threads is terminated.
+# * th.all_waits
+# waits until all of specified threads are terminated.
+# if a block is supplied for the method, evaluates it for
+# each thread termination.
#
require "thread.rb"
require "e2mmap.rb"
class ThreadsWait
- RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/thwait.rb,v 1.1 1997/08/18 03:13:14 keiju Exp keiju $-'
+ RCS_ID='-$Id: thwait.rb,v 1.3 1998/06/26 03:19:34 keiju Exp keiju $-'
Exception2MessageMapper.extend_to(binding)
- def_exception("ErrWaitThreadsNothing", "Wait threads nothing.")
- def_exception("FinshedThreadsNothing", "finished thread nothing.")
+ def_exception("ErrNoWaitingThread", "No threads for waiting.")
+ def_exception("ErrNoFinshedThread", "No finished threads.")
- # class mthods
- # all_waits
-
- #
- # 指定したスレッドが全て終了するまで待つ. イテレータとして呼ばれると
- # 指定したスレッドが終了するとイテレータを呼び出す.
- #
def ThreadsWait.all_waits(*threads)
- tw = ThreadsWait.new(th1, th2, th3, th4, th5)
+ tw = ThreadsWait.new(*threads)
if iterator?
tw.all_waits do
|th|
@@ -39,12 +58,6 @@ class ThreadsWait
end
end
- # initialize and terminating:
- # initialize
-
- #
- # 初期化. 待つスレッドの指定ができる.
- #
def initialize(*threads)
@threads = []
@wait_queue = Queue.new
@@ -52,24 +65,19 @@ class ThreadsWait
end
# accessing
- # threads
-
- # 待ちスレッドの一覧を返す.
+ # threads - list threads to be synchronized
attr :threads
# testing
# empty?
# finished?
- #
-
- #
- # 待ちスレッドが存在するかどうかを返す.
+
+ # is there any thread to be synchronized.
def empty?
@threads.empty?
end
- #
- # すでに終了したスレッドがあるかどうか返す
+ # is there already terminated thread.
def finished?
!@wait_queue.empty?
end
@@ -80,45 +88,40 @@ class ThreadsWait
# next_wait
# all_wait
- #
- # 待っているスレッドを追加し待ちにはいる.
- #
+ # adds thread(s) to join, waits for any of waiting threads to terminate.
def join(*threads)
join_nowait(*threads)
next_wait
end
- #
- # 待っているスレッドを追加する. 待ちには入らない.
- #
+ # adds thread(s) to join, no wait.
def join_nowait(*threads)
@threads.concat threads
for th in threads
Thread.start do
- th = Thread.join(th)
+ th = th.join
@wait_queue.push th
end
end
end
- #
- # 次の待ちにはいる.
- # 待つべきスレッドがなければ, 例外ErrWaitThreadsNothing を返す.
- # nonnlockが真の時には, nonblockingで調べる. 存在しなければ, 例外
- # FinishedThreadNothingを返す.
- #
+ # waits for any of waiting threads to terminate
+ # if there is no thread to wait, raises ErrNoWaitingThread.
+ # if `nonblock' is true, and there is no terminated thread,
+ # raises ErrNoFinishedThread.
def next_wait(nonblock = nil)
- Threads.Wait.fail ErrWaitThreadsNothing if @threads.empty?
-
- th = @wait_queue.pop(nonblock)
- @threads.delete th
- th
+ ThreadsWait.fail ErrNoWaitingThread if @threads.empty?
+ begin
+ @threads.delete(th = @wait_queue.pop(nonblock))
+ th
+ rescue ThreadError
+ ThreadsWait.fail ErrNoFinshedThread
+ end
end
- #
- # 全てのスレッドが終了するまで待つ. イテレータとして呼ばれた時は, ス
- # レッドが終了する度に, イテレータを呼び出す.
- #
+ # waits until all of specified threads are terminated.
+ # if a block is supplied for the method, evaluates it for
+ # each thread termination.
def all_waits
until @threads.empty?
th = next_wait
@@ -126,3 +129,5 @@ class ThreadsWait
end
end
end
+
+ThWait = ThreadsWait
diff --git a/lib/tracer.rb b/lib/tracer.rb
index d37339f..fbfca24 100644
--- a/lib/tracer.rb
+++ b/lib/tracer.rb
@@ -1,7 +1,28 @@
+#
+# tracer.rb -
+# $Release Version: 0.2$
+# $Revision: 1.8 $
+# $Date: 1998/05/19 03:42:49 $
+# by Keiju ISHITSUKA(Nippon Rational Inc.)
+#
+# --
+#
+#
+#
+
+#
+# tracer main class
+#
class Tracer
- MY_FILE_NAME_PATTERN = /^tracer\.(rb)?/
- Threads = Hash.new
- Sources = Hash.new
+ @RCS_ID='-$Id: tracer.rb,v 1.8 1998/05/19 03:42:49 keiju Exp keiju $-'
+
+ class << self
+ attr :verbose, TRUE
+ alias verbose? verbose
+ end
+ verbose = TRUE
+
+ MY_FILE_NAME = caller(0)[0].scan(/^(.*):[0-9]+$/)[0][0]
EVENT_SYMBOL = {
"line" => "-",
@@ -10,39 +31,89 @@ class Tracer
"class" => "C",
"end" => "E"}
+ def initialize
+ @threads = Hash.new
+ if defined? Thread.main
+ @threads[Thread.main.id] = 0
+ else
+ @threads[Thread.current.id] = 0
+ end
+
+ @get_line_procs = {}
+ @sources = {}
+
+ @filters = []
+ end
+
def on
- set_trace_func proc{|event, file, line, id, binding|
- trace_func event, file, line, id, binding
- }
- print "Trace on\n"
+ if iterator?
+ on
+ begin
+ yield
+ ensure
+ off
+ end
+ else
+ set_trace_func proc{|event, file, line, id, binding|
+ trace_func event, file, line, id, binding
+ }
+ print "Trace on\n" if Tracer.verbose?
+ end
end
def off
set_trace_func nil
- print "Trace off\n"
+ print "Trace off\n" if Tracer.verbose?
end
-
- def get_thread_no
- unless no = Threads[Thread.current.id]
- Threads[Thread.current.id] = no = Threads.size
- end
- no
+
+ def add_filter(p = proc)
+ @filters.push p
+ end
+
+ def set_get_line_procs(file, p = proc)
+ @get_line_procs[file] = p
end
def get_line(file, line)
- unless list = Sources[file]
- f =open(file)
- begin
- Sources[file] = list = f.readlines
- ensure
- f.close
+ if p = @get_line_procs[file]
+ return p.call line
+ end
+
+ unless list = @sources[file]
+# print file if $DEBUG
+ begin
+ f = open(file)
+ begin
+ @sources[file] = list = f.readlines
+ ensure
+ f.close
+ end
+ rescue
+ @sources[file] = list = []
end
end
- list[line - 1]
+ if l = list[line - 1]
+ l
+ else
+ "-\n"
+ end
+ end
+
+ def get_thread_no
+ if no = @threads[Thread.current.id]
+ no
+ else
+ @threads[Thread.current.id] = @threads.size
+ end
end
def trace_func(event, file, line, id, binding)
- return if File.basename(file) =~ MY_FILE_NAME_PATTERN
+ return if file == MY_FILE_NAME
+ #printf "Th: %s\n", Thread.current.inspect
+
+ for p in @filters
+ return unless p.call event, file, line, id, binding
+ end
Thread.critical = TRUE
printf("#%d:%s:%d:%s: %s",
@@ -56,20 +127,36 @@ class Tracer
Single = new
def Tracer.on
- Single.on
+ if iterator?
+ Single.on{yield}
+ else
+ Single.on
+ end
end
def Tracer.off
Single.off
end
-end
+ def Tracer.set_get_line_procs(file_name, p = proc)
+ Single.set_get_line_procs(file_name, p)
+ end
-if File.basename($0) =~ Tracer::MY_FILE_NAME_PATTERN
- $0 = ARGV.shift
+ def Tracer.add_filter(p = proc)
+ Single.add_filter(p)
+ end
- Tracer.on
- load $0
-else
- Tracer.on
+end
+
+if caller(0).size == 1
+ if $0 == Tracer::MY_FILE_NAME
+ # direct call
+
+ $0 = ARGV[0]
+ ARGV.shift
+ Tracer.on
+ require $0
+ else
+ Tracer.on
+ end
end
diff --git a/lib/weakref.rb b/lib/weakref.rb
index 93b2c65..c31e959 100644
--- a/lib/weakref.rb
+++ b/lib/weakref.rb
@@ -10,9 +10,10 @@
require "delegate"
-class WeakRef<Delegater
+class WeakRef<Delegator
- Exception :RefError
+ class RefError<StandardError
+ end
ID_MAP = {}
ID_REV_MAP = {}
@@ -31,26 +32,22 @@ class WeakRef<Delegater
def initialize(orig)
super
- @id = orig.id
+ @__id = orig.__id__
ObjectSpace.call_finalizer orig
- ID_MAP[@id] = self.id
- ID_REV_MAP[self.id] = @id
+ ObjectSpace.call_finalizer self
+ ID_MAP[@__id] = self.__id__
+ ID_REV_MAP[self.id] = @__id
end
def __getobj__
- unless ID_MAP[@id]
- $@ = caller(1)
- $! = RefError.new("Illegal Reference - probably recycled")
- raise
+ unless ID_MAP[@__id]
+ raise RefError, "Illegal Reference - probably recycled", caller(2)
end
- ObjectSpace.id2ref(@id)
-# ObjectSpace.each_object do |obj|
-# return obj if obj.id == @id
-# end
+ ObjectSpace._id2ref(@__id)
end
def weakref_alive?
- if ID_MAP[@id]
+ if ID_MAP[@__id]
true
else
false
@@ -62,9 +59,11 @@ class WeakRef<Delegater
end
end
-foo = Object.new
-p foo.hash
-foo = WeakRef.new(foo)
-p foo.hash
-ObjectSpace.garbage_collect
-p foo.hash
+if __FILE__ == $0
+ foo = Object.new
+ p foo.hash # original's hash value
+ foo = WeakRef.new(foo)
+ p foo.hash # should be same hash value
+ ObjectSpace.garbage_collect
+ p foo.hash # should raise exception (recycled)
+end