diff options
author | (no author) <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1998-02-10 08:44:05 +0000 |
---|---|---|
committer | (no author) <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1998-02-10 08:44:05 +0000 |
commit | 36f3603cae6536e571220721e916b8d284cf0675 (patch) | |
tree | eb9605811483000f6980263aa163b4f627ab1c3f /lib | |
parent | fd1d8cdc09ed86e4a0812120a17ff0d7b04adcaf (diff) |
This commit was manufactured by cvs2svn to create tag 'v1_1b7'.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_1b7@70 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Env.rb | 28 | ||||
-rw-r--r-- | lib/complex.rb | 4 | ||||
-rw-r--r-- | lib/date.rb | 72 | ||||
-rw-r--r-- | lib/delegate.rb | 21 | ||||
-rw-r--r-- | lib/e2mmap1_0.rb | 71 | ||||
-rw-r--r-- | lib/final.rb | 41 | ||||
-rw-r--r-- | lib/finalize.rb | 150 | ||||
-rw-r--r-- | lib/ftplib.rb | 2 | ||||
-rw-r--r-- | lib/getopts.rb | 2 | ||||
-rw-r--r-- | lib/mathn.rb | 4 | ||||
-rw-r--r-- | lib/matrix.rb | 2 | ||||
-rw-r--r-- | lib/mutex_m.rb | 4 | ||||
-rw-r--r-- | lib/parsearg.rb | 2 | ||||
-rw-r--r-- | lib/parsedate.rb | 79 | ||||
-rw-r--r-- | lib/rational.rb | 4 | ||||
-rw-r--r-- | lib/sync.rb | 9 | ||||
-rw-r--r-- | lib/tempfile.rb | 88 | ||||
-rw-r--r-- | lib/thread.rb | 30 | ||||
-rw-r--r-- | lib/tk.rb | 25 | ||||
-rw-r--r-- | lib/tkcore.rb | 528 | ||||
-rw-r--r-- | lib/tkmenubar.rb | 137 | ||||
-rw-r--r-- | lib/tkthcore.rb | 550 | ||||
-rw-r--r-- | lib/tracer.rb | 107 | ||||
-rw-r--r-- | lib/weakref.rb | 2 |
24 files changed, 639 insertions, 1323 deletions
diff --git a/lib/Env.rb b/lib/Env.rb new file mode 100644 index 0000000000..e52501f801 --- /dev/null +++ b/lib/Env.rb @@ -0,0 +1,28 @@ +# Env.rb -- imports environment variables as global variables +# +# Usage: +# +# p $USER +# $USER = "matz" +# p ENV["USER"] + +for k,v in ENV + next unless /^[a-zA-Z][_a-zA-Z0-9]*/ =~ k + eval <<EOS + $#{k} = %q!#{v}! + trace_var "$#{k}", proc{|v| + ENV[%q!#{k}!] = v; + $#{k} = %q!#{v}! + if v == nil + untrace_var "$#{k}" + end + } +EOS +end + +p $TERM +$TERM = nil +p $TERM +p ENV["TERM"] +$TERM = "foo" +p ENV["TERM"] diff --git a/lib/complex.rb b/lib/complex.rb index aa5d219d2f..69437b01bb 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.1.1.1 $ +# $Date: 1998/01/16 04:05:49 $ # by Keiju ISHITSUKA(SHL Japan Inc.) # # -- diff --git a/lib/date.rb b/lib/date.rb index 998c2e8152..2d5090b62b 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.2 $ +# $Date: 1998/02/02 04:49:13 $ # 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) @@ -125,6 +154,9 @@ class Date 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." diff --git a/lib/delegate.rb b/lib/delegate.rb index e5943cead8..571bf87510 100644 --- a/lib/delegate.rb +++ b/lib/delegate.rb @@ -7,16 +7,16 @@ # # Usage: # foo = Object.new -# foo = SimpleDelegater.new(foo) +# foo = SimpleDelegator.new(foo) # foo.type # => Object -class Delegater +class Delegator def initialize(obj) preserved = ["id", "equal?", "__getobj__"] for t in self.type.ancestors preserved |= t.instance_methods - break if t == Delegater + break if t == Delegator end for method in obj.methods next if preserved.include? method @@ -30,7 +30,7 @@ class Delegater end -class SimpleDelegater<Delegater +class SimpleDelegator<Delegator def initialize(obj) super @@ -41,4 +41,17 @@ class SimpleDelegater<Delegater @obj end + def __setobj__(obj) + @obj = obj + end +end + +# backword compatibility ^_^;;; +Delegater = Delegator +SimpleDelegater = SimpleDelegator + +if __FILE__ == $0 + foo = Object.new + foo = SimpleDelegator.new(foo) + p foo.type # => Object end diff --git a/lib/e2mmap1_0.rb b/lib/e2mmap1_0.rb deleted file mode 100644 index d245dec975..0000000000 --- a/lib/e2mmap1_0.rb +++ /dev/null @@ -1,71 +0,0 @@ -# -# e2mmap.rb - -# $Release Version: 1.0$ -# $Revision$ -# $Date$ -# by Keiju ISHITSUKA -# -# -- -# -# - -module Exception2MessageMapper - RCS_ID='-$Header$-' - E2MM = Exception2MessageMapper - - def E2MM.extend_to(b) - c = eval("self", b) - c.extend(self) - c.bind(b) - end - - def bind(b) - eval " - @binding = binding - E2MM_ErrorMSG = Hash.new - - # fail(err, *rest) - # err: 例外 - # rest: メッセージに渡すパラメータ - # - def fail!(*rest) - super - end - - def fail(err, *rest) - $! = err.new(sprintf(E2MM_ErrorMSG[err], *rest)) - super() - end - - public :fail - # def_exception(c, m) - # c: exception - # m: message_form - # 例外cのメッセージをmとする. - # - def def_e2message(c, m) - E2MM_ErrorMSG[c] = m - end - - # def_exception(c, m) - # c: exception_name - # m: message_form - # s: 例外スーパークラス(デフォルト: Exception) - # 例外名``c''をもつ例外を定義し, そのメッセージをmとする. - # - def def_exception(c, m) - - c = c.id2name if c.kind_of?(Fixnum) - eval \"class \#{c} < Exception - end - E2MM_ErrorMSG[\#{c}] = '\#{m}' - \", @binding - end -", b - - end - - E2MM.extend_to(binding) - def_exception("ErrNotClassOrModule", "Not Class or Module") -end - diff --git a/lib/final.rb b/lib/final.rb new file mode 100644 index 0000000000..fc17dce289 --- /dev/null +++ b/lib/final.rb @@ -0,0 +1,41 @@ +# +# $Id$ +# Copyright (C) 1998 Yukihiro Matsumoto. All rights reserved. + +# The ObjectSpace extention: +# +# ObjectSpace.define_finalizer(obj, proc=lambda()) +# +# Defines the finalizer for the specified object. +# +# ObjectSpace.undefine_finalizer(obj) +# +# Removes the finalizers for the object. If multiple finalizers are +# defined for the object, all finalizers will be removed. +# + +module ObjectSpace + Finalizers = {} + def define_finalizer(obj, proc=lambda()) + ObjectSpace.call_finalizer(obj) + if assoc = Finalizers[obj.id] + assoc.push(proc) + else + Finalizers[obj.id] = [proc] + end + end + def undefine_finalizer(obj) + Finalizers.delete(obj.id) + end + module_function :define_finalizer, :undefine_finalizer + + Generic_Finalizer = proc {|id| + if Finalizers.key? id + for proc in Finalizers[id] + proc.call(id) + end + Finalizers.delete(id) + end + } + add_finalizer Generic_Finalizer +end diff --git a/lib/finalize.rb b/lib/finalize.rb index 9b2ffefcf5..1482e7ae20 100644 --- a/lib/finalize.rb +++ b/lib/finalize.rb @@ -13,10 +13,10 @@ # add_dependency(obj, dependant, method = :finalize, *opt) # 依存関係 R_method(obj, dependant) の追加 # -# delete(obj_or_id, dependant, method = :finalize) -# delete_dependency(obj_or_id, dependant, method = :finalize) +# delete(obj, dependant, method = :finalize) +# delete_dependency(obj, dependant, method = :finalize) # 依存関係 R_method(obj, dependant) の削除 -# delete_all_dependency(obj_or_id, dependant) +# delete_all_dependency(obj, dependant) # 依存関係 R_*(obj, dependant) の削除 # delete_by_dependant(dependant, method = :finalize) # 依存関係 R_method(*, dependant) の削除 @@ -25,11 +25,11 @@ # delete_all # 全ての依存関係の削除. # -# finalize(obj_or_id, dependant, method = :finalize) -# finalize_dependency(obj_or_id, dependant, method = :finalize) +# finalize(obj, dependant, method = :finalize) +# finalize_dependency(obj, dependant, method = :finalize) # 依存関連 R_method(obj, dependtant) で結ばれるdependantを # finalizeする. -# finalize_all_dependency(obj_or_id, dependant) +# finalize_all_dependency(obj, dependant) # 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする. # finalize_by_dependant(dependant, method = :finalize) # 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする. @@ -45,49 +45,45 @@ 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 $-' - - # @dependency: {id => [[dependant, method, *opt], ...], ...} - + + # Dependency: {id => [[dependant, method, opt], ...], ...} + 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) - assoc = [dependant, method].concat(opt) - if dep = @dependency[obj.id] + assoc = [dependant, method, opt] + if dep = Dependency[obj.id] dep.push assoc else - @dependency[obj.id] = [assoc] + Dependency[obj.id] = [assoc] end end alias add add_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) - for assoc in @dependency[id] - assoc.delete_if do - |d, m, *o| + def delete_dependency(obj, dependant, method = :finalize) + id = obj.id + for assoc in Dependency[id] + assoc.delete_if do |d,m,*o| d == dependant && m == method end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end alias delete 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) - for assoc in @dependency[id] - assoc.delete_if do - |d, m, *o| + def delete_all_dependency(obj, dependant) + id = obj.id + for assoc in Dependency[id] + assoc.delete_if do |d,m,*o| d == dependant end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end - + # 依存関係 R_method(*, dependant) の削除 def delete_by_dependant(dependant, method = :finalize) method = method.intern unless method.kind_of?(Integer) @@ -95,100 +91,103 @@ module Finalizer delete(id, dependant, method) end end - + # 依存関係 R_*(*, dependant) の削除 def delete_all_by_dependant(dependant) - for id in @dependency.keys + for id in Dependency.keys delete_all_dependency(id, dependant) end end - - # 依存関連 R_method(obj, dependtant) で結ばれるdependantをfinalizeす + + # 依存関連 R_method(id, dependtant) で結ばれるdependantをfinalizeす # る. 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 - ret + for assocs in Dependency[id] + assocs.delete_if do |d, m, *o| + if d == dependant && m == method + d.send(m, *o) + true + else + false + end end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end alias finalize finalize_dependency - - # 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする. + + # 依存関連 R_*(id, dependtant) で結ばれるdependantをfinalizeする. 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 + for assoc in Dependency[id] + assoc.delete_if do |d, m, *o| + if d == dependant + d.send(m, *o) + true + else + false + end end - @dependency.delete(id) if assoc.empty? + Dependency.delete(id) if assoc.empty? end end - + # 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする. def finalize_by_dependant(dependant, method = :finalize) - method = method.intern unless method.kind_of?(Integer) - for id in @dependency.keys + for id in Dependency.keys finalize(id, dependant, method) end end - + # 依存関連 R_*(*, dependtant) で結ばれるdependantをfinalizeする. def fainalize_all_by_dependant(dependant) - for id in @dependency.keys + for id in Dependency.keys finalize_all_dependency(id, dependant) end end - + # Finalizerに登録されている全てのdependantをfinalizeする def finalize_all - for id, assocs in @dependency + for id, assocs in Dependency for dependant, method, *opt in assocs dependant.send(method, id, *opt) end assocs.clear end end - + # finalize_* を安全に呼び出すためのイテレータ def safe - old_status = Thread.critical - Thread.critical = TRUE - ObjectSpace.remove_finalizer(@proc) - yield - ObjectSpace.add_finalizer(@proc) - Thread.critical = old_status + old_status, Thread.critical = Thread.critical, true + ObjectSpace.remove_finalizer(Proc) + begin + yield + ensure + ObjectSpace.add_finalizer(Proc) + Thread.critical = old_status + end end - + # ObjectSpace#add_finalizerへの登録関数 def final_of(id) - if assocs = @dependency.delete(id) + if assocs = Dependency.delete(id) for dependant, method, *opt in assocs dependant.send(method, id, *opt) end end end - - @dependency = Hash.new - @proc = proc{|id| final_of(id)} - ObjectSpace.add_finalizer(@proc) + + Proc = proc{|id| final_of(id)} + ObjectSpace.add_finalizer(Proc) module_function :add module_function :add_dependency - + module_function :delete module_function :delete_dependency module_function :delete_all_dependency module_function :delete_by_dependant module_function :delete_all_by_dependant - + module_function :finalize module_function :finalize_dependency module_function :finalize_all_dependency @@ -197,9 +196,8 @@ module Finalizer module_function :finalize_all module_function :safe - + module_function :final_of private_class_method :final_of - -end +end diff --git a/lib/ftplib.rb b/lib/ftplib.rb index 34ee2f8d62..a8edac8123 100644 --- a/lib/ftplib.rb +++ b/lib/ftplib.rb @@ -17,7 +17,7 @@ class FTPProtoError < FTPError; end class FTP - RCS_ID = '$Id: ftplib.rb,v 1.5 1997/09/16 08:03:31 shugo Exp $' + RCS_ID = %q$Id: ftplib.rb,v 1.5 1997/09/16 08:03:31 shugo Exp $ FTP_PORT = 21 CRLF = "\r\n" diff --git a/lib/getopts.rb b/lib/getopts.rb index 6929f7e4fd..1862f56080 100644 --- a/lib/getopts.rb +++ b/lib/getopts.rb @@ -11,7 +11,7 @@ # # -$RCS_ID="$Header$" +$RCS_ID=%q$Header$ def isSingle(lopt) if lopt.index(":") diff --git a/lib/mathn.rb b/lib/mathn.rb index fdf27f6771..b5cc9b818b 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 $ +# $Date: 1998/01/16 04:05:49 $ # by Keiju ISHITSUKA(SHL Japan Inc.) # # -- diff --git a/lib/matrix.rb b/lib/matrix.rb index 394c66f098..175981379f 100644 --- a/lib/matrix.rb +++ b/lib/matrix.rb @@ -36,7 +36,7 @@ module ExceptionForMatrix end class Matrix - RCS_ID='-$Header: ruby-mode,v 1.2 91/04/20 17:24:57 keiju Locked $-' + RCS_ID='-$Header: matrix.rb,v 1.2 91/04/20 17:24:57 keiju Locked $-' include ExceptionForMatrix diff --git a/lib/mutex_m.rb b/lib/mutex_m.rb index 823888e72f..693da41675 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.1.1.1 $ +# $Date: 1998/01/16 04:05:49 $ # Original from mutex.rb # by Keiju ISHITSUKA(SHL Japan Inc.) # diff --git a/lib/parsearg.rb b/lib/parsearg.rb index a0ef90f018..6811dd3b97 100644 --- a/lib/parsearg.rb +++ b/lib/parsearg.rb @@ -11,7 +11,7 @@ # # -$RCS_ID="$Header$" +$RCS_ID=%q$Header$ load("getopts.rb") diff --git a/lib/parsedate.rb b/lib/parsedate.rb index 1c1dda76bc..69b7ae98a9 100644 --- a/lib/parsedate.rb +++ b/lib/parsedate.rb @@ -4,39 +4,66 @@ 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 + # ISO 8601? + if date =~ /(\d\d\d\d)-?(?:(\d\d)-?(\d\d)?)? *(?:(\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, + nil, + if $4 then $4.to_i end, + if $5 then $5.to_i end, + if $6 then $6.to_i end, + 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, wday, hour, min, sec, zone end module_function :parsedate end + +if __FILE__ == $0 + p Time.now.asctime + p ParseDate.parsedate(Time.now.asctime) +end diff --git a/lib/rational.rb b/lib/rational.rb index d4112c2956..a8c8322abc 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.1.1.1 $ +# $Date: 1998/01/16 04:05:49 $ # by Keiju ISHITSUKA(SHL Japan Inc.) # # -- diff --git a/lib/sync.rb b/lib/sync.rb index b5a3fc32b3..1cf70a66ab 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$-' @@ -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/tempfile.rb b/lib/tempfile.rb new file mode 100644 index 0000000000..9d986e7691 --- /dev/null +++ b/lib/tempfile.rb @@ -0,0 +1,88 @@ +# +# $Id$ +# +# The class for temporary files. +# o creates a temporary file, which name is "basename.pid.n" with mode "w+". +# o Tempfile objects can be used like IO object. +# o with tmpfile.close(true) created temporary files are removed. +# o created files are also removed on script termination. +# o with Tempfile#open, you can reopen the temporary file. +# o file mode of the temporary files are 0600. + +require 'delegate' +require 'final' + +class Tempfile < SimpleDelegator + Max_try = 10 + + def Tempfile.callback(path) + lambda{ + print "removing ", path, "..." + if File.exist?(path) + File.unlink(path) + end + if File.exist?(path + '.lock') + File.unlink(path + '.lock') + end + print "done\n" + } + end + + def initialize(basename, tmpdir = '/tmp') + umask = File.umask(0177) + begin + n = 0 + while true + begin + @tmpname = sprintf('%s/%s.%d.%d', tmpdir, basename, $$, n) + unless File.exist?(@tmpname) + File.symlink(tmpdir, @tmpname + '.lock') + break + end + rescue + raise "cannot generate tmpfile `%s'" % @tmpname if n >= Max_try + #sleep(1) + end + n += 1 + end + + @clean_files = Tempfile.callback(@tmpname) + ObjectSpace.define_finalizer(self, @clean_files) + + @tmpfile = File.open(@tmpname, 'w+') + super(@tmpfile) + File.unlink(@tmpname + '.lock') + ensure + File.umask(umask) + end + end + + def Tempfile.open(*args) + Tempfile.new(*args) + end + + def open + @tmpfile.close if @tmpfile + @tmpfile = File.open(@tmpname, 'r+') + __setobj__(@tmpfile) + end + + def close(real=false) + @tmpfile.close if @tmpfile + @tmpfile = nil + if real + @clean_files.call + ObjectSpace.undefine_finalizer(self) + end + end +end + +if __FILE__ == $0 + f = Tempfile.new("foo") + f.print("foo\n") + f.close + f = nil + f.open + p f.gets # => "foo\n" + f.close(true) +end diff --git a/lib/thread.rb b/lib/thread.rb index 4f294cc9a3..8f7f6cdd6a 100644 --- a/lib/thread.rb +++ b/lib/thread.rb @@ -13,6 +13,10 @@ unless defined? ThreadError end end +if $DEBUG + Thread.abort_on_exception = true +end + class Mutex def initialize @waiting = [] @@ -107,4 +111,30 @@ class Queue def length @que.length end + alias size length +end + +class SizedQueue<Queue + def initialize(max) + @max = max + @queue_wait = [] + super() + end + + def push(obj) + while @que.length >= @max + @queue_wait.push Thread.current + Thread.stop + end + super + end + + def pop(*args) + if @que.length < @max + t = @queue_wait.shift + t.run if t + end + pop = super + pop + end end @@ -26,6 +26,9 @@ module TkComm private :error_at def tk_tcl2ruby(val) + if val.include? ? + return val.split.collect{|v| tk_tcl2ruby(v)} + end case val when /^-?\d+$/ val.to_i @@ -241,6 +244,15 @@ module TkComm uninstall_cmd myid }) end + + def update(idle=nil) + if idle + tk_call 'update', 'idletasks' + else + tk_call 'update' + end + end + end module TkCore @@ -963,6 +975,7 @@ class TkRoot<TkWindow return ROOT[0] if ROOT[0] new = super ROOT[0] = new + Tk_WINDOWS["."] = new end def create_self @path = '.' @@ -1220,12 +1233,12 @@ module TkComposite @delegates = {} @delegates['DEFAULT'] = @frame end - if option.kind_of?(String) - @delegates[option] = wins - else - for i in option - @delegates[i] = wins + if @delegates[option].kind_of?(Array) + for i in wins + @delegates[option].push(i) end + else + @delegates[option] = wins end end @@ -1252,3 +1265,5 @@ autoload :TkBitmapImage, 'tkcanvas' autoload :TkPhotoImage, 'tkcanvas' autoload :TkEntry, 'tkentry' autoload :TkText, 'tktext' +autoload :TkDialog, 'tkdialog' +autoload :TkMenubar, 'tkmenubar' diff --git a/lib/tkcore.rb b/lib/tkcore.rb deleted file mode 100644 index c151b0af9e..0000000000 --- a/lib/tkcore.rb +++ /dev/null @@ -1,528 +0,0 @@ -# -# tkcore.rb - Tk interface modue without thread -# $Date$ -# by Yukihiro Matsumoto <matz@caelum.co.jp> - -require "tkutil" -if defined? Thread - require "thread" -end - -module Tk - include TkUtil - extend Tk - - wish_path = nil - ENV['PATH'].split(":").each {|path| - for wish in ['wish4.2', 'wish4.1', 'wish4.0', 'wish'] - if File.exist? path+'/'+wish - wish_path = path+'/'+wish - break - end - break if wish_path - end - } - fail 'can\'t find wish' if not wish_path #' - - def Tk.tk_exit - if not PORT.closed? - PORT.print "exit\n" - PORT.close - end - end - -# PORT = open(format("|%s -n %s", wish_path, File.basename($0)), "w+"); - PORT = open(format("|%s", wish_path), "w+"); - trap "EXIT", proc{Tk.tk_exit} - trap "PIPE", "" - - def tk_write(*args) - printf PORT, *args; - PORT.print "\n" - PORT.flush - end - tk_write '\ -wm withdraw . -proc rb_out args { - puts [format %%s $args] - flush stdout -} -proc rb_ans arg { - if [catch $arg var] {puts "!$var"} {puts "=$var@@"} - flush stdout -} -proc tkerror args { exit } -proc keepalive {} { rb_out alive; after 120000 keepalive} -after 120000 keepalive' - - READABLE = [] - READ_CMD = {} - - def file_readable(port, cmd) - if cmd == nil - READABLE.delete port - else - READABLE.push port - end - READ_CMD[port] = cmd - end - - WRITABLE = [] - WRITE_CMD = {} - def file_writable(port, cmd) - if cmd == nil - WRITABLE.delete port - else - WRITABLE.push port - end - WRITE_CMD[port] = cmd - end - module_function :file_readable, :file_writable - - file_readable PORT, proc { - line = PORT.gets - exit if not line - Tk.dispatch(line.chop!) - } - - def error_at - frames = caller(1) - frames.delete_if do |c| - c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+! - end - frames - end - - def tk_tcl2ruby(val) - case val - when /^-?\d+$/ - val.to_i - when /^\./ - $tk_window_list[val] - when /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - when / / - val.split.collect{|elt| - tk_tcl2ruby(elt) - } - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - - def tk_split_list(str) - idx = str.index('{') - return tk_tcl2ruby(str) if not idx - - list = tk_tcl2ruby(str[0,idx]) - str = str[idx+1..-1] - i = -1 - brace = 1 - str.each_byte {|c| - i += 1 - brace += 1 if c == ?{ - brace -= 1 if c == ?} - break if brace == 0 - } - if str[0, i] == ' ' - list.push ' ' - else - list.push tk_split_list(str[0, i]) - end - list += tk_split_list(str[i+1..-1]) - list - end - private :tk_tcl2ruby, :tk_split_list - - def bool(val) - case bool - when "1", 1, 'yes', 'true' - TRUE - else - FALSE - end - end - def number(val) - case val - when /^-?\d+$/ - val.to_i - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - def string(val) - if val == "{}" - '' - elsif val[0] == ?{ - val[1..-2] - else - val - end - end - def list(val) - tk_split_list(val) - end - def window(val) - $tk_window_list[val] - end - def procedure(val) - if val =~ /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - else - nil - end - end - private :bool, :number, :string, :list, :window, :procedure - - # mark for non-given arguments - None = Object.new - def None.to_s - 'None' - end - - $tk_event_queue = [] - def tk_call(str, *args) - args = args.collect{|s| - next if s == None - if s.kind_of?(Hash) - s = hash_kv(s).join(" ") - else - if not s - s = "0" - elsif s == TRUE - s = "1" - elsif s.kind_of?(TkObject) - s = s.path - elsif s.kind_of?(TkVariable) - s = s.id - else - s = s.to_s - s.gsub!(/["\\\$\[\]]/, '\\\\\0') #" - s.gsub!(/\{/, '\\\\173') - s.gsub!(/\}/, '\\\\175') - end - "\"#{s}\"" - end - } - str += " " - str += args.join(" ") - print str, "\n" if $DEBUG - tk_write 'rb_ans {%s}', str - while PORT.gets - print $_ if $DEBUG - $_.chop! - if /^=(.*)@@$/ - val = $1 - break - elsif /^=/ - val = $' + "\n" - while TRUE - PORT.readline - if ~/@@$/ - val += $' - return val - else - val += $_ - end - end - elsif /^!/ - $@ = error_at - msg = $' - if msg =~ /unknown option "-(.*)"/ - $! = NameError.new(format("undefined method `%s' for %s(%s)", - $1, self, self.type)) #`' - else - $! = RuntimeError.new(format("%s - %s", self.type, msg)) - end - fail - end - $tk_event_queue.push $_ - end - - while ev = $tk_event_queue.shift - Tk.dispatch ev - end - fail 'wish closed' if PORT.closed? -# tk_split_list(val) - val - end - - def hash_kv(keys) - conf = [] - if keys - for k, v in keys - conf.push("-#{k}") - v = install_cmd(v) if v.kind_of? Proc - conf.push(v) - end - end - conf - end - private :tk_call, :error_at, :hash_kv - - $tk_cmdid = 0 - def install_cmd(cmd) - return '' if cmd == '' # uninstall cmd - id = format("c%.4d", $tk_cmdid) - $tk_cmdid += 1 - $tk_cmdtbl[id] = cmd - @cmdtbl = [] if not @cmdtbl - @cmdtbl.push id - return format('rb_out %s', id) - end - def uninstall_cmd(id) - $tk_cmdtbl[id] = nil - end - private :install_cmd, :uninstall_cmd - - $tk_window_list = {} - class Event - def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy) - @serial = seq - @num = b - @focus = (f == 1) - @height = h - @keycode = k - @state = s - @time = t - @width = w - @x = x - @y = y - @char = aa - @send_event = (ee == 1) - @keysym = kk - @keysym_num = nn - @type = tt - @widget = ww - @x_root = xx - @y_root = yy - end - attr :serial - attr :num - attr :focus - attr :height - attr :keycode - attr :state - attr :time - attr :width - attr :x - attr :y - attr :char - attr :send_event - attr :keysym - attr :keysym_num - attr :type - attr :widget - attr :x_root - attr :y_root - end - - def install_bind(cmd, args=nil) - if args - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, *arg - }) - id + " " + args - else - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, Event.new(*arg) - }) - id + " %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y" - end - end - - def _bind(path, context, cmd, args=nil) - begin - id = install_bind(cmd, args) - tk_call 'bind', path, "<#{context}>", id - rescue - $tk_cmdtbl[id] = nil - fail - end - end - private :install_bind, :_bind - - def bind_all(context, cmd=Proc.new, args=nil) - _bind 'all', context, cmd, args - end - - def pack(*args) - TkPack.configure *args - end - - $tk_cmdtbl = {} - - def after(ms, cmd=Proc.new) - myid = format("c%.4d", $tk_cmdid) - tk_call 'after', ms, - install_cmd(proc{ - TkUtil.eval_cmd cmd - uninstall_cmd myid - }) - end - - def update(idle=nil) - if idle - tk_call 'update', 'idletasks' - else - tk_call 'update' - end - end - - def dispatch(line) - if line =~ /^c\d+/ - cmd = $& - fail "no command `#{cmd}'" if not $tk_cmdtbl[cmd] - args = tk_split_list($') - TkUtil.eval_cmd $tk_cmdtbl[cmd], *args - elsif line =~ /^alive$/ - # keep alive, do nothing - else - fail "malformed line <#{line}>" - end - end - - def mainloop - begin - tk_write 'after idle {wm deiconify .}' - while TRUE - rf, wf = select(READABLE, WRITABLE) - for f in rf - READ_CMD[f].call(f) if READ_CMD[f] - if f.closed? - READABLE.delete f - READ_CMD[f] = nil - end - end - for f in wf - WRITE_CMD[f].call(f) if WRITE_CMD[f] - if f.closed? - WRITABLE.delete f - WRITE_CMD[f] = nil - end - end - end - ensure - Tk.tk_exit - end - end - - def root - $tk_root - end - - def bell - tk_call 'bell' - end - module_function :after, :update, :dispatch, :mainloop, :root, :bell - - module Scrollable - def xscrollcommand(cmd=Proc.new) - configure_cmd 'xscrollcommand', cmd - end - def yscrollcommand(cmd=Proc.new) - configure_cmd 'yscrollcommand', cmd - end - end - - module Wm - def aspect(*args) - w = window(tk_call('wm', 'grid', path, *args)) - w.split.collect{|s|s.to_i} if args.length == 0 - end - def client(name=None) - tk_call 'wm', 'client', path, name - end - def colormapwindows(*args) - list(tk_call('wm', 'colormapwindows', path, *args)) - end - def wm_command(value=None) - string(tk_call('wm', 'command', path, value)) - end - def deiconify - tk_call 'wm', 'deiconify', path - end - def focusmodel(*args) - tk_call 'wm', 'focusmodel', path, *args - end - def frame - tk_call 'wm', 'frame', path - end - def geometry(*args) - list(tk_call('wm', 'geometry', path, *args)) - end - def grid(*args) - w = tk_call('wm', 'grid', path, *args) - list(w) if args.size == 0 - end - def group(*args) - tk_call 'wm', 'path', path, *args - end - def iconbitmap(*args) - tk_call 'wm', 'bitmap', path, *args - end - def iconify - tk_call 'wm', 'iconify' - end - def iconmask(*args) - tk_call 'wm', 'iconmask', path, *args - end - def iconname(*args) - tk_call 'wm', 'iconname', path, *args - end - def iconposition(*args) - w = tk_call('wm', 'iconposition', path, *args) - list(w) if args.size == 0 - end - def iconwindow(*args) - tk_call 'wm', 'iconwindow', path, *args - end - def maxsize(*args) - w = tk_call('wm', 'maxsize', path, *args) - list(w) if not args.size == 0 - end - def minsize(*args) - w = tk_call('wm', 'minsize', path, *args) - list(w) if args.size == 0 - end - def overrideredirect(bool=None) - if bool == None - bool(tk_call('wm', 'overrideredirect', path)) - else - tk_call 'wm', 'overrideredirect', path, bool - end - end - def positionfrom(*args) - tk_call 'wm', 'positionfrom', path, *args - end - def protocol(name, func=None) - func = install_cmd(func) if not func == None - tk_call 'wm', 'command', path, name, func - end - def resizable(*args) - w = tk_call('wm', 'resizable', path, *args) - if args.length == 0 - list(w).collect{|e| bool(e)} - end - end - def sizefrom(*args) - list(tk_call('wm', 'sizefrom', path, *args)) - end - def state - tk_call 'wm', 'state', path - end - def title(*args) - tk_call 'wm', 'title', path, *args - end - def transient(*args) - tk_call 'wm', 'transient', path, *args - end - def withdraw - tk_call 'wm', 'withdraw', path - end - end -end diff --git a/lib/tkmenubar.rb b/lib/tkmenubar.rb new file mode 100644 index 0000000000..441f3f5c03 --- /dev/null +++ b/lib/tkmenubar.rb @@ -0,0 +1,137 @@ +# +# tkmenubar.rb +# +# Copyright (C) 1998 maeda shugo. All rights reserved. +# This file can be distributed under the terms of the Ruby. + +# Usage: +# +# menu_spec = [ +# [['File', 0], +# ['Open', proc{puts('Open clicked')}, 0], +# '---', +# ['Quit', proc{exit}, 0]], +# [['Edit', 0], +# ['Cut', proc{puts('Cut clicked')}, 2], +# ['Copy', proc{puts('Copy clicked')}, 0], +# ['Paste', proc{puts('Paste clicked')}, 0]] +# ] +# menubar = TkMenubar.new(nil, menu_spec, +# 'tearoff'=>false, +# 'foreground'=>'grey40', +# 'activeforeground'=>'red', +# 'font'=>'-adobe-helvetica-bold-r-*--12-*-iso8859-1') +# menubar.pack('side'=>'top', 'fill'=>'x') +# +# +# OR +# +# +# menubar = TkMenubar.new +# menubar.add_menu([['File', 0], +# ['Open', proc{puts('Open clicked')}, 0], +# '---', +# ['Quit', proc{exit}, 0]]) +# menubar.add_menu([['Edit', 0], +# ['Cut', proc{puts('Cut clicked')}, 2], +# ['Copy', proc{puts('Copy clicked')}, 0], +# ['Paste', proc{puts('Paste clicked')}, 0]]) +# menubar.configure('tearoff', false) +# menubar.configure('foreground', 'grey40') +# menubar.configure('activeforeground', 'red') +# menubar.configure('font', '-adobe-helvetica-bold-r-*--12-*-iso8859-1') +# menubar.pack('side'=>'top', 'fill'=>'x') + +# The format of the menu_spec is: +# [ +# [ +# [button text, underline, accelerator], +# [menu label, command, underline, accelerator], +# '---', # separator +# ... +# ], +# ... +# ] + +# underline and accelerator are optional parameters. +# Hashes are OK instead of Arrays. + +# To use add_menu, configuration must be done by calling configure after +# adding all menus by add_menu, not by the constructor arguments. + +require "tk" + +class TkMenubar<TkFrame + + include TkComposite + + def initialize(parent = nil, spec = nil, options = nil) + super(parent, options) + + @menus = [] + + if spec + for menu_info in spec + add_menu(menu_info) + end + end + + if options + for key, value in options + configure(key, value) + end + end + end + + def add_menu(menu_info) + btn_info = menu_info.shift + mbtn = TkMenubutton.new(@frame) + + if btn_info.kind_of?(Hash) + for key, value in btn_info + mbtn.configure(key, value) + end + elsif btn_info.kind_of?(Array) + mbtn.configure('text', btn_info[0]) if btn_info[0] + mbtn.configure('underline', btn_info[1]) if btn_info[1] + mbtn.configure('accelerator', btn_info[2]) if btn_info[2] + else + mbtn.configure('text', btn_info) + end + + menu = TkMenu.new(mbtn) + + for item_info in menu_info + if item_info.kind_of?(Hash) + menu.add('command', item_info) + elsif item_info.kind_of?(Array) + options = {} + options['label'] = item_info[0] if item_info[0] + options['command'] = item_info[1] if item_info[1] + options['underline'] = item_info[2] if item_info[2] + options['accelerator'] = item_info[3] if item_info[3] + menu.add('command', options) + elsif /^-+$/ =~ item_info + menu.add('sep') + else + menu.add('command', 'label' => item_info) + end + end + + mbtn.menu(menu) + @menus.push([mbtn, menu]) + delegate('tearoff', menu) + delegate('foreground', mbtn, menu) + delegate('background', mbtn, menu) + delegate('disabledforeground', mbtn, menu) + delegate('activeforeground', mbtn, menu) + delegate('activebackground', mbtn, menu) + delegate('font', mbtn, menu) + delegate('kanjifont', mbtn, menu) + mbtn.pack('side' => 'left') + end + + def [](index) + return @menus[index] + end +end diff --git a/lib/tkthcore.rb b/lib/tkthcore.rb deleted file mode 100644 index a6648502bd..0000000000 --- a/lib/tkthcore.rb +++ /dev/null @@ -1,550 +0,0 @@ -# -# tkthcore.rb - Tk interface modue using thread -# $Date$ -# by Yukihiro Matsumoto <matz@caelum.co.jp> - -require "tkutil" -require "thread" - -module Tk - include TkUtil - extend Tk - - def Tk.tk_exit - if not PORT.closed? - tk_write "exit" - PORT.close - end - end - - trap "EXIT", proc{Tk.tk_exit} - trap "PIPE", '' - - wish_path = nil - ENV['PATH'].split(":").each {|path| - for wish in ['wish4.2', 'wish4.1', 'wish4.0', 'wish'] - if File.exist? path+'/'+wish - wish_path = path+'/'+wish - break - end - break if wish_path - end - } - fail 'can\'t find wish' if not wish_path #' - - # mark for non-given arguments - None = Object.new - def None.to_s - 'None' - end - - Qin = Queue.new - Qout = Queue.new - Qwish = Queue.new - Qcmd = Queue.new - PORT = open(format("|%s -n %s", wish_path, File.basename($0)), "w+"); - - $tk_not_init = TRUE - - def Tk.init - $tk_not_init = FALSE - Thread.start do - loop do - while line = PORT.gets - line.chop! - if line =~ /^[=!]/ - Qwish.push line - else - Qcmd.push line - end - end - exit - end - end - - Thread.start do - ary = [PORT] - loop do - str = Qin.pop - print "Qin: ", str, "\n" if $DEBUG - tk_write 'if [catch {%s} var] {puts "!$var"} {puts "=$var@@"};flush stdout', str - line = tk_recv - Qout.push(line) - end - end - end - - $tk_event_queue = [] - def tk_recv() - val = nil - $_ = Qwish.pop - loop do - if /^=(.*)@@$/ - val = $1 - break - elsif /^=/ - val = $' + "\n" - while TRUE - PORT.readline - if ~/@@$/ - val += $' - return val - else - val += $_ - end - end - elsif /^!/ - $@ = error_at - msg = $' - if msg =~ /unknown option "-(.*)"/ - fail NameError, format("undefined method `%s' for %s(%s)", $1, self, self.type) #`' - else - fail format("%s - %s", self.type, msg) - end - end - end - - fail 'wish closed' if PORT.closed? -# tk_split_list(val) - val - end - - def tk_call(str, *args) - Tk.init if $tk_not_init - args = args.collect{|s| - next if s == None - if s.kind_of?(Hash) - s = hash_kv(s).join(" ") - else - if not s - s = "0" - elsif s == TRUE - s = "1" - elsif s.kind_of?(TkObject) - s = s.path - elsif s.kind_of?(TkVariable) - s = s.id - else - s = s.to_s - s.gsub!(/["\\\$\[\]]/, '\\\\\0') #" - s.gsub!(/\{/, '\\\\173') - s.gsub!(/\}/, '\\\\175') - end - "\"#{s}\"" - end - } - str += " " - str += args.join(" ") - Qin.push str - return Qout.pop - end - - def tk_write(*args) - PORT.printf *args; PORT.print "\n" - PORT.flush - end - module_function :tk_write, :tk_recv - tk_write '\ -wm withdraw . -proc rb_out args { - puts [format %%s $args] - flush stdout -} -proc tkerror args { exit } -proc keepalive {} { rb_out alive; after 120000 keepalive} -after 120000 keepalive' - - READ_TH = {} - def file_readable(port, cmd) - if cmd == nil - if READ_TH[port].has_key? - READ_TH[port].exit - READ_TH[port] = nil - end - else - READ_TH[port] = Thread.start{ - loop do - TkUtil.eval_cmd cmd - end - } - end - end - - WRITE_TH = {} - def file_writable(port, cmd) - if cmd == nil - if WRITE_TH[port].has_key? - WRITE_TH[port].exit - end - else - WRITE_TH[port] = Thread.start{ - loop do - TkUtil.eval_cmd cmd - end - } - end - end - module_function :file_readable, :file_writable - - def tk_tcl2ruby(val) - case val - when /^-?\d+$/ - val.to_i - when /^\./ - $tk_window_list[val] - when /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - when / / - val.split.collect{|elt| - tk_tcl2ruby(elt) - } - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - - def tk_split_list(str) - idx = str.index('{') - return tk_tcl2ruby(str) if not idx - - list = tk_tcl2ruby(str[0,idx]) - str = str[idx+1..-1] - i = -1 - brace = 1 - str.each_byte {|c| - i += 1 - brace += 1 if c == ?{ - brace -= 1 if c == ?} - break if brace == 0 - } - if str[0, i] == ' ' - list.push ' ' - else - list.push tk_split_list(str[0, i]) - end - list += tk_split_list(str[i+1..-1]) - list - end - private :tk_tcl2ruby, :tk_split_list - - def dispatch(line) - if line =~ /^c\d+/ - cmd = $& - fail "no command `#{cmd}'" if not $tk_cmdtbl[cmd] - args = tk_split_list($') - TkUtil.eval_cmd $tk_cmdtbl[cmd], *args - elsif line =~ /^alive$/ - # keep alive, do nothing - else - fail "malformed line <#{line}>" - end - end - module_function :dispatch - - def error_at - frames = caller(1) - frames.delete_if do |c| - c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+! - end - frames - end - - def bool(val) - case bool - when "1", 1, 'yes', 'true' - TRUE - else - FALSE - end - end - def number(val) - case val - when /^-?\d+$/ - val.to_i - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - def string(val) - if val == "{}" - '' - elsif val[0] == ?{ - val[1..-2] - else - val - end - end - def list(val) - tk_split_list(val) - end - def window(val) - $tk_window_list[val] - end - def procedure(val) - if val =~ /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - else - nil - end - end - private :bool, :number, :string, :list, :window, :procedure - - def hash_kv(keys) - conf = [] - if keys - for k, v in keys - conf.push("-#{k}") - v = install_cmd(v) if v.kind_of? Proc - conf.push(v) - end - end - conf - end - private :tk_call, :error_at, :hash_kv - - $tk_cmdid = 0 - def install_cmd(cmd) - return '' if cmd == '' # uninstall cmd - id = format("c%.4d", $tk_cmdid) - $tk_cmdid += 1 - $tk_cmdtbl[id] = cmd - @cmdtbl = [] if not @cmdtbl - @cmdtbl.push id - return format('rb_out %s', id) - end - def uninstall_cmd(id) - $tk_cmdtbl[id] = nil - end - private :install_cmd, :uninstall_cmd - - $tk_window_list = {} - class Event - def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy) - @serial = seq - @num = b - @focus = (f == 1) - @height = h - @keycode = k - @state = s - @time = t - @width = w - @x = x - @y = y - @char = aa - @send_event = (ee == 1) - @keysym = kk - @keysym_num = nn - @type = tt - @widget = ww - @x_root = xx - @y_root = yy - end - attr :serial - attr :num - attr :focus - attr :height - attr :keycode - attr :state - attr :time - attr :width - attr :x - attr :y - attr :char - attr :send_event - attr :keysym - attr :keysym_num - attr :type - attr :widget - attr :x_root - attr :y_root - end - - def install_bind(cmd, args=nil) - if args - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, *arg - }) - id + " " + args - else - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, Event.new(*arg) - }) - id + " %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y" - end - end - - def _bind(path, context, cmd, args=nil) - begin - id = install_bind(cmd, args) - tk_call 'bind', path, "<#{context}>", id - rescue - $tk_cmdtbl[id] = nil - fail - end - end - private :install_bind, :_bind - - def bind_all(context, cmd=Proc.new, args=nil) - _bind 'all', context, cmd, args - end - - def pack(*args) - TkPack.configure *args - end - - $tk_cmdtbl = {} - - Qafter = Queue.new - def after(ms, cmd=Proc.new) - unless $tk_after_thread - $tk_after_thread = Thread.start{ - loop do - cmd = Qafter.pop - TkUtil.eval_cmd cmd - end - } - end - Thread.start do - sleep Float(ms)/1000 - Qafter.push cmd - end - end - - def update(idle=nil) - if idle - tk_call 'update', 'idletasks' - else - tk_call 'update' - end - end - - def root - $tk_root - end - - def bell - tk_call 'bell' - end - - def mainloop - begin - tk_call 'after', 'idle', 'wm deiconify .' - loop do - dispatch Qcmd.pop - end - ensure - Tk.tk_exit - end - end - module_function :after, :update, :dispatch, :mainloop, :root, :bell - - module Scrollable - def xscrollcommand(cmd=Proc.new) - configure_cmd 'xscrollcommand', cmd - end - def yscrollcommand(cmd=Proc.new) - configure_cmd 'yscrollcommand', cmd - end - end - - module Wm - def aspect(*args) - w = window(tk_call('wm', 'grid', path, *args)) - w.split.collect{|s|s.to_i} if args.length == 0 - end - def client(name=None) - tk_call 'wm', 'client', path, name - end - def colormapwindows(*args) - list(tk_call('wm', 'colormapwindows', path, *args)) - end - def wm_command(value=None) - string(tk_call('wm', 'command', path, value)) - end - def deiconify - tk_call 'wm', 'deiconify', path - end - def focusmodel(*args) - tk_call 'wm', 'focusmodel', path, *args - end - def frame - tk_call 'wm', 'frame', path - end - def geometry(*args) - list(tk_call('wm', 'geometry', path, *args)) - end - def grid(*args) - w = tk_call('wm', 'grid', path, *args) - list(w) if args.size == 0 - end - def group(*args) - tk_call 'wm', 'path', path, *args - end - def iconbitmap(*args) - tk_call 'wm', 'bitmap', path, *args - end - def iconify - tk_call 'wm', 'iconify' - end - def iconmask(*args) - tk_call 'wm', 'iconmask', path, *args - end - def iconname(*args) - tk_call 'wm', 'iconname', path, *args - end - def iconposition(*args) - w = tk_call('wm', 'iconposition', path, *args) - list(w) if args.size == 0 - end - def iconwindow(*args) - tk_call 'wm', 'iconwindow', path, *args - end - def maxsize(*args) - w = tk_call('wm', 'maxsize', path, *args) - list(w) if not args.size == 0 - end - def minsize(*args) - w = tk_call('wm', 'minsize', path, *args) - list(w) if args.size == 0 - end - def overrideredirect(bool=None) - if bool == None - bool(tk_call('wm', 'overrideredirect', path)) - else - tk_call 'wm', 'overrideredirect', path, bool - end - end - def positionfrom(*args) - tk_call 'wm', 'positionfrom', path, *args - end - def protocol(name, func=None) - func = install_cmd(func) if not func == None - tk_call 'wm', 'command', path, name, func - end - def resizable(*args) - w = tk_call('wm', 'resizable', path, *args) - if args.length == 0 - list(w).collect{|e| bool(e)} - end - end - def sizefrom(*args) - list(tk_call('wm', 'sizefrom', path, *args)) - end - def state - tk_call 'wm', 'state', path - end - def title(*args) - tk_call 'wm', 'title', path, *args - end - def transient(*args) - tk_call 'wm', 'transient', path, *args - end - def withdraw - tk_call 'wm', 'withdraw', path - end - end -end diff --git a/lib/tracer.rb b/lib/tracer.rb index d37339fd62..ef03fe09c9 100644 --- a/lib/tracer.rb +++ b/lib/tracer.rb @@ -1,7 +1,23 @@ +#!/usr/local/bin/ruby +# +# tracer.rb - +# $Release Version: 0.2$ +# $Revision: 1.6 $ +# $Date: 1998/02/02 08:12:02 $ +# 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.6 1998/02/02 08:12:02 keiju Exp keiju $-' + + MY_FILE_NAME = caller(0)[0].scan(/^(.*):[0-9]+$/)[0] EVENT_SYMBOL = { "line" => "-", @@ -10,11 +26,31 @@ 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 + + @sources = Hash.new + 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" + end end def off @@ -22,27 +58,38 @@ class Tracer print "Trace off\n" end - def get_thread_no - unless no = Threads[Thread.current.id] - Threads[Thread.current.id] = no = Threads.size + def get_line(file, line) + 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 + if l = list[line - 1] + l + else + "-\n" end - no end - def get_line(file, line) - unless list = Sources[file] - f =open(file) - begin - Sources[file] = list = f.readlines - ensure - f.close - end + def get_thread_no + if no = @threads[Thread.current.id] + no + else + @threads[Thread.current.id] = @threads.size end - list[line - 1] 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 Thread.critical = TRUE printf("#%d:%s:%d:%s: %s", @@ -65,11 +112,15 @@ class Tracer end -if File.basename($0) =~ Tracer::MY_FILE_NAME_PATTERN - $0 = ARGV.shift - - Tracer.on - load $0 -else - Tracer.on +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 93b2c65ecd..18d3bbc9a3 100644 --- a/lib/weakref.rb +++ b/lib/weakref.rb @@ -10,7 +10,7 @@ require "delegate" -class WeakRef<Delegater +class WeakRef<Delegator Exception :RefError |