aboutsummaryrefslogtreecommitdiffstats
path: root/sample
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-01-16 12:13:05 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-01-16 12:13:05 +0000
commit3db12e8b236ac8f88db8eb4690d10e4a3b8dbcd4 (patch)
treeb3c086e437cab449f90ba637710daed0ddfec4c4 /sample
parent392296c12de9d7f9be03a8205250ba0844cb9d38 (diff)
downloadruby-3db12e8b236ac8f88db8eb4690d10e4a3b8dbcd4.tar.gz
Initial revisionv1_0_r2
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'sample')
-rw-r--r--sample/biorhythm.rb138
-rw-r--r--sample/clnt.rb17
-rw-r--r--sample/dbmtest.rb14
-rw-r--r--sample/dir.rb10
-rw-r--r--sample/eval.rb42
-rw-r--r--sample/export.rb40
-rw-r--r--sample/exyacc.rb22
-rw-r--r--sample/fact.rb8
-rw-r--r--sample/fib.awk5
-rw-r--r--sample/fib.pl10
-rw-r--r--sample/fib.rb10
-rw-r--r--sample/fib.scm6
-rw-r--r--sample/freq.rb13
-rw-r--r--sample/from.rb87
-rw-r--r--sample/fullpath.rb23
-rw-r--r--sample/getopts.test36
-rw-r--r--sample/io.rb44
-rw-r--r--sample/less.rb17
-rw-r--r--sample/list.rb80
-rw-r--r--sample/list2.rb16
-rw-r--r--sample/list3.rb18
-rw-r--r--sample/mkproto.rb27
-rw-r--r--sample/mpart.rb44
-rw-r--r--sample/mrshtest.rb14
-rw-r--r--sample/observ.rb31
-rw-r--r--sample/occur.pl9
-rw-r--r--sample/occur.rb12
-rw-r--r--sample/occur2.rb16
-rw-r--r--sample/philos.rb54
-rw-r--r--sample/pi.rb18
-rw-r--r--sample/rcs.awk33
-rw-r--r--sample/rcs.dat17
-rw-r--r--sample/rcs.rb49
-rw-r--r--sample/regx.rb23
-rw-r--r--sample/ruby-mode.el644
-rw-r--r--sample/rubydb2x.el104
-rw-r--r--sample/rubydb3x.el104
-rw-r--r--sample/sieve.rb18
-rw-r--r--sample/svr.rb32
-rw-r--r--sample/test.rb943
-rw-r--r--sample/time.rb8
-rw-r--r--sample/tkbiff.rb149
-rw-r--r--sample/tkbrowse.rb69
-rw-r--r--sample/tkdialog.rb62
-rw-r--r--sample/tkfrom.rb126
-rw-r--r--sample/tkhello.rb13
-rw-r--r--sample/tkline.rb46
-rw-r--r--sample/tktimer.rb50
-rw-r--r--sample/trojan.rb14
-rw-r--r--sample/tsvr.rb23
-rw-r--r--sample/uumerge.rb37
51 files changed, 3445 insertions, 0 deletions
diff --git a/sample/biorhythm.rb b/sample/biorhythm.rb
new file mode 100644
index 0000000000..50ad1f2ef7
--- /dev/null
+++ b/sample/biorhythm.rb
@@ -0,0 +1,138 @@
+#!/usr/local/bin/ruby
+#
+# biorhythm.rb -
+# $Release Version: $
+# $Revision$
+# $Date$
+# by Yasuo OHBA(STAFS Development Room)
+#
+# --
+#
+#
+#
+
+include Math
+require "date.rb"
+require "parsearg.rb"
+
+def usage()
+ print "Usage:\n"
+ print "biorhythm.rb [options]\n"
+ print " options...\n"
+ print " -D YYYYMMDD(birthday) : すべて default 値を使う. \n"
+ print " --sdate | --date YYYYMMDD : system date もしくは指定した日付を使う.\n"
+ print " --birthday YYYYMMDD : 誕生日の指定をする. \n"
+ print " -v | -g : Values or Graph の指定. \n"
+ print " --days DAYS : 期間の指定をする(Graph の時のみ有効). \n"
+ print " --help : help\n"
+end
+$USAGE = 'usage'
+
+def printHeader(y, m, d, p, w)
+ print "\n>>> Biorhythm <<<\n"
+ printf "The birthday %04d.%02d.%02d is a %s\n", y, m, d, w
+ printf "Age in days: [%d]\n\n", p
+end
+
+def getPosition(z)
+ pi = 3.14159265
+ phys = (50.0 * (1.0 + sin((z / 23.0 - (z / 23)) * 360.0 * pi / 180.0))).to_i
+ emot = (50.0 * (1.0 + sin((z / 28.0 - (z / 28)) * 360.0 * pi / 180.0))).to_i
+ geist =(50.0 * (1.0 + sin((z / 33.0 - (z / 33)) * 360.0 * pi / 180.0))).to_i
+ return phys, emot, geist
+end
+
+#
+# main program
+#
+parseArgs(0, nil, "vg", "D:", "sdate", "date:", "birthday:", "days:")
+
+if $OPT_D
+ dd = Date.new(Time.now.strftime("%Y%m%d"))
+ bd = Date.new($OPT_D)
+ ausgabeart = "g"
+else
+ if $OPT_birthday
+ bd = Date.new($OPT_birthday)
+ else
+ printf(STDERR, "Birthday (YYYYMMDD) : ")
+ if (si = STDIN.gets.chop) != ""
+ bd = Date.new(si)
+ end
+ end
+ if !bd
+ printf STDERR, "BAD Input Birthday!!\n"
+ exit()
+ end
+
+ if $OPT_sdate
+ dd = Date.new(Time.now.strftime("%Y%m%d"))
+ elsif $OPT_date
+ dd = Date.new($OPT_date)
+ else
+ printf(STDERR, "Date [<RETURN> for Systemdate] (YYYYMMDD) : ")
+ if (si = STDIN.gets.chop) != ""
+ dd = Date.new(si)
+ end
+ end
+ if !dd
+ dd = Date.new(Time.now.strftime("%Y%m%d"))
+ end
+
+ if $OPT_v
+ ausgabeart = "v"
+ elsif $OPT_g
+ ausgabeart = "g"
+ else
+ printf(STDERR, "Values for today or Graph (v/g) [default g] : ")
+ ausgabeart = STDIN.gets.chop
+ end
+end
+if (ausgabeart == "v")
+ printHeader(bd.year, bd.month, bd.day, dd.period - bd.period, bd.name_of_week)
+ print "\n"
+
+ phys, emot, geist = getPosition(dd.period - bd.period)
+ printf "Biorhythm: %04d.%02d.%02d\n", dd.year, dd.month, dd.day
+ printf "Physical: %d%%\n", phys
+ printf "Emotional: %d%%\n", emot
+ printf "Mental: %d%%\n", geist
+ print "\n"
+else
+ if $OPT_days
+ display_period = $OPT_days.to_i
+ elsif $OPT_D
+ display_period = 9
+ else
+ printf(STDERR, "Graph for how many days [default 10] : ")
+ display_period = STDIN.gets.chop
+ if (display_period == "")
+ display_period = 9
+ else
+ display_period = display_period.to_i - 1
+ end
+ end
+
+ printHeader(bd.year, bd.month, bd.day, dd.period - bd.period, bd.name_of_week)
+ print " P=physical, E=emotional, M=mental\n"
+ print " -------------------------+-------------------------\n"
+ print " Bad Condition | Good Condition\n"
+ print " -------------------------+-------------------------\n"
+
+ for z in (dd.period - bd.period)..(dd.period - bd.period + display_period)
+ phys, emot, geist = getPosition(z)
+
+ printf "%04d.%02d.%02d : ", dd.year, dd.month, dd.day
+ p = (phys / 2.0 + 0.5).to_i
+ e = (emot / 2.0 + 0.5).to_i
+ g = (geist / 2.0 + 0.5).to_i
+ graph = "." * 51
+ graph[25] = ?|
+ graph[p] = ?P
+ graph[e] = ?E
+ graph[g] = ?M
+ print graph, "\n"
+ dd = dd + 1
+ end
+ print " -------------------------+-------------------------\n\n"
+end
diff --git a/sample/clnt.rb b/sample/clnt.rb
new file mode 100644
index 0000000000..7998379aa2
--- /dev/null
+++ b/sample/clnt.rb
@@ -0,0 +1,17 @@
+# socket example - client side
+# usage: ruby clnt.rb [host] port
+
+require "socket"
+
+host=(if ARGV.length == 2; ARGV.shift; else "localhost"; end)
+print("Trying ", host, " ...")
+STDOUT.flush
+s = TCPsocket.open(host, ARGV.shift)
+print(" done\n")
+print("addr: ", s.addr.join(":"), "\n")
+print("peer: ", s.peeraddr.join(":"), "\n")
+while gets()
+ s.write($_)
+ print(s.readline)
+end
+s.close
diff --git a/sample/dbmtest.rb b/sample/dbmtest.rb
new file mode 100644
index 0000000000..c77cc2065b
--- /dev/null
+++ b/sample/dbmtest.rb
@@ -0,0 +1,14 @@
+# ruby dbm acess
+require "dbm"
+
+d = DBM.open("test")
+keys = d.keys
+if keys.length > 0 then
+ for k in keys; print k, "\n"; end
+ for v in d.values; print v, "\n"; end
+else
+ d['foobar'] = 'FB'
+ d['baz'] = 'BZ'
+ d['quux'] = 'QX'
+end
+
diff --git a/sample/dir.rb b/sample/dir.rb
new file mode 100644
index 0000000000..2465c4d68e
--- /dev/null
+++ b/sample/dir.rb
@@ -0,0 +1,10 @@
+# directory access
+# list all files but .*/*~/*.o
+dirp = Dir.open(".")
+for f in dirp
+ $_ = f
+ unless (~/^\./ || ~/~$/ || ~/\.o/)
+ print f, "\n"
+ end
+end
+dirp.close
diff --git a/sample/eval.rb b/sample/eval.rb
new file mode 100644
index 0000000000..216bf8ca39
--- /dev/null
+++ b/sample/eval.rb
@@ -0,0 +1,42 @@
+line = ''
+indent=0
+$stdout.sync = TRUE
+print "ruby> "
+while TRUE
+ l = gets
+ unless l
+ break if line == ''
+ else
+ line = line + l
+ if l =~ /,\s*$/
+ print "ruby| "
+ next
+ end
+ if l =~ /^\s*(class|module|def|if|case|while|for|begin)\b[^_]/
+ indent += 1
+ end
+ if l =~ /^\s*end\b[^_]/
+ indent -= 1
+ end
+ if l =~ /\{\s*(\|.*\|)?\s*$/
+ indent += 1
+ end
+ if l =~ /^\s*\}/
+ indent -= 1
+ end
+ if indent > 0
+ print "ruby| "
+ next
+ end
+ end
+ begin
+ print eval(line).inspect, "\n"
+ rescue
+ $! = 'exception raised' unless $!
+ print "ERR: ", $!, "\n"
+ end
+ break if not l
+ line = ''
+ print "ruby> "
+end
+print "\n"
diff --git a/sample/export.rb b/sample/export.rb
new file mode 100644
index 0000000000..949e5b10bf
--- /dev/null
+++ b/sample/export.rb
@@ -0,0 +1,40 @@
+# method access permission
+# output:
+# foobar
+# Foo
+
+class Foo
+ public :printf
+ def baz
+ print "baz\n"
+ end
+ private :baz
+
+ def quux
+ print "in QUUX "
+ baz()
+ end
+end
+
+def foobar
+ print "foobar\n"
+end
+
+f = Foo.new
+#Foo.private :printf
+class Foo # redefines foobar's scope
+ public :foobar
+end
+f.foobar
+f.printf "%s\n", Foo
+
+f.quux
+
+class Bar<Foo
+ def quux
+ super
+ baz()
+ end
+end
+
+Bar.new.quux
diff --git a/sample/exyacc.rb b/sample/exyacc.rb
new file mode 100644
index 0000000000..dbe0dee710
--- /dev/null
+++ b/sample/exyacc.rb
@@ -0,0 +1,22 @@
+#! /usr/local/bin/ruby -Kn
+# usage: exyacc.rb [yaccfiles]
+# this is coverted from exyacc.pl in the camel book
+
+$/ = nil
+
+while gets()
+ sbeg = $_.index("\n%%") + 1
+ send = $_.rindex("\n%%") + 1
+ $_ = $_[sbeg, send-sbeg]
+ sub!(/.*\n/, "")
+ gsub!(/'{'/, "'\001'")
+ gsub!(/'}'/, "'\002'")
+ gsub!('\*/', "\003\003")
+ gsub!("/\\*[^\003]*\003\003", '')
+ while gsub!(/\{[^{}]*}/, ''); end
+ gsub!(/'\001'/, "'{'")
+ gsub!(/'\002'/, "'}'")
+ while gsub!(/^[ \t]*\n(\s)/, '\1'); end
+ gsub!(/([:|])[ \t\n]+(\w)/, '\1 \2')
+ print $_
+end
diff --git a/sample/fact.rb b/sample/fact.rb
new file mode 100644
index 0000000000..49678bc9d0
--- /dev/null
+++ b/sample/fact.rb
@@ -0,0 +1,8 @@
+def fact(n)
+ if n == 0
+ 1
+ else
+ n * fact(n-1)
+ end
+end
+print fact(ARGV[0].to_i), "\n"
diff --git a/sample/fib.awk b/sample/fib.awk
new file mode 100644
index 0000000000..7ebe8930f5
--- /dev/null
+++ b/sample/fib.awk
@@ -0,0 +1,5 @@
+ function fib(n) {
+ if ( n<2 ) return n; else return fib(n-2) + fib(n-1)
+ }
+
+ BEGIN { print fib(20); }
diff --git a/sample/fib.pl b/sample/fib.pl
new file mode 100644
index 0000000000..c5593764aa
--- /dev/null
+++ b/sample/fib.pl
@@ -0,0 +1,10 @@
+ sub fib {
+ local($n)=@_;
+ if( $n<2 ){
+ return $n;
+ } {
+ return &fib($n-2)+&fib($n-1)
+ }
+ }
+
+ print &fib(20), "\n";
diff --git a/sample/fib.rb b/sample/fib.rb
new file mode 100644
index 0000000000..cde4fba082
--- /dev/null
+++ b/sample/fib.rb
@@ -0,0 +1,10 @@
+# calculate Fibonacci(20)
+# for benchmark
+def fib(n)
+ if n<2
+ n
+ else
+ fib(n-2)+fib(n-1)
+ end
+end
+print(fib(20), "\n");
diff --git a/sample/fib.scm b/sample/fib.scm
new file mode 100644
index 0000000000..8eba75bb9e
--- /dev/null
+++ b/sample/fib.scm
@@ -0,0 +1,6 @@
+(define (fib n)
+ (if (< n 2)
+ n
+ (+ (fib (- n 2)) (fib (- n 1)))))
+
+(fib 20)
diff --git a/sample/freq.rb b/sample/freq.rb
new file mode 100644
index 0000000000..d951591735
--- /dev/null
+++ b/sample/freq.rb
@@ -0,0 +1,13 @@
+# word occurrence listing
+# usege: ruby freq.rb file..
+freq = {}
+while gets
+ while sub!(/\w+/, '')
+ word = $&
+ freq[word] +=1
+ end
+end
+
+for word in freq.keys.sort
+ printf("%s -- %d\n", word, freq[word])
+end
diff --git a/sample/from.rb b/sample/from.rb
new file mode 100644
index 0000000000..d39bb70084
--- /dev/null
+++ b/sample/from.rb
@@ -0,0 +1,87 @@
+#! /usr/local/bin/ruby
+
+require "parsedate"
+require "kconv"
+require "mailread"
+
+include ParseDate
+include Kconv
+
+class String
+
+ public :kconv
+
+ def kconv(code = Kconv::EUC)
+ Kconv.kconv(self, code, Kconv::AUTO)
+ end
+
+ def kjust(len)
+ len += 1
+ me = self[0, len].ljust(len)
+ if me =~ /.$/ and $&.size == 2
+ me[-2, 2] = ' '
+ end
+ me.chop!
+ end
+
+end
+
+if ARGV[0] == '-w'
+ wait = TRUE
+ ARGV.shift
+end
+
+if ARGV.length == 0
+ user = ENV['USER']
+else
+ user = ARGV[0]
+end
+
+[ENV['SPOOLDIR'], '/usr/spool', '/var/spool', '/usr', '/var'].each do |m|
+ break if File.exist? ARGV[0] = "#{m}/mail/#{user}"
+end
+
+$outcount = 0;
+def fromout(date, from, subj)
+ return if !date
+ y = m = d = 0
+ y, m, d = parsedate(date) if date
+ if from
+ from.gsub! /\n/, ""
+ else
+ from = "sombody@somewhere"
+ end
+ if subj
+ subj.gsub! /\n/, ""
+ else
+ subj = "(nil)"
+ end
+ if ENV['LANG'] =~ /sjis/i
+ lang = Kconv::SJIS
+ else
+ lang = Kconv::EUC
+ end
+ from = from.kconv(lang).kjust(28)
+ subj = subj.kconv(lang).kjust(40)
+ printf "%02d/%02d/%02d [%s] %s\n",y,m,d,from,subj
+ $outcount += 1
+end
+
+for file in ARGV
+ next if !File.exist?(file)
+ f = open(file, "r")
+ while !f.eof?
+ mail = Mail.new(f)
+ fromout mail.header['Date'], mail.header['From'], mail.header['Subject']
+ end
+ f.close
+end
+
+if $outcount == 0
+ print "You have no mail.\n"
+ sleep 2 if wait
+elsif wait
+ system "stty cbreak -echo"
+ getc()
+ system "stty cooked echo"
+end
diff --git a/sample/fullpath.rb b/sample/fullpath.rb
new file mode 100644
index 0000000000..ce268e20b9
--- /dev/null
+++ b/sample/fullpath.rb
@@ -0,0 +1,23 @@
+#! /usr/local/bin/ruby
+# convert ls-lR filename into fullpath.
+
+if ARGV[0] =~ /-p/
+ ARGV.shift
+ path = ARGV.shift
+end
+
+if path == nil
+ path = ""
+elsif path !~ /\/$/
+ path += "/"
+end
+
+while gets()
+ if /:$/
+ path = $_.chop.chop + "/"
+ elsif /^total/ || /^d/
+ elsif /^(.*\d )(.+)$/
+ print($1, path, $2, "\n")
+ end
+end
+
diff --git a/sample/getopts.test b/sample/getopts.test
new file mode 100644
index 0000000000..2866bccea8
--- /dev/null
+++ b/sample/getopts.test
@@ -0,0 +1,36 @@
+#! /usr/local/bin/ruby
+
+load("parsearg.rb")
+
+def usage()
+ printf "Usage:\n"
+ printf "%s -d [-x x] [-y y] [--geometry geom] [--version] [string ...]\n", $0
+end
+
+$USAGE = 'usage'
+parseArgs(0, "d&(x|y)", "dfg", "x:", "y:", "geometry:800x600", "version")
+if ($OPT_d)
+ if $OPT_version
+ printf "version 1.0\n"
+ end
+ if ($OPT_x)
+ printf("x = %d\n", $OPT_x.to_i)
+ end
+ if ($OPT_y)
+ printf("y = %d\n", $OPT_y.to_i)
+ end
+ if ($OPT_geometry)
+ printf("geometry = %s\n", $OPT_geometry)
+ end
+ if $OPT_f
+ printf "f = TRUE\n"
+ end
+ if $OPT_g
+ printf "g = TRUE\n"
+ end
+end
+
+while (ARGV.length != 0)
+ print "other = ", ARGV[0], "\n"
+ ARGV.shift
+end
diff --git a/sample/io.rb b/sample/io.rb
new file mode 100644
index 0000000000..0b38d2112d
--- /dev/null
+++ b/sample/io.rb
@@ -0,0 +1,44 @@
+# IO test
+# usage: ruby io.rb file..
+
+home = ENV["HOME"]
+home.sub("m", "&&")
+print(home, "\n")
+print(home.reverse, "\n")
+
+if File.s("io.rb")
+ print(File.s("io.rb"), ": io.rb\n")
+end
+
+$/="f\n"
+for i in "abc\n\ndef\nghi\n"
+ print("tt: ", i)
+end
+
+printf("%s:(%d)%s\n", $0, ARGV.length, ARGV[0])
+passwd = open(ARGV[0], "r")
+#printf("%s", passwd.find{i|i =~ /\*/})
+
+n = 1
+for i in passwd #.grep(/^\*/)
+ printf("%6d: %s", n, i)
+ n = n + 1;
+end
+
+fp = open("|-", "r")
+
+if fp == nil
+ for i in 1..5
+ print(i, "\n")
+ end
+else
+ for line in fp
+ print(line)
+ end
+end
+
+def printUsage()
+ if $USAGE
+ apply($USAGE);
+ end
+end
diff --git a/sample/less.rb b/sample/less.rb
new file mode 100644
index 0000000000..8be359108f
--- /dev/null
+++ b/sample/less.rb
@@ -0,0 +1,17 @@
+#! /usr/local/bin/ruby
+
+ZCAT = "/usr/local/bin/zcat"
+LESS = "/usr/local/bin/less"
+
+FILE = ARGV.pop
+OPTION = (if ARGV.length == 0; "" else ARGV.join(" "); end)
+
+if FILE =~ /\.(Z|gz)$/
+ exec(format("%s %s | %s %s", ZCAT, FILE, LESS, OPTION))
+elsif FILE == nil
+ exec(format("%s %s", LESS, OPTION))
+else
+ print(format("%s %s %s", LESS, OPTION, FILE), "\n")
+ exec(format("%s %s %s", LESS, OPTION, FILE))
+end
+exit()
diff --git a/sample/list.rb b/sample/list.rb
new file mode 100644
index 0000000000..76035e67d6
--- /dev/null
+++ b/sample/list.rb
@@ -0,0 +1,80 @@
+# Linked list example
+class MyElem
+ # オブジェクト生成時に自動的に呼ばれるメソッド
+ def initialize(item)
+ # @変数はインスタンス変数(宣言は要らない)
+ @data = item
+ @succ = nil
+ end
+
+ def data
+ @data
+ end
+
+ def succ
+ @succ
+ end
+
+ # 「obj.data = val」としたときに暗黙に呼ばれるメソッド
+ def succ=(new)
+ @succ = new
+ end
+end
+
+class MyList
+ def add_to_list(obj)
+ elt = MyElem.new(obj)
+ if @head
+ @tail.succ = elt
+ else
+ @head = elt
+ end
+ @tail = elt
+ end
+
+ def each
+ elt = @head
+ while elt
+ yield elt
+ elt = elt.succ
+ end
+ end
+
+ # オブジェクトを文字列に変換するメソッド
+ # これを再定義するとprintでの表現が変わる
+ def to_s
+ str = "<MyList:\n";
+ for elt in self
+ # 「str = str + elt.data.to_s + "\n"」の省略形
+ str += elt.data.to_s + "\n"
+ end
+ str += ">"
+ str
+ end
+end
+
+class Point
+ def initialize(x, y)
+ @x = x; @y = y
+ self
+ end
+
+ def to_s
+ sprintf("%d@%d", @x, @y)
+ end
+end
+
+# 大域変数は`$'で始まる.
+$list1 = MyList.new
+$list1.add_to_list(10)
+$list1.add_to_list(20)
+$list1.add_to_list(Point.new(2, 3))
+$list1.add_to_list(Point.new(4, 5))
+$list2 = MyList.new
+$list2.add_to_list(20)
+$list2.add_to_list(Point.new(4, 5))
+$list2.add_to_list($list1)
+
+# 曖昧でない限りメソッド呼び出しの括弧は省略できる
+print "list1:\n", $list1, "\n"
+print "list2:\n", $list2, "\n"
diff --git a/sample/list2.rb b/sample/list2.rb
new file mode 100644
index 0000000000..914cb8996e
--- /dev/null
+++ b/sample/list2.rb
@@ -0,0 +1,16 @@
+# Linked list example -- short version
+class Point
+ def initialize(x, y)
+ @x = x; @y = y
+ self
+ end
+
+ def to_s
+ sprintf("%d@%d", @x, @y)
+ end
+end
+
+list1 = [10, 20, Point.new(2, 3), Point.new(4, 5)]
+list2 = [20, Point.new(4, 5), list1]
+print("list1:\n", list1.join("\n"), "\n")
+print("list2:\n", list2.join("\n"), "\n")
diff --git a/sample/list3.rb b/sample/list3.rb
new file mode 100644
index 0000000000..1d756fdff0
--- /dev/null
+++ b/sample/list3.rb
@@ -0,0 +1,18 @@
+# Linked list example -- short version
+# using inspect
+
+class Point
+ def initialize(x, y)
+ @x = x; @y = y
+ self
+ end
+
+ def to_s
+ sprintf("%d@%d", @x, @y)
+ end
+end
+
+list1 = [10, 20, Point.new(2, 3), Point.new(4, 5)]
+list2 = [20, Point.new(4, 5), list1]
+print("list1: ", list1.inspect, "\n")
+print("list2: ", list2.inspect, "\n")
diff --git a/sample/mkproto.rb b/sample/mkproto.rb
new file mode 100644
index 0000000000..1d9c9faccb
--- /dev/null
+++ b/sample/mkproto.rb
@@ -0,0 +1,27 @@
+$/ = nil
+while gets()
+ if /^((void|VALUE|int|char *\*|ID|struct [\w_]+ *\*|st_table *\*) *)?\n([\w\d_]+)\(.*\)\n\s*((.+;\n)*){/
+ $_ = $'
+ printf "%s %s(", $2, $3
+ args = []
+ for arg in $4.split(/;\n\s*/)
+ arg.gsub! ' +', ' '
+ if arg =~ /,/
+ if arg =~ /(([^*]+) *\** *[\w\d_]+),/
+ type = $2.strip!
+ args.push $1.strip!
+ arg = $'
+ else
+ type = ""
+ end
+ while arg.sub!(/(\** *[\w\d_]+)(,|$)/, "")
+ args.push type + " " + $1.strip!
+ end
+ else
+ args.push arg.strip!
+ end
+ end
+ printf "%s);\n", args.join(', ')
+ redo
+ end
+end
diff --git a/sample/mpart.rb b/sample/mpart.rb
new file mode 100644
index 0000000000..6c40d50e18
--- /dev/null
+++ b/sample/mpart.rb
@@ -0,0 +1,44 @@
+#! ./ruby
+# split into multi part
+# usage: mpart.rb [-nnn] file..
+
+lines = 1000
+
+if (ARGV[0] =~ /^-(\d+)$/ )
+ lines = $1.to_i;
+ ARGV.shift;
+end
+
+basename = ARGV[0]
+extname = "part"
+
+part = 1
+line = 0
+
+fline = 0
+for i in ifp = open(basename)
+ fline = fline + 1
+end
+ifp.close
+
+parts = fline / lines + 1
+
+for i in ifp = open(basename)
+ if line == 0
+ ofp = open(sprintf("%s.%s%02d", basename, extname, part), "w")
+ printf(ofp, "%s part%02d/%02d\n", basename, part, parts)
+ ofp.write("BEGIN--cut here--cut here\n")
+ end
+ ofp.write(i)
+ line = line + 1
+ if line >= lines
+ ofp.write("END--cut here--cut here\n")
+ ofp.close
+ part = part + 1
+ line = 0
+ end
+end
+ofp.write("END--cut here--cut here\n")
+ofp.close
+
+ifp.close
diff --git a/sample/mrshtest.rb b/sample/mrshtest.rb
new file mode 100644
index 0000000000..402b35ad55
--- /dev/null
+++ b/sample/mrshtest.rb
@@ -0,0 +1,14 @@
+require "marshal"
+include Marshal
+a = 25.6;
+pt = Struct.new('Point', :x,:y);
+x = pt.new(10, 10)
+y = pt.new(20, 20)
+rt = Struct.new('Rectangle', :origin,:corner);
+z = rt.new(x, y)
+c = Object.new
+s = [a, x, z, c, c, "fff"];
+p s
+d = dump(s);
+p d
+p load(d)
diff --git a/sample/observ.rb b/sample/observ.rb
new file mode 100644
index 0000000000..f7b1e73137
--- /dev/null
+++ b/sample/observ.rb
@@ -0,0 +1,31 @@
+#! /usr/local/bin/ruby
+
+require "thread"
+require "observer"
+
+class Tick
+ include Observable
+ def initialize
+ Thread.start do
+ while TRUE
+ sleep 0.999
+ changed
+ notify_observers(Time.now.strftime("%H:%M:%S"))
+ end
+ end
+ end
+end
+
+class Clock
+ def initialize
+ @tick = Tick.new
+ @tick.add_observer(self)
+ end
+ def update(time)
+ print "\e[8D", time
+ STDOUT.flush
+ end
+end
+
+clock = Clock.new
+sleep
diff --git a/sample/occur.pl b/sample/occur.pl
new file mode 100644
index 0000000000..1f5fcf27a4
--- /dev/null
+++ b/sample/occur.pl
@@ -0,0 +1,9 @@
+while (<>) {
+ for (split(/\W+/)) {
+ $freq{$_}++;
+ }
+}
+
+for (sort keys %freq) {
+ print "$_ -- $freq{$_}\n";
+}
diff --git a/sample/occur.rb b/sample/occur.rb
new file mode 100644
index 0000000000..2141fade38
--- /dev/null
+++ b/sample/occur.rb
@@ -0,0 +1,12 @@
+# word occurrence listing
+# usege: ruby occur.rb file..
+freq = {}
+while gets()
+ for word in $_.split(/\W+/)
+ freq[word] +=1
+ end
+end
+
+for word in freq.keys.sort
+ printf("%s -- %d\n", word, freq[word])
+end
diff --git a/sample/occur2.rb b/sample/occur2.rb
new file mode 100644
index 0000000000..c450c30b0f
--- /dev/null
+++ b/sample/occur2.rb
@@ -0,0 +1,16 @@
+# word occurrence listing
+# usege: ruby occur2.rb file..
+freq = {}
+while gets()
+ for word in $_.split(/\W+/)
+ begin
+ freq[word] = freq[word] + 1
+ rescue
+ freq[word] = 1
+ end
+ end
+end
+
+for word in freq.keys.sort
+ printf("%s -- %d\n", word, freq[word])
+end
diff --git a/sample/philos.rb b/sample/philos.rb
new file mode 100644
index 0000000000..3ccb052532
--- /dev/null
+++ b/sample/philos.rb
@@ -0,0 +1,54 @@
+#
+# The Dining Philosophers - thread example
+#
+require "thread"
+
+srand
+#srand
+N=9 # number of philosophers
+$forks = []
+for i in 0..N-1
+ $forks[i] = Mutex.new
+end
+$state = "-o"*N
+
+def wait
+ sleep rand(20)/10.0
+end
+
+def think(n)
+ wait
+end
+
+def eat(n)
+ wait
+end
+
+def philosopher(n)
+ while TRUE
+ think n
+ $forks[n].lock
+ if not $forks[(n+1)%N].try_lock
+ $forks[n].unlock # avoid deadlock
+ next
+ end
+ $state[n*2] = ?|;
+ $state[(n+1)%N*2] = ?|;
+ $state[n*2+1] = ?*;
+ print $state, "\n"
+ eat(n)
+ $state[n*2] = ?-;
+ $state[(n+1)%N*2] = ?-;
+ $state[n*2+1] = ?o;
+ print $state, "\n"
+ $forks[n].unlock
+ $forks[(n+1)%N].unlock
+ end
+end
+
+for i in 0..N-1
+ Thread.start{philosopher(i)}
+ sleep 0.1
+end
+
+sleep
diff --git a/sample/pi.rb b/sample/pi.rb
new file mode 100644
index 0000000000..49067cc347
--- /dev/null
+++ b/sample/pi.rb
@@ -0,0 +1,18 @@
+#!/usr/local/bin/ruby
+
+k, a, b, a1, b1 = 2, 4, 1, 12, 4
+
+while TRUE
+ # Next approximation
+ p, q, k = k*k, 2*k+1, k+1
+ a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
+ # Print common digits
+ d = a / b
+ d1 = a1 / b1
+ while d == d1
+ print d
+ $stdout.flush
+ a, a1 = 10*(a%b), 10*(a1%b1)
+ d, d1 = a/b, a1/b1
+ end
+end
diff --git a/sample/rcs.awk b/sample/rcs.awk
new file mode 100644
index 0000000000..08979285c9
--- /dev/null
+++ b/sample/rcs.awk
@@ -0,0 +1,33 @@
+BEGIN {
+ sw = 40.0;
+ dw = 78.0;
+ hdw = dw / 2.0;
+ w = 20.0;
+ h =1.0;
+ d = 0.2;
+ ss="abcdefghijklmnopqrstuvwxyz0123456789!#$%^&*()-=\\[];'`,./";
+ rnd = srand();
+}
+
+{
+ xr = -hdw; y = h * 1.0; maxxl = -999;
+ s = "";
+ while (xr < hdw) {
+ x = xr * (1 + y) - y * w / 2;
+ i = (x / (1 + h) + sw /2);
+ c = (0 < i && i < length($0)) ? substr($0, i, 1) : "0";
+ y = h - d * c;
+ xl = xr - w * y / (1 + y);
+ if (xl < -hdw || xl >= hdw || xl <= maxxl) {
+ t = rand() * length(ss);
+ c = substr(ss, t, 1);
+ }
+ else {
+ c = substr(s, xl + hdw, 1);
+ maxxl = xl;
+ }
+ s = s c;
+ xr = xr + 1;
+ }
+ print s;
+}
diff --git a/sample/rcs.dat b/sample/rcs.dat
new file mode 100644
index 0000000000..61c88bff89
--- /dev/null
+++ b/sample/rcs.dat
@@ -0,0 +1,17 @@
+0000000000000000220000000000000000
+0000000000000111221110000000000000
+0000000000111112222111110000000000
+0000000111111112222111111110000000
+0000111111111122222211111111110000
+0111111111111222222221111111111110
+2222222222222222222222222222222222
+1122222222222222222222222222222211
+0111122222222222222222222222211110
+0011111122222222222222222211111100
+0001111111222222222222221111111000
+0000111112222222222222222111110000
+0000011122222222112222222211100000
+0000001122222221111222222211000000
+0000000122221111111111222210000000
+0000000221111111111111111220000000
+0000000000000000000000000000000000
diff --git a/sample/rcs.rb b/sample/rcs.rb
new file mode 100644
index 0000000000..3f74da9ef2
--- /dev/null
+++ b/sample/rcs.rb
@@ -0,0 +1,49 @@
+# random dot steraogram
+# usage: rcs.rb rcs.dat
+
+sw = 40.0 # p^[
+dw = 78.0 # Random Character Streogram
+hdw = dw / 2.0
+w = 20.0 #
+h =1.0 #
+d = 0.2 # P
+ss="abcdefghijklmnopqrstuvwxyz0123456789#!$%^&*()-=\\[];'`,./"
+rnd = srand()
+
+while gets()
+# print($_)
+ xr = -hdw; y = h * 1.0; maxxl = -999
+ s = "";
+ while xr < hdw
+ x = xr * (1 + y) - y * w / 2
+ i = (x / (1 + h) + sw / 2)
+ if (1 < i && i < $_.length);
+ c = $_[i, 1].to_i
+ else
+ c = 0
+ end
+ y = h - d * c
+ xl = xr - w * y / (1 + y);
+ if xl < -hdw || xl >= hdw || xl <= maxxl
+ tt = rand(ss.length)
+ c = ss[tt, 1]
+ else
+ c = s[xl + hdw, 1]
+ maxxl = xl
+ end
+ s += c
+ xr += 1
+ end
+ print(s, "\n")
+end
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample/regx.rb b/sample/regx.rb
new file mode 100644
index 0000000000..aaf4b5f1ee
--- /dev/null
+++ b/sample/regx.rb
@@ -0,0 +1,23 @@
+st = "\033[7m"
+en = "\033[m"
+#st = "<<"
+#en = ">>"
+
+while TRUE
+ print "str> "
+ STDOUT.flush
+ input = gets
+ break if not input
+ if input != ""
+ str = input
+ str.chop!
+ end
+ print "pat> "
+ STDOUT.flush
+ re = gets
+ break if not re
+ re.chop!
+ str.gsub! re, "#{st}\\&#{en}"
+ print str, "\n"
+end
+print "\n"
diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el
new file mode 100644
index 0000000000..d8165bd23a
--- /dev/null
+++ b/sample/ruby-mode.el
@@ -0,0 +1,644 @@
+;;;
+;;; ruby-mode.el -
+;;;
+;;; $Author$
+;;; Time-stamp: <97/03/21 01:16:05 matz>
+;;; created at: Fri Feb 4 14:49:13 JST 1994
+;;;
+
+(defconst ruby-mode-version "1.0.7")
+
+(defconst ruby-block-beg-re
+ "class\\|module\\|def\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin\\|do"
+ )
+
+(defconst ruby-indent-beg-re
+ "\\(\\s *\\(class\\|module\\|def\\)\\)\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin"
+ )
+
+(defconst ruby-modifier-re
+ "if\\|unless\\|while\\|until"
+ )
+
+(defconst ruby-block-mid-re
+ "then\\|else\\|elsif\\|when\\|rescue\\|ensure"
+ )
+
+(defconst ruby-block-op-re
+ "and\\|or\\|not"
+ )
+
+(defconst ruby-block-end-re "end")
+
+(defconst ruby-delimiter
+ (concat "[?$/%(){}#\"'`]\\|\\[\\|\\]\\|\\<\\("
+ ruby-block-beg-re
+ "\\|" ruby-block-end-re
+ "\\)\\>\\|^=begin")
+ )
+
+(defconst ruby-negative
+ (concat "^[ \t]*\\(\\(" ruby-block-mid-re "\\)\\>\\|\\("
+ ruby-block-end-re "\\)\\>\\|\\}\\|\\]\\)")
+ )
+
+(defconst ruby-operator-chars "[,.+*/%-&|^~=<>:]")
+(defconst ruby-symbol-chars "[a-zA-Z0-9_]")
+
+(defvar ruby-mode-abbrev-table nil
+ "Abbrev table in use in ruby-mode buffers.")
+
+(define-abbrev-table 'ruby-mode-abbrev-table ())
+
+(defvar ruby-mode-map nil "Keymap used in ruby mode.")
+
+(if ruby-mode-map
+ nil
+ (setq ruby-mode-map (make-sparse-keymap))
+ (define-key ruby-mode-map "{" 'ruby-electric-brace)
+ (define-key ruby-mode-map "}" 'ruby-electric-brace)
+ (define-key ruby-mode-map "\e\C-a" 'ruby-beginning-of-defun)
+ (define-key ruby-mode-map "\e\C-e" 'ruby-end-of-defun)
+ (define-key ruby-mode-map "\e\C-b" 'ruby-beginning-of-block)
+ (define-key ruby-mode-map "\e\C-f" 'ruby-end-of-block)
+ (define-key ruby-mode-map "\e\C-p" 'ruby-beginning-of-block)
+ (define-key ruby-mode-map "\e\C-n" 'ruby-end-of-block)
+ (define-key ruby-mode-map "\t" 'ruby-indent-command)
+ (define-key ruby-mode-map "\C-c\C-e" 'ruby-insert-end)
+ (define-key ruby-mode-map "\C-j" 'ruby-reindent-then-newline-and-indent)
+ (define-key ruby-mode-map "\C-m" 'newline))
+
+(defvar ruby-mode-syntax-table nil
+ "Syntax table in use in ruby-mode buffers.")
+
+(if ruby-mode-syntax-table
+ ()
+ (setq ruby-mode-syntax-table (make-syntax-table))
+ (modify-syntax-entry ?\' "\"" ruby-mode-syntax-table)
+ (modify-syntax-entry ?\" "\"" ruby-mode-syntax-table)
+ (modify-syntax-entry ?\` "\"" ruby-mode-syntax-table)
+ (modify-syntax-entry ?# "<" ruby-mode-syntax-table)
+ (modify-syntax-entry ?\n ">" ruby-mode-syntax-table)
+ (modify-syntax-entry ?\\ "'" ruby-mode-syntax-table)
+ (modify-syntax-entry ?$ "/" ruby-mode-syntax-table)
+ (modify-syntax-entry ?? "_" ruby-mode-syntax-table)
+ (modify-syntax-entry ?_ "_" ruby-mode-syntax-table)
+ (modify-syntax-entry ?< "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?> "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?& "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?| "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?% "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?= "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?/ "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?+ "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?* "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?- "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?\; "." ruby-mode-syntax-table)
+ (modify-syntax-entry ?\( "()" ruby-mode-syntax-table)
+ (modify-syntax-entry ?\) ")(" ruby-mode-syntax-table)
+ (modify-syntax-entry ?\{ "(}" ruby-mode-syntax-table)
+ (modify-syntax-entry ?\} "){" ruby-mode-syntax-table)
+ (modify-syntax-entry ?\[ "(]" ruby-mode-syntax-table)
+ (modify-syntax-entry ?\] ")[" ruby-mode-syntax-table)
+ )
+
+(defvar ruby-indent-level 2
+ "*Indentation of ruby statements.")
+
+(defun ruby-mode ()
+ "Major mode for editing ruby scripts.
+\\[ruby-indent-command] properly indents subexpressions of multi-line
+class, module, def, if, while, for, do, and case statements, taking
+nesting into account.
+
+The variable ruby-indent-level controls the amount of indentation.
+\\{ruby-mode-map}"
+ (interactive)
+ (kill-all-local-variables)
+ (use-local-map ruby-mode-map)
+ (setq mode-name "ruby")
+ (setq major-mode 'ruby-mode)
+ (set-syntax-table ruby-mode-syntax-table)
+ (setq local-abbrev-table ruby-mode-abbrev-table)
+ (make-local-variable 'indent-line-function)
+ (setq indent-line-function 'ruby-indent-line)
+ (make-local-variable 'require-final-newline)
+ (setq require-final-newline t)
+ (make-variable-buffer-local 'comment-start)
+ (setq comment-start "# ")
+ (make-variable-buffer-local 'comment-end)
+ (setq comment-end "")
+ (make-variable-buffer-local 'comment-column)
+ (setq comment-column 32)
+ (make-variable-buffer-local 'comment-start-skip)
+ (setq comment-start-skip "#+ *")
+ (make-local-variable 'parse-sexp-ignore-comments)
+ (setq parse-sexp-ignore-comments t)
+ (run-hooks 'ruby-mode-hook))
+
+(defun ruby-current-indentation ()
+ (save-excursion
+ (beginning-of-line)
+ (back-to-indentation)
+ (current-column)))
+
+(defun ruby-indent-line (&optional flag)
+ "Correct indentation of the current ruby line."
+ (ruby-indent-to (ruby-calculate-indent)))
+
+(defun ruby-indent-command ()
+ (interactive)
+ (ruby-indent-line t))
+
+(defun ruby-indent-to (x)
+ (if x
+ (let (shift top beg)
+ (and (< x 0)
+ (error "invalid nest"))
+ (setq shift (current-column))
+ (beginning-of-line)
+ (setq beg (point))
+ (back-to-indentation)
+ (setq top (current-column))
+ (skip-chars-backward " \t")
+ (cond
+ ((>= x shift)
+ (setq shift 0))
+ ((>= shift top)
+ (setq shift (- shift top)))
+ (t (setq shift 0)))
+ (if (and (bolp)
+ (= x top))
+ (move-to-column (+ x shift))
+ (move-to-column top)
+ (delete-region beg (point))
+ (beginning-of-line)
+ (indent-to x)
+ (move-to-column (+ x shift))))))
+
+(defun ruby-expr-beg (&optional modifier)
+ (save-excursion
+ (if (looking-at "\\?")
+ (progn
+ (or (bolp) (forward-char -1))
+ (not (looking-at "\\sw")))
+ (skip-chars-backward " \t")
+ (or (bolp) (forward-char -1))
+ (or (looking-at ruby-operator-chars)
+ (looking-at "[\\[({!?]")
+ (bolp)
+ (and (looking-at ruby-symbol-chars)
+ (forward-word -1)
+ (or
+ (and modifier (bolp))
+ (looking-at ruby-block-beg-re)
+ (looking-at ruby-block-op-re)
+ (looking-at ruby-block-mid-re)
+ (and modifier
+ (save-excursion
+ (forward-char -1)
+ (let ((c (char-after (point))))
+ (or (eq c ?.)
+ (eq c ? )
+ (eq c ?\t))))))
+ (goto-char (match-end 0))
+ (looking-at "[^_]"))))))
+
+(defun ruby-parse-region (start end)
+ (let ((indent-point end)
+ (indent 0)
+ (in-string nil)
+ (in-paren nil)
+ (depth 0)
+ (nest nil)
+ (pcol nil))
+ (save-excursion
+ (if start
+ (goto-char start)
+ (ruby-beginning-of-indent))
+ (save-restriction
+ (narrow-to-region (point) end)
+ (while (and (> indent-point (point))
+ (re-search-forward ruby-delimiter indent-point t))
+ (let ((pnt (point)) w)
+ (goto-char (match-beginning 0))
+ (cond
+ ((or (looking-at "\"") ;skip string
+ (looking-at "'")
+ (looking-at "`"))
+ (setq w (char-after (point)))
+ (cond
+ ((and (not (eobp))
+ (re-search-forward (format "[^\\]%c" w) indent-point t))
+ nil)
+ (t
+ (setq in-string (point))
+ (goto-char indent-point))))
+ ((looking-at "/")
+ (cond
+ ((and (not (eobp)) (ruby-expr-beg))
+ (if (re-search-forward "[^\\]/" indent-point t)
+ nil
+ (setq in-string (point))
+ (goto-char indent-point)))
+ (t
+ (goto-char pnt))))
+ ((looking-at "%")
+ (cond
+ ((and (not (eobp)) (ruby-expr-beg)
+ (looking-at "%[Qqrx]?\\(.\\)"))
+ (setq w (buffer-substring (match-beginning 1)
+ (match-end 1)))
+ (cond
+ ((string= w "[") (setq w "]"))
+ ((string= w "{") (setq w "}"))
+ ((string= w "(") (setq w ")"))
+ ((string= w "<") (setq w ">")))
+ (goto-char (match-end 0))
+ (if (search-forward w indent-point t)
+ nil
+ (setq in-string (point))
+ (goto-char indent-point)))
+ (t
+ (goto-char pnt))))
+ ((looking-at "\\?") ;skip ?char
+ (cond
+ ((ruby-expr-beg)
+ (looking-at "?\\(\\\\C-\\|\\\\M-\\)*.")
+ (goto-char (match-end 0)))
+ (t
+ (goto-char pnt))))
+ ((looking-at "\\$") ;skip $char
+ (goto-char pnt)
+ (forward-char 1))
+ ((looking-at "#") ;skip comment
+ (forward-line 1)
+ (goto-char (point))
+ )
+ ((looking-at "(")
+ (setq nest (cons (cons (char-after (point)) pnt) nest))
+ (setq pcol (cons (cons pnt depth) pcol))
+ (setq depth 0)
+ (goto-char pnt)
+ )
+ ((looking-at "[\\[{]")
+ (setq nest (cons (cons (char-after (point)) pnt) nest))
+ (setq depth (1+ depth))
+ (goto-char pnt)
+ )
+ ((looking-at ")")
+ (setq nest (cdr nest))
+ (setq depth (cdr (car pcol)))
+ (setq pcol (cdr pcol))
+ (goto-char pnt))
+ ((looking-at "[])}]")
+ (setq nest (cdr nest))
+ (setq depth (1- depth))
+ (goto-char pnt))
+ ((looking-at ruby-block-end-re)
+ (if (or (and (not (bolp))
+ (progn
+ (forward-char -1)
+ (eq ?_ (char-after (point)))))
+ (progn
+ (goto-char pnt)
+ (setq w (char-after (point)))
+ (or (eq ?_ w)
+ (eq ?! w)
+ (eq ?? w))))
+ nil
+ (setq nest (cdr nest))
+ (setq depth (1- depth)))
+ (goto-char pnt))
+ ((looking-at ruby-block-beg-re)
+ (and
+ (or (bolp)
+ (progn
+ (forward-char -1)
+ (not (eq ?_ (char-after (point))))))
+ (progn
+ (goto-char pnt)
+ (setq w (char-after (point)))
+ (and (not (eq ?_ w))
+ (not (eq ?! w))
+ (not (eq ?? w))))
+ (progn
+ (goto-char (match-beginning 0))
+ (if (looking-at ruby-modifier-re)
+ (ruby-expr-beg)
+ t))
+ (progn
+ (setq nest (cons (cons nil pnt) nest))
+ (setq depth (1+ depth))))
+ (if (looking-at "def\\s *[/`]")
+ (goto-char (match-end 0))
+ (goto-char pnt)))
+ ((looking-at "^=begin")
+ (if (re-search-forward "^=end" indent-point t)
+ (forward-line 1)
+ (setq in-string (match-end 0))
+ (goto-char indent-point)))
+ (t
+ (error (format "bad string %s"
+ (buffer-substring (point) pnt)
+ )))))))
+ (list in-string (car nest) depth (car (car pcol))))))
+
+(defun ruby-calculate-indent (&optional parse-start)
+ (save-excursion
+ (beginning-of-line)
+ (let ((indent-point (point))
+ (case-fold-search nil)
+ state bol eol
+ (indent 0))
+ (if parse-start
+ (goto-char parse-start)
+ (ruby-beginning-of-indent)
+ (setq parse-start (point)))
+ (back-to-indentation)
+ (setq indent (current-column))
+ (setq state (ruby-parse-region parse-start indent-point))
+ (cond
+ ((nth 0 state) ; within string
+ (setq indent nil)) ; do nothing
+
+ ((car (nth 1 state)) ; in paren
+ (goto-char (cdr (nth 1 state)))
+ (if (eq (car (nth 1 state)) ?\( )
+ (let ((column (current-column))
+ (s (ruby-parse-region (point) indent-point)))
+ (cond
+ ((and (nth 2 s) (> (nth 2 s) 0))
+ (goto-char (cdr (nth 1 s)))
+ (forward-word -1)
+ (setq indent (+ (current-column) ruby-indent-level)))
+ (t
+ (setq indent (current-column)))))
+ (cond
+ ((nth 3 state)
+ (goto-char (nth 3 state))
+ (setq indent (+ (current-column) ruby-indent-level)))
+ (t
+ (goto-char parse-start)
+ (back-to-indentation)
+ (setq indent (+ (current-column) (* (nth 2 state) ruby-indent-level)))))
+ ))
+
+ ((and (nth 2 state)(> (nth 2 state) 0)) ; in nest
+ (goto-char (cdr (nth 1 state)))
+ (forward-word -1) ; skip back a keyword
+ (cond
+ ((looking-at "do") ; iter block is a special case
+ (cond
+ ((nth 3 state)
+ (goto-char (nth 3 state))
+ (setq indent (+ (current-column) ruby-indent-level)))
+ (t
+ (goto-char parse-start)
+ (back-to-indentation)
+ (setq indent (+ (current-column) (* (nth 2 state) ruby-indent-level))))))
+ (t
+ (setq indent (+ (current-column) ruby-indent-level)))))
+
+ ((and (nth 2 state) (< (nth 2 state) 0)) ; in negative nest
+ (setq indent (+ (current-column) (* (nth 2 state) ruby-indent-level)))))
+
+ (cond
+ (indent
+ (goto-char indent-point)
+ (end-of-line)
+ (setq eol (point))
+ (beginning-of-line)
+ (cond
+ ((re-search-forward ruby-negative eol t)
+ (and (not (eq ?_ (char-after (match-end 0))))
+ (setq indent (- indent ruby-indent-level))))
+ ;;operator terminated lines
+ ((and
+ (save-excursion
+ (beginning-of-line)
+ (not (bobp)))
+ (or (null (car (nth 1 state))) ;not in parens
+ (and (eq (car (nth 1 state)) ?\{)
+ (save-excursion ;except non-block braces
+ (goto-char (cdr (nth 1 state)))
+ (or (bobp) (forward-char -1))
+ (not (ruby-expr-beg))))))
+ ;; goto beginning of non-empty no-comment line
+ (let (end done)
+ (while (not done)
+ (skip-chars-backward " \t\n")
+ (setq end (point))
+ (beginning-of-line)
+ (if (re-search-forward "^\\s *#" end t)
+ (beginning-of-line)
+ (setq done t))))
+ (setq bol (point))
+ (end-of-line)
+ (skip-chars-backward " \t")
+ (or (bobp) (forward-char -1))
+ (and
+ (or (and (looking-at ruby-symbol-chars)
+ (skip-chars-backward ruby-symbol-chars)
+ (looking-at ruby-block-op-re))
+ (and (looking-at ruby-operator-chars)
+ (or (not (or (eq ?/ (char-after (point)))))
+ (null (nth 0 (ruby-parse-region parse-start (point)))))
+ (not (eq (char-after (1- (point))) ?$))
+ (or (not (eq ?| (char-after (point))))
+ (save-excursion
+ (or (eolp) (forward-char -1))
+ (and (search-backward "|")
+ (skip-chars-backward " \t\n")
+ (and (not (eolp))
+ (progn
+ (forward-char -1)
+ (not (looking-at "\\{")))
+ (progn
+ (forward-word -1)
+ (not (looking-at "do\\>[^_]")))))))))
+ (setq indent (+ indent ruby-indent-level)))))))
+ indent)))
+
+(defun ruby-electric-brace (arg)
+ (interactive "P")
+ (self-insert-command (prefix-numeric-value arg))
+ (ruby-indent-line t))
+
+(defun ruby-beginning-of-defun (&optional arg)
+ "Move backward to next beginning-of-defun.
+With argument, do this that many times.
+Returns t unless search stops due to end of buffer."
+ (interactive "p")
+ (and (re-search-backward (concat "^\\(" ruby-block-beg-re "\\)\\b")
+ nil 'move (or arg 1))
+ (progn (beginning-of-line) t)))
+
+(defun ruby-beginning-of-indent ()
+ (and (re-search-backward (concat "^\\(" ruby-indent-beg-re "\\)\\b")
+ nil 'move)
+ (progn
+ (beginning-of-line)
+ t)))
+
+(defun ruby-end-of-defun (&optional arg)
+ "Move forward to next end of defun.
+An end of a defun is found by moving forward from the beginning of one."
+ (interactive "p")
+ (and (re-search-forward (concat "^\\(" ruby-block-end-re "\\)\\b[^_]")
+ nil 'move (or arg 1))
+ (progn (beginning-of-line) t))
+ (forward-line 1))
+
+(defun ruby-move-to-block (n)
+ (let (start pos done down)
+ (setq start (ruby-calculate-indent))
+ (if (eobp)
+ nil
+ (while (and (not (bobp)) (not done))
+ (forward-line n)
+ (cond
+ ((looking-at "^$"))
+ ((looking-at "^\\s *#"))
+ (t
+ (setq pos (current-indentation))
+ (cond
+ ((< start pos)
+ (setq down t))
+ ((and down (= pos start))
+ (setq done t))
+ ((> start pos)
+ (setq done t)))))
+ (if done
+ (progn
+ (back-to-indentation)
+ (if (looking-at ruby-block-mid-re)
+ (setq done nil)))))))
+ (back-to-indentation))
+
+(defun ruby-beginning-of-block ()
+ "Move backward to next beginning-of-block"
+ (interactive)
+ (ruby-move-to-block -1))
+
+(defun ruby-end-of-block ()
+ "Move forward to next beginning-of-block"
+ (interactive)
+ (ruby-move-to-block 1))
+
+(defun ruby-reindent-then-newline-and-indent ()
+ (interactive "*")
+ (save-excursion
+ (delete-region (point) (progn (skip-chars-backward " \t") (point))))
+ (newline)
+ (save-excursion
+ (forward-line -1)
+ (indent-according-to-mode))
+ (indent-according-to-mode))
+
+(fset 'ruby-encomment-region (symbol-function 'comment-region))
+
+(defun ruby-decomment-region (beg end)
+ (interactive "r")
+ (save-excursion
+ (goto-char beg)
+ (while (re-search-forward "^\\([ \t]*\\)#" end t)
+ (replace-match "\\1" nil nil)
+ (save-excursion
+ (ruby-indent-line)))))
+
+(defun ruby-insert-end ()
+ (interactive)
+ (insert "end")
+ (ruby-indent-line t)
+ (end-of-line))
+
+(cond
+ ((featurep 'hilit19)
+ (hilit-set-mode-patterns
+ 'ruby-mode
+ '(("[^$\\?]\\(\"[^\\\"]*\\(\\\\\\(.\\|\n\\)[^\\\"]*\\)*\"\\)" 1 string)
+ ("[^$\\?]\\('[^\\']*\\(\\\\\\(.\\|\n\\)[^\\']*\\)*'\\)" 1 string)
+ ("[^$\\?]\\(`[^\\`]*\\(\\\\\\(.\\|\n\\)[^\\`]*\\)*`\\)" 1 string)
+ ("^\\s *#.*$" nil comment)
+ ("[^$@?\\]\\(#[^$@{].*$\\)" 1 comment)
+ ("[^a-zA-Z_]\\(\\?\\(\\\\[CM]-\\)*.\\)" 1 string)
+ ("^\\s *\\(require\\|load\\).*$" nil include)
+ ("^\\s *\\(include\\|alias\\|undef\\).*$" nil decl)
+ ("^\\s *\\<\\(class\\|def\\|module\\)\\>" "[)\n;]" defun)
+ ("[^_]\\<\\(begin\\|case\\|else\\|elsif\\|end\\|ensure\\|for\\|if\\|unless\\|rescue\\|then\\|when\\|while\\|until\\|do\\)\\>[^_]" 1 defun)
+ ("[^_]\\<\\(and\\|break\\|next\\|raise\\|fail\\|in\\|not\\|or\\|redo\\|retry\\|return\\|super\\|yield\\|self\\|nil\\)\\>[^_]" 1 keyword)
+ ("\\$\\(.\\|\\sw+\\)" nil type)
+ ("[$@].[a-zA-Z_0-9]*" nil struct)
+ ("^__END__" nil label))))
+
+ ((featurep 'font-lock)
+ (or (boundp 'font-lock-variable-name-face)
+ (setq font-lock-variable-name-face font-lock-type-face))
+ (defvar ruby-font-lock-keywords
+ (list
+ (cons (concat
+ "\\(^\\|[^_]\\)\\b\\("
+ (mapconcat
+ 'identity
+ '("alias"
+ "and"
+ "begin"
+ "break"
+ "case"
+ "class"
+ "do"
+ "elsif"
+ "else"
+ "fail"
+ "ensure"
+ "for"
+ "end"
+ "if"
+ "in"
+ "module"
+ "next"
+ "not"
+ "or"
+ "raise"
+ "redo"
+ "rescue"
+ "retry"
+ "return"
+ "then"
+ "self"
+ "super"
+ "unless"
+ "undef"
+ "until"
+ "when"
+ "while"
+ )
+ "\\|")
+ "\\)[ \n\t()]")
+ 2)
+ ;; variables
+ '("\\(^\\|[^_]\\)\\b\\(nil\\|self\\|true\\|false\\)\\b[^_]"
+ 2 font-lock-variable-name-face)
+ ;; variables
+ '("\\[$@].\\([a-zA-Z0-9_]\\)"
+ 0 font-lock-variable-name-face)
+ ;; constants
+ '("\\(^\\|[^_]\\)\\b\\([A-Z]+[a-zA-Z0-9_]*\\)"
+ 2 font-lock-type-face)
+ ;; functions
+ '("\\bdef[ \t]+\\([a-zA-Z_]+[a-zA-Z0-9_]*[?!=]?\\|\\[\\]=?\\)"
+ 0 font-lock-function-name-face))
+ "*Additional expressions to highlight in ruby mode.")
+ (if (and (>= (string-to-int emacs-version) 20)
+ (not (featurep 'xemacs)))
+ (add-hook
+ 'ruby-mode-hook
+ (lambda ()
+ (make-local-variable 'font-lock-defaults)
+ (setq font-lock-defaults
+ '((ruby-font-lock-keywords) nil nil ((?\_ . "w"))))))
+ (add-hook 'ruby-mode-hook
+ (lambda ()
+ (setq font-lock-keywords ruby-font-lock-keywords)
+ (font-lock-mode 1))))))
diff --git a/sample/rubydb2x.el b/sample/rubydb2x.el
new file mode 100644
index 0000000000..a74265fb0e
--- /dev/null
+++ b/sample/rubydb2x.el
@@ -0,0 +1,104 @@
+(require 'gud)
+(provide 'rubydb)
+
+;; ======================================================================
+;; rubydb functions
+
+;;; History of argument lists passed to rubydb.
+(defvar gud-rubydb-history nil)
+
+(defun gud-rubydb-massage-args (file args)
+ (cons "-I" (cons "." (cons "-r" (cons "debug" (cons file args))))))
+
+;; There's no guarantee that Emacs will hand the filter the entire
+;; marker at once; it could be broken up across several strings. We
+;; might even receive a big chunk with several markers in it. If we
+;; receive a chunk of text which looks like it might contain the
+;; beginning of a marker, we save it here between calls to the
+;; filter.
+(defvar gud-rubydb-marker-acc "")
+
+(defun gud-rubydb-marker-filter (string)
+ (save-match-data
+ (setq gud-marker-acc (concat gud-marker-acc string))
+ (let ((output ""))
+
+ ;; Process all the complete markers in this chunk.
+ (while (string-match "\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n"
+ gud-marker-acc)
+ (setq
+
+ ;; Extract the frame position from the marker.
+ gud-last-frame
+ (cons (substring gud-marker-acc (match-beginning 1) (match-end 1))
+ (string-to-int (substring gud-marker-acc
+ (match-beginning 2)
+ (match-end 2))))
+
+ ;; Append any text before the marker to the output we're going
+ ;; to return - we don't include the marker in this text.
+ output (concat output
+ (substring gud-marker-acc 0 (match-beginning 0)))
+
+ ;; Set the accumulator to the remaining text.
+ gud-marker-acc (substring gud-marker-acc (match-end 0))))
+
+ ;; Does the remaining text look like it might end with the
+ ;; beginning of another marker? If it does, then keep it in
+ ;; gud-marker-acc until we receive the rest of it. Since we
+ ;; know the full marker regexp above failed, it's pretty simple to
+ ;; test for marker starts.
+ (if (string-match "\032.*\\'" gud-marker-acc)
+ (progn
+ ;; Everything before the potential marker start can be output.
+ (setq output (concat output (substring gud-marker-acc
+ 0 (match-beginning 0))))
+
+ ;; Everything after, we save, to combine with later input.
+ (setq gud-marker-acc
+ (substring gud-marker-acc (match-beginning 0))))
+
+ (setq output (concat output gud-marker-acc)
+ gud-marker-acc ""))
+
+ output)))
+
+(defun gud-rubydb-find-file (f)
+ (find-file-noselect f))
+
+(defvar rubydb-command-name "ruby"
+ "File name for executing ruby.")
+
+;;;###autoload
+(defun rubydb (command-line)
+ "Run rubydb on program FILE in buffer *gud-FILE*.
+The directory containing FILE becomes the initial working directory
+and source-file directory for your debugger."
+ (interactive
+ (list (read-from-minibuffer "Run rubydb (like this): "
+ (if (consp gud-rubydb-history)
+ (car gud-rubydb-history)
+ (concat rubydb-command-name " "))
+ nil nil
+ '(gud-rubydb-history . 1))))
+
+ (gud-overload-functions '((gud-massage-args . gud-rubydb-massage-args)
+ (gud-marker-filter . gud-rubydb-marker-filter)
+ (gud-find-file . gud-rubydb-find-file)
+ ))
+ (gud-common-init command-line)
+
+ (gud-def gud-break "b %l" "\C-b" "Set breakpoint at current line.")
+; (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line")
+ (gud-def gud-step "s" "\C-s" "Step one source line with display.")
+ (gud-def gud-next "n" "\C-n" "Step one line (skip functions).")
+ (gud-def gud-cont "c" "\C-r" "Continue with display.")
+ (gud-def gud-finish "finish" "\C-f" "Finish executing current function.")
+ (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).")
+ (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).")
+ (gud-def gud-print "p %e" "\C-p" "Evaluate ruby expression at point.")
+
+ (setq comint-prompt-regexp "^(rdb:-) ")
+ (setq paragraph-start comint-prompt-regexp)
+ (run-hooks 'rubydb-mode-hook)
+ )
diff --git a/sample/rubydb3x.el b/sample/rubydb3x.el
new file mode 100644
index 0000000000..9d4e31f90e
--- /dev/null
+++ b/sample/rubydb3x.el
@@ -0,0 +1,104 @@
+(require 'gud)
+(provide 'rubydb)
+
+;; ======================================================================
+;; rubydb functions
+
+;;; History of argument lists passed to rubydb.
+(defvar gud-rubydb-history nil)
+
+(defun gud-rubydb-massage-args (file args)
+ (cons "-r" (cons "debug" args)))
+
+;; There's no guarantee that Emacs will hand the filter the entire
+;; marker at once; it could be broken up across several strings. We
+;; might even receive a big chunk with several markers in it. If we
+;; receive a chunk of text which looks like it might contain the
+;; beginning of a marker, we save it here between calls to the
+;; filter.
+(defvar gud-rubydb-marker-acc "")
+
+(defun gud-rubydb-marker-filter (string)
+ (setq gud-marker-acc (concat gud-marker-acc string))
+ (let ((output ""))
+
+ ;; Process all the complete markers in this chunk.
+ (while (string-match "\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n"
+ gud-marker-acc)
+ (setq
+
+ ;; Extract the frame position from the marker.
+ gud-last-frame
+ (cons (substring gud-marker-acc (match-beginning 1) (match-end 1))
+ (string-to-int (substring gud-marker-acc
+ (match-beginning 2)
+ (match-end 2))))
+
+ ;; Append any text before the marker to the output we're going
+ ;; to return - we don't include the marker in this text.
+ output (concat output
+ (substring gud-marker-acc 0 (match-beginning 0)))
+
+ ;; Set the accumulator to the remaining text.
+ gud-marker-acc (substring gud-marker-acc (match-end 0))))
+
+ ;; Does the remaining text look like it might end with the
+ ;; beginning of another marker? If it does, then keep it in
+ ;; gud-marker-acc until we receive the rest of it. Since we
+ ;; know the full marker regexp above failed, it's pretty simple to
+ ;; test for marker starts.
+ (if (string-match "\032.*\\'" gud-marker-acc)
+ (progn
+ ;; Everything before the potential marker start can be output.
+ (setq output (concat output (substring gud-marker-acc
+ 0 (match-beginning 0))))
+
+ ;; Everything after, we save, to combine with later input.
+ (setq gud-marker-acc
+ (substring gud-marker-acc (match-beginning 0))))
+
+ (setq output (concat output gud-marker-acc)
+ gud-marker-acc ""))
+
+ output))
+
+(defun gud-rubydb-find-file (f)
+ (save-excursion
+ (let ((buf (find-file-noselect f)))
+ (set-buffer buf)
+ (gud-make-debug-menu)
+ buf)))
+
+(defvar rubydb-command-name "ruby"
+ "File name for executing ruby.")
+
+;;;###autoload
+(defun rubydb (command-line)
+ "Run rubydb on program FILE in buffer *gud-FILE*.
+The directory containing FILE becomes the initial working directory
+and source-file directory for your debugger."
+ (interactive
+ (list (read-from-minibuffer "Run rubydb (like this): "
+ (if (consp gud-rubydb-history)
+ (car gud-rubydb-history)
+ (concat rubydb-command-name " "))
+ nil nil
+ '(gud-rubydb-history . 1))))
+
+ (gud-common-init command-line 'gud-rubydb-massage-args
+ 'gud-rubydb-marker-filter 'gud-rubydb-find-file)
+
+ (gud-def gud-break "b %l" "\C-b" "Set breakpoint at current line.")
+; (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line")
+ (gud-def gud-step "s" "\C-s" "Step one source line with display.")
+ (gud-def gud-next "n" "\C-n" "Step one line (skip functions).")
+ (gud-def gud-cont "c" "\C-r" "Continue with display.")
+ (gud-def gud-finish "finish" "\C-f" "Finish executing current function.")
+ (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).")
+ (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).")
+ (gud-def gud-print "p %e" "\C-p" "Evaluate ruby expression at point.")
+
+ (setq comint-prompt-regexp "^(rdb:-) ")
+ (setq paragraph-start comint-prompt-regexp)
+ (run-hooks 'rubydb-mode-hook)
+ )
diff --git a/sample/sieve.rb b/sample/sieve.rb
new file mode 100644
index 0000000000..03ff8a67f4
--- /dev/null
+++ b/sample/sieve.rb
@@ -0,0 +1,18 @@
+# sieve of Eratosthenes
+sieve = []
+if ! max = ARGV.shift; max = 100; end
+max = max.to_i
+
+print "1"
+for i in 2 .. max
+ begin
+ for d in sieve
+ fail if i % d == 0
+ end
+ print ", "
+ print i
+ sieve.push(i)
+ rescue
+ end
+end
+print "\n"
diff --git a/sample/svr.rb b/sample/svr.rb
new file mode 100644
index 0000000000..c866407eb0
--- /dev/null
+++ b/sample/svr.rb
@@ -0,0 +1,32 @@
+# socket example - server side
+# usage: ruby svr.rb
+
+require "socket"
+
+gs = TCPserver.open(0)
+addr = gs.addr
+addr.shift
+printf("server is on %d\n", addr.join(":"))
+socks = [gs]
+
+while TRUE
+ nsock = select(socks);
+ next if nsock == nil
+ for s in nsock[0]
+ if s == gs
+ ns = s.accept
+ socks.push(ns)
+ print(s, " is accepted\n")
+ else
+ if s.eof?
+ print(s, " is gone\n")
+ s.close
+ socks.delete(s)
+ else
+ if str = s.gets;
+ s.write(str)
+ end
+ end
+ end
+ end
+end
diff --git a/sample/test.rb b/sample/test.rb
new file mode 100644
index 0000000000..382ca9428a
--- /dev/null
+++ b/sample/test.rb
@@ -0,0 +1,943 @@
+#! /usr/local/bin/ruby
+
+$testnum=0
+$ntest=0
+$failed = 0
+
+def check(what)
+ printf "%s\n", what
+ $what = what
+ $testnum = 0
+end
+
+def ok(cond)
+ $testnum+=1
+ $ntest+=1
+ if cond
+ printf "ok %d\n", $testnum
+ else
+ where = caller[0]
+ printf "not ok %s %d -- %s\n", $what, $testnum, where
+ $failed+=1
+ end
+end
+
+# make sure conditional operators work
+
+check "condition"
+
+$x = '0';
+
+$x == $x && ok(TRUE)
+$x != $x && ok(FALSE)
+$x == $x || ok(FALSE)
+$x != $x || ok(TRUE)
+
+# first test to see if we can run the tests.
+
+check "if/unless";
+
+$x = 'test';
+ok(if $x == $x then TRUE else FALSE end)
+$bad = FALSE
+unless $x == $x
+ $bad = TRUE
+end
+ok(!$bad)
+ok(unless $x != $x then TRUE else FALSE end)
+
+check "case"
+
+case 5
+when 1, 2, 3, 4, 6, 7, 8
+ ok(FALSE)
+when 5
+ ok(TRUE)
+end
+
+case 5
+when 5
+ ok(TRUE)
+when 1..10
+ ok(FALSE)
+end
+
+case 5
+when 1..10
+ ok(TRUE)
+else
+ ok(FALSE)
+end
+
+case 5
+when 5
+ ok(TRUE)
+else
+ ok(FALSE)
+end
+
+case "foobar"
+when /^f.*r$/
+ ok(TRUE)
+else
+ ok(FALSE)
+end
+
+check "while/until";
+
+tmp = open("while_tmp", "w")
+tmp.print "tvi925\n";
+tmp.print "tvi920\n";
+tmp.print "vt100\n";
+tmp.print "Amiga\n";
+tmp.print "paper\n";
+tmp.close
+
+# test break
+
+tmp = open("while_tmp", "r")
+ok(tmp.kind_of?(File))
+
+while tmp.gets()
+ break if /vt100/
+end
+
+ok(!tmp.eof? && /vt100/)
+tmp.close
+
+# test next
+$bad = FALSE
+tmp = open("while_tmp", "r")
+while tmp.gets()
+ next if /vt100/;
+ $bad = 1 if /vt100/;
+end
+ok(!(!tmp.eof? || /vt100/ || $bad))
+tmp.close
+
+# test redo
+$bad = FALSE
+tmp = open("while_tmp", "r")
+while tmp.gets()
+ if gsub!('vt100', 'VT100')
+ gsub!('VT100', 'Vt100')
+ redo;
+ end
+ $bad = 1 if /vt100/;
+ $bad = 1 if /VT100/;
+end
+ok(tmp.eof? && !$bad)
+tmp.close
+
+sum=0
+for i in 1..10
+ sum += i
+ i -= 1
+ if i > 0
+ redo
+ end
+end
+ok(sum == 220)
+
+# test interval
+$bad = FALSE
+tmp = open("while_tmp", "r")
+while tmp.gets()
+ break unless 1..2
+ if /vt100/ || /Amiga/ || /paper/
+ $bad = TRUE
+ break
+ end
+end
+ok(!$bad)
+tmp.close
+
+File.unlink "while_tmp" or `/bin/rm -f "while_tmp"`
+ok(!File.exist?("while_tmp"))
+
+i = 0
+until i>4
+ i+=1
+end
+ok(i>4)
+
+# exception handling
+check "exception";
+
+begin
+ fail "this must be handled"
+ ok(FALSE)
+rescue
+ ok(TRUE)
+end
+
+$bad = TRUE
+begin
+ fail "this must be handled no.2"
+rescue
+ if $bad
+ $bad = FALSE
+ retry
+ ok(FALSE)
+ end
+end
+ok(TRUE)
+
+# exception in rescue clause
+$string = "this must be handled no.3"
+begin
+ begin
+ fail "exception in rescue clause"
+ rescue
+ fail $string
+ end
+ ok(FALSE)
+rescue
+ ok(TRUE) if $! == $string
+end
+
+# exception in ensure clause
+begin
+ begin
+ fail "this must be handled no.4"
+ ensure
+ fail "exception in ensure clause"
+ end
+ ok(FALSE)
+rescue
+ ok(TRUE)
+end
+
+$bad = TRUE
+begin
+ begin
+ fail "this must be handled no.5"
+ ensure
+ $bad = FALSE
+ end
+rescue
+end
+ok(!$bad)
+
+$bad = TRUE
+begin
+ begin
+ fail "this must be handled no.6"
+ ensure
+ $bad = FALSE
+ end
+rescue
+end
+ok(!$bad)
+
+$bad = TRUE
+while TRUE
+ begin
+ break
+ ensure
+ $bad = FALSE
+ end
+end
+ok(!$bad)
+
+check "array"
+ok([1, 2] + [3, 4] == [1, 2, 3, 4])
+ok([1, 2] * 2 == [1, 2, 1, 2])
+ok([1, 2] * ":" == "1:2")
+
+ok([1, 2].hash == [1, 2].hash)
+
+ok([1,2,3] & [2,3,4] == [2,3])
+ok([1,2,3] | [2,3,4] == [1,2,3,4])
+ok([1,2,3] - [2,3] == [1])
+
+$x = [0, 1, 2, 3, 4, 5]
+ok($x[2] == 2)
+ok($x[1..3] == [1, 2, 3])
+ok($x[1,3] == [1, 2, 3])
+
+$x[0, 2] = 10
+ok($x[0] == 10 && $x[1] == 2)
+
+$x[0, 0] = -1
+ok($x[0] == -1 && $x[1] == 10)
+
+$x[-1, 1] = 20
+ok($x[-1] == 20 && $x.pop == 20)
+
+# compact
+$x = [nil, 1, nil, nil, 5, nil, nil]
+$x.compact!
+ok($x == [1, 5])
+
+# empty?
+ok(!$x.empty?)
+$x = []
+ok($x.empty?)
+
+# sort
+$x = ["it", "came", "to", "pass", "that", "..."]
+$x = $x.sort.join(" ")
+ok($x == "... came it pass that to")
+$x = [2,5,3,1,7]
+$x.sort!{|a,b| a<=>b} # sort with condition
+ok($x == [1,2,3,5,7])
+$x.sort!{|a,b| b-a} # reverse sort
+ok($x == [7,5,3,2,1])
+
+# split test
+$x = "The Book of Mormon"
+ok($x.split(//).reverse!.join == "nomroM fo kooB ehT")
+ok("1 byte string".split(//).reverse.join(":") == "g:n:i:r:t:s: :e:t:y:b: :1")
+$x = "a b c d"
+ok($x.split == ['a', 'b', 'c', 'd'])
+ok($x.split(' ') == ['a', 'b', 'c', 'd'])
+
+$x = [1]
+ok(($x * 5).join(":") == '1:1:1:1:1')
+ok(($x * 1).join(":") == '1')
+ok(($x * 0).join(":") == '')
+
+*$x = 1..7
+ok($x.size == 7)
+ok($x == [1, 2, 3, 4, 5, 6, 7])
+
+check "hash"
+$x = {1=>2, 2=>4, 3=>6}
+$y = {1, 2, 2, 4, 3, 6}
+
+ok($x[1] == 2)
+
+ok(begin
+ for k,v in $y
+ fail if k*2 != v
+ end
+ TRUE
+ rescue
+ FALSE
+ end)
+
+ok($x.length == 3)
+ok($x.has_key?(1))
+ok($x.has_value?(4))
+ok($x.indexes(2,3) == [4,6])
+ok($x == (1=>2, 2=>4, 3=>6))
+
+$z = $y.keys.join(":")
+ok($z == "1:2:3")
+
+$z = $y.values.join(":")
+ok($z == "2:4:6")
+ok($x == $y)
+
+$y.shift
+ok($y.length == 2)
+
+$z = [1,2]
+$y[$z] = 256
+ok($y[$z] == 256)
+
+check "iterator"
+
+ok(!iterator?)
+
+def ttt
+ ok(iterator?)
+end
+ttt{}
+
+# yield at top level
+ok(!defined?(yield))
+
+$x = [1, 2, 3, 4]
+$y = []
+
+# iterator over array
+for i in $x
+ $y.push i
+end
+ok($x == $y)
+
+# nested iterator
+def tt
+ 1.upto(10) {|i|
+ yield i
+ }
+end
+
+tt{|i| break if i == 5}
+ok(i == 5)
+
+# iterator break/redo/next/retry
+unless defined? loop
+ def loop
+ while TRUE
+ yield
+ end
+ end
+ ok(FALSE)
+else
+ ok(TRUE)
+end
+
+done = TRUE
+loop{
+ break
+ done = FALSE
+}
+ok(done)
+
+done = FALSE
+$bad = FALSE
+loop {
+ break if done
+ done = TRUE
+ next
+ $bad = TRUE
+}
+ok(!$bad)
+
+done = FALSE
+$bad = FALSE
+loop {
+ break if done
+ done = TRUE
+ redo
+ $bad = TRUE
+}
+ok(!$bad)
+
+$x = []
+for i in 1 .. 7
+ $x.push i
+end
+ok($x.size == 7)
+ok($x == [1, 2, 3, 4, 5, 6, 7])
+
+$done = FALSE
+$x = []
+for i in 1 .. 7 # see how retry works in iterator loop
+ if i == 4 and not $done
+ $done = TRUE
+ retry
+ end
+ $x.push(i)
+end
+ok($x.size == 10)
+ok($x == [1, 2, 3, 1, 2, 3, 4, 5, 6, 7])
+
+check "bignum"
+def fact(n)
+ return 1 if n == 0
+ f = 1
+ while n>0
+ f *= n
+ n -= 1
+ end
+ return f
+end
+fact(3)
+$x = fact(40)
+ok($x == $x)
+ok($x == fact(40))
+ok($x < $x+2)
+ok($x > $x-2)
+ok($x == 815915283247897734345611269596115894272000000000)
+ok($x != 815915283247897734345611269596115894272000000001)
+ok($x+1 == 815915283247897734345611269596115894272000000001)
+ok($x/fact(20) == 335367096786357081410764800000)
+$x = -$x
+ok($x == -815915283247897734345611269596115894272000000000)
+ok(2-(2**32) == -(2**32-2))
+ok(2**32 - 5 == (2**32-3)-2)
+
+$good = TRUE;
+for i in 1000..1024
+ $good = FALSE if ((1<<i) != (2**i))
+end
+ok($good)
+
+$good = TRUE;
+n1=1<<1000
+for i in 1000..1024
+ $good = FALSE if ((1<<i) != n1)
+ n1 *= 2
+end
+ok($good)
+
+$good = TRUE;
+n2=n1
+for i in 1..10
+ n1 = n1 / 2
+ n2 = n2 >> 1
+ $good = FALSE if (n1 != n2)
+end
+ok($good)
+
+$good = TRUE;
+for i in 4000..4192
+ n1 = 1 << i;
+ $good = FALSE if ((n1**2-1) / (n1+1) != (n1-1))
+end
+ok($good)
+
+check "string & char"
+
+ok("abcd" == "abcd")
+ok("abcd" =~ "abcd")
+ok("abcd" === "abcd")
+ok(("abc" =~ /^$/) == FALSE)
+ok(("abc\n" =~ /^$/) == FALSE)
+ok(("abc" =~ /^d*$/) == FALSE)
+ok(("abc" =~ /d*$/) == 3)
+ok("" =~ /^$/)
+ok("\n" =~ /^$/)
+ok("a\n\n" =~ /^$/)
+
+$foo = "abc"
+ok("#$foo = abc" == "abc = abc")
+ok("#{$foo} = abc" == "abc = abc")
+
+foo = "abc"
+ok("#{foo} = abc" == "abc = abc")
+
+ok('-' * 5 == '-----')
+ok('-' * 1 == '-')
+ok('-' * 0 == '')
+
+foo = '-'
+ok(foo * 5 == '-----')
+ok(foo * 1 == '-')
+ok(foo * 0 == '')
+
+$x = "a.gif"
+ok($x.sub(/.*\.([^\.]+)$/, '\1') == "gif")
+ok($x.sub(/.*\.([^\.]+)$/, 'b.\1') == "b.gif")
+ok($x.sub(/.*\.([^\.]+)$/, '\2') == "")
+ok($x.sub(/.*\.([^\.]+)$/, 'a\2b') == "ab")
+ok($x.sub(/.*\.([^\.]+)$/, '<\&>') == "<a.gif>")
+
+# character constants(assumes ASCII)
+ok("a"[0] == ?a)
+ok(?a == ?a)
+ok(?\C-a == 1)
+ok(?\M-a == 225)
+ok(?\M-\C-a == 129)
+
+$x = "abcdef"
+$y = [ ?a, ?b, ?c, ?d, ?e, ?f ]
+$bad = FALSE
+$x.each_byte {|i|
+ if i != $y.shift
+ $bad = TRUE
+ break
+ end
+}
+ok(!$bad)
+
+check "asignment"
+a = nil
+ok(defined?(a))
+ok(a == nil)
+
+# multiple asignment
+a, b = 1, 2
+ok(a == 1 && b == 2)
+
+a, b = b, a
+ok(a == 2 && b == 1)
+
+a, = 1,2
+ok(a == 1)
+
+a, *b = 1, 2, 3
+ok(a == 1 && b == [2, 3])
+
+*a = 1, 2, 3
+ok(a == [1, 2, 3])
+
+check "call"
+def aaa(a, b=100, *rest)
+ res = [a, b]
+ res += rest if rest
+ return res
+end
+
+# not enough argument
+begin
+ aaa() # need at least 1 arg
+ ok(FALSE)
+rescue
+ ok(TRUE)
+end
+
+begin
+ aaa # no arg given (exception raised)
+ ok(FALSE)
+rescue
+ ok(TRUE)
+end
+
+begin
+ if aaa(1) == [1, 100]
+ ok(TRUE)
+ else
+ fail
+ end
+rescue
+ ok(FALSE)
+end
+
+begin
+ if aaa(1, 2) == [1, 2]
+ ok(TRUE)
+ else
+ fail
+ end
+rescue
+ ok(FALSE)
+end
+
+ok(aaa(1, 2, 3, 4) == [1, 2, 3, 4])
+ok(aaa(1, *[2, 3, 4]) == [1, 2, 3, 4])
+
+check "proc"
+$proc = proc{|i| i}
+ok($proc.call(2) == 2)
+ok($proc.call(3) == 3)
+
+$proc = proc{|i| i*2}
+ok($proc.call(2) == 4)
+ok($proc.call(3) == 6)
+
+proc{
+ iii=5 # dynamic local variable
+ $proc = proc{|i|
+ iii = i
+ }
+ $proc2 = proc {
+ $x = iii # dynamic variables shared by procs
+ }
+ # scope of dynamic variables
+ ok(defined?(iii))
+}.call
+ok(!defined?(iii)) # out of scope
+
+$x=0
+$proc.call(5)
+$proc2.call
+ok($x == 5)
+
+if defined? Process.kill
+ check "signal"
+
+ $x = 0
+ trap "SIGINT", proc{|sig| $x = 2}
+ Process.kill "SIGINT", $$
+ sleep 0.1
+ ok($x == 2)
+
+ trap "SIGINT", proc{fail "Interrupt"}
+
+ x = FALSE
+ begin
+ Process.kill "SIGINT", $$
+ sleep 0.1
+ rescue
+ x = $!
+ end
+ ok(x && x =~ /Interrupt/)
+else
+ ok(FALSE)
+end
+
+check "eval"
+ok(eval("") == nil)
+$bad=FALSE
+eval 'while FALSE; $bad = TRUE; print "foo\n" end'
+ok(!$bad)
+
+ok(eval('TRUE'))
+
+$foo = 'ok(TRUE)'
+begin
+ eval $foo
+rescue
+ ok(FALSE)
+end
+
+ok(eval("$foo") == 'ok(TRUE)')
+ok(eval("TRUE") == TRUE)
+i = 5
+ok(eval("i == 5"))
+ok(eval("i") == 5)
+ok(eval("defined? i"))
+
+# eval with binding
+def test_ev
+ local1 = "local1"
+ lambda {
+ local2 = "local2"
+ return binding
+ }.call
+end
+
+$x = test_ev
+ok(eval("local1", $x) == "local1") # static local var
+ok(eval("local2", $x) == "local2") # dynamic local var
+$bad = TRUE
+begin
+ p eval("local1")
+rescue NameError # must raise error
+ $bad = FALSE
+end
+ok(!$bad)
+
+module EvTest
+ EVTEST1 = 25
+ evtest2 = 125
+ $x = binding
+end
+ok(eval("EVTEST1", $x) == 25) # constant in module
+ok(eval("evtest2", $x) == 125) # local var in module
+$bad = TRUE
+begin
+ eval("EVTEST1")
+rescue NameError # must raise error
+ $bad = FALSE
+end
+ok(!$bad)
+
+check "system"
+ok(`echo foobar` == "foobar\n")
+ok(`./ruby -e 'print "foobar"'` == 'foobar')
+
+tmp = open("script_tmp", "w")
+tmp.print "print $zzz\n";
+tmp.close
+
+ok(`./ruby -s script_tmp -zzz` == 'TRUE')
+ok(`./ruby -s script_tmp -zzz=555` == '555')
+
+tmp = open("script_tmp", "w")
+tmp.print "#! /usr/local/bin/ruby -s\n";
+tmp.print "print $zzz\n";
+tmp.close
+
+ok(`./ruby script_tmp -zzz=678` == '678')
+
+tmp = open("script_tmp", "w")
+tmp.print "this is a leading junk\n";
+tmp.print "#! /usr/local/bin/ruby -s\n";
+tmp.print "print $zzz\n";
+tmp.print "__END__\n";
+tmp.print "this is a trailing junk\n";
+tmp.close
+
+ok(`./ruby -x script_tmp` == 'nil')
+ok(`./ruby -x script_tmp -zzz=555` == '555')
+
+tmp = open("script_tmp", "w")
+for i in 1..5
+ tmp.print i, "\n"
+end
+tmp.close
+
+`./ruby -i.bak -pe 'sub(/^[0-9]+$/){$&.to_i * 5}' script_tmp`
+done = TRUE
+tmp = open("script_tmp", "r")
+while tmp.gets
+ if $_.to_i % 5 != 0
+ done = FALSE
+ break
+ end
+end
+tmp.close
+ok(done)
+
+File.unlink "script_tmp" or `/bin/rm -f "script_tmp"`
+File.unlink "script_tmp.bak" or `/bin/rm -f "script_tmp.bak"`
+
+check "const"
+TEST1 = 1
+TEST2 = 2
+
+module Const
+ TEST3 = 3
+ TEST4 = 4
+end
+
+module Const2
+ TEST3 = 6
+ TEST4 = 8
+end
+
+include Const
+
+ok([TEST1,TEST2,TEST3,TEST4] == [1,2,3,4])
+
+include Const2
+STDERR.print "intentionally redefines TEST3, TEST4\n" if $VERBOSE
+ok([TEST1,TEST2,TEST3,TEST4] == [1,2,6,8])
+
+check "clone"
+foo = Object.new
+def foo.test
+ "test"
+end
+bar = foo.clone
+def bar.test2
+ "test2"
+end
+
+ok(bar.test2 == "test2")
+ok(bar.test == "test")
+ok(foo.test == "test")
+
+begin
+ foo.test2
+ ok FALSE
+rescue
+ ok TRUE
+end
+
+check "pack"
+
+$format = "c2x5CCxsdila6";
+# Need the expression in here to force ary[5] to be numeric. This avoids
+# test2 failing because ary2 goes str->numeric->str and ary does not.
+ary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,"abcdef"]
+$x = ary.pack($format)
+ary2 = $x.unpack($format)
+
+ok(ary.length == ary2.length)
+ok(ary.join(':') == ary2.join(':'))
+ok($x =~ /def/)
+
+check "math"
+ok(Math.sqrt(4) == 2)
+
+include Math
+ok(sqrt(4) == 2)
+
+check "struct"
+struct_test = Struct.new("Test", :foo, :bar)
+ok(struct_test == Struct::Test)
+
+test = struct_test.new(1, 2)
+ok(test.foo == 1 && test.bar == 2)
+ok(test[0] == 1 && test[1] == 2)
+
+a, b = test
+ok(a == 1 && b == 2)
+
+test[0] = 22
+ok(test.foo == 22)
+
+test.bar = 47
+ok(test.bar == 47)
+
+check "variable"
+ok($$.instance_of?(Fixnum))
+
+# read-only variable
+begin
+ $$ = 5
+ ok FALSE
+rescue
+ ok TRUE
+end
+
+foobar = "foobar"
+$_ = foobar
+ok($_ == foobar)
+
+check "trace"
+$x = 1234
+$y = 0
+trace_var :$x, proc{$y = $x}
+$x = 40414
+ok($y == $x)
+
+untrace_var :$x
+$x = 19660208
+ok($y != $x)
+
+trace_var :$x, proc{$x *= 2}
+$x = 5
+ok($x == 10)
+
+untrace_var :$x
+
+check "defined?"
+
+ok(defined?($x)) # global variable
+ok(defined?($x) == 'global-variable')# returns description
+
+foo=5
+ok(defined?(foo)) # local variable
+
+ok(defined?(Array)) # constant
+ok(defined?(Object.new)) # method
+ok(!defined?(Object.print)) # private method
+ok(defined?(1 == 2)) # operator expression
+
+def defined_test
+ return !defined?(yield)
+end
+
+ok(defined_test) # not iterator
+ok(!defined_test{}) # called as iterator
+
+check "alias"
+class Alias0
+ def foo; "foo" end
+end
+class Alias1<Alias0
+ alias bar foo
+ def foo; "foo+" + super end
+end
+class Alias2<Alias1
+ alias baz foo
+ undef foo
+end
+
+x = Alias2.new
+ok(x.bar == "foo")
+ok(x.baz == "foo+foo")
+
+# check for cache
+ok(x.baz == "foo+foo")
+
+class Alias3<Alias2
+ def foo
+ defined? super
+ end
+ def bar
+ defined? super
+ end
+ def quux
+ defined? super
+ end
+end
+x = Alias3.new
+ok(!x.foo)
+ok(x.bar)
+ok(!x.quux)
+
+check "gc"
+begin
+ 1.upto(10000) {
+ tmp = [0,1,2,3,4,5,6,7,8,9]
+ }
+ tmp = nil
+ ok TRUE
+rescue
+ ok FALSE
+end
+
+if $failed > 0
+ printf "test: %d failed %d\n", $ntest, $failed
+else
+ printf "end of test(test: %d)\n", $ntest
+end
diff --git a/sample/time.rb b/sample/time.rb
new file mode 100644
index 0000000000..f4f4ec4883
--- /dev/null
+++ b/sample/time.rb
@@ -0,0 +1,8 @@
+#! /usr/local/bin/ruby
+cmd = ARGV.join(" ")
+b = Time.now
+system(cmd)
+e = Time.now
+ut, st, cut, cst = Time.times
+total = (e - b).to_f
+printf STDERR, "%11.1f real %11.1f user %11.1f sys\n", total, cut, cst
diff --git a/sample/tkbiff.rb b/sample/tkbiff.rb
new file mode 100644
index 0000000000..d2d7bf7beb
--- /dev/null
+++ b/sample/tkbiff.rb
@@ -0,0 +1,149 @@
+#! /usr/local/bin/ruby
+
+if ARGV[0] != '-d'
+ unless $DEBUG
+ exit if fork
+ end
+else
+ ARGV.shift
+end
+
+if ARGV.length == 0
+ if ENV['MAIL']
+ $spool = ENV['MAIL']
+ else
+ $spool = '/usr/spool/mail/' + ENV['USER']
+ end
+else
+ $spool = ARGV[0]
+end
+
+require "parsedate"
+require "base64"
+
+include ParseDate
+
+class Mail
+ def Mail.new(f)
+ if !f.kind_of?(IO)
+ f = open(f, "r")
+ me = super
+ f.close
+ else
+ me = super
+ end
+ return me
+ end
+
+ def initialize(f)
+ @header = {}
+ @body = []
+ while f.gets()
+ $_.chop!
+ next if /^From / # skip From-line
+ break if /^$/ # end of header
+ if /^(\S+):\s*(.*)/
+ @header[attr = $1.capitalize] = $2
+ elsif attr
+ sub(/^\s*/, '')
+ @header[attr] += "\n" + $_
+ end
+ end
+
+ return if ! $_
+
+ while f.gets()
+ break if /^From /
+ @body.push($_)
+ end
+ end
+
+ def header
+ return @header
+ end
+
+ def body
+ return @body
+ end
+
+end
+
+require "tkscrollbox"
+
+$top = TkRoot.new
+$top.withdraw
+$list = TkScrollbox.new($top) {
+ relief 'raised'
+ width 80
+ height 8
+ setgrid 'yes'
+ pack
+}
+TkButton.new($top) {
+ text 'Dismiss'
+ command proc {$top.withdraw}
+ pack('fill'=>'both','expand'=>'yes')
+}
+$top.bind "Control-c", proc{exit}
+$top.bind "Control-q", proc{exit}
+$top.bind "space", proc{exit}
+
+$spool_size = 0
+$check_time = Time.now
+
+def check
+ $check_time = Time.now
+ size = File.size($spool)
+ if size and size != $spool_size
+ $spool_size = size
+ pop_up if size > 0
+ end
+ Tk.after 5000, proc{check}
+end
+
+if defined? Thread
+ Thread.start do
+ loop do
+ sleep 600
+ if Time.now - $check_time > 200
+ Tk.after 5000, proc{check}
+ end
+ end
+ end
+end
+
+def pop_up
+ outcount = 0;
+ $list.delete 0, 'end'
+ f = open($spool, "r")
+ while !f.eof?
+ mail = Mail.new(f)
+ date, from, subj = mail.header['Date'], mail.header['From'], mail.header['Subject']
+ next if !date
+ y = m = d = 0
+ y, m, d = parsedate(date) if date
+ from = "sombody@somewhere" if ! from
+ subj = "(nil)" if ! subj
+ from = decode_b(from)
+ subj = decode_b(subj)
+ $list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj)
+ outcount += 1
+ end
+ f.close
+ if outcount == 0
+ $list.insert 'end', "You have no mail."
+ else
+ $list.see 'end'
+ end
+ $top.deiconify
+ Tk.after 2000, proc{$top.withdraw}
+end
+
+$list.insert 'end', "You have no mail."
+check
+Tk.after 2000, proc{$top.withdraw}
+begin
+ Tk.mainloop
+rescue
+ `echo #$! > /tmp/tkbiff`
+end
diff --git a/sample/tkbrowse.rb b/sample/tkbrowse.rb
new file mode 100644
index 0000000000..d127996173
--- /dev/null
+++ b/sample/tkbrowse.rb
@@ -0,0 +1,69 @@
+#!/usr/local/bin/ruby
+#
+# This script generates a directory browser, which lists the working
+# directory and allows you to open files or subdirectories by
+# double-clicking.
+
+# Create a scrollbar on the right side of the main window and a listbox
+# on the left side.
+
+require "tkscrollbox"
+
+list = TkScrollbox.new {
+ relief 'raised'
+ width 20
+ height 20
+ setgrid 'yes'
+ pack
+}
+
+# The procedure below is invoked to open a browser on a given file; if the
+# file is a directory then another instance of this program is invoked; if
+# the file is a regular file then the Mx editor is invoked to display
+# the file.
+
+def browse (dir, file)
+ if dir != "."
+ file="#{dir}/#{file}"
+ if File.directory? file
+ system "browse #{file} &"
+ else
+ if File.file? file
+ if ENV['EDITOR']
+ system format("%s %s&", ENV['EDITOR'], file)
+ else
+ sysmte "xedit #{file}&"
+ end
+ else
+ STDERR.print "\"#{file}\" isn't a directory or regular file"
+ end
+ end
+ end
+end
+
+# Fill the listbox with a list of all the files in the directory (run
+# the "ls" command to get that information).
+
+if ARGV.length>0
+ dir = ARGV[0]
+else
+ dir="."
+end
+list.insert 'end', *`ls #{dir}`.split
+
+# Set up bindings for the browser.
+
+list.focus
+list.bind "Control-q", proc{exit}
+list.bind "Control-c", proc{exit}
+list.bind "Control-p", proc{
+ print "selection <", TkSelection.get, ">\n"
+}
+
+list.bind "Double-Button-1", proc{
+ for i in TkSelection.get.split
+ print "clicked ", i, "\n"
+ browse dir, i
+ end
+}
+Tk.mainloop
diff --git a/sample/tkdialog.rb b/sample/tkdialog.rb
new file mode 100644
index 0000000000..e83e16d0a8
--- /dev/null
+++ b/sample/tkdialog.rb
@@ -0,0 +1,62 @@
+#! /usr/local/bin/ruby
+require "tk"
+
+root = TkFrame.new
+top = TkFrame.new(root) {
+ relief 'raised'
+ border 1
+}
+msg = TkMessage.new(top) {
+ text "File main.c hasn't been saved to disk since \
+it was last modified. What should I do?"
+ justify 'center'
+ aspect 200
+ font '-Adobe-helvetica-medium-r-normal--*-240*'
+ pack('padx'=>5, 'pady'=>5, 'expand'=>'yes')
+}
+top.pack('fill'=>'both')
+root.pack
+
+bot = TkFrame.new(root) {
+ relief 'raised'
+ border 1
+}
+
+TkFrame.new(bot) { |left|
+ relief 'sunken'
+ border 1
+ pack('side'=>'left', 'expand'=>'yes', 'padx'=>10, 'pady'=> 10)
+ TkButton.new(left) {
+ text "Save File"
+ command "quit 'save'"
+ pack('expand'=>'yes','padx'=>6,'pady'=> 6)
+ top.bind "Enter", proc{state 'active'}
+ msg.bind "Enter", proc{state 'active'}
+ bot.bind "Enter", proc{state 'active'}
+ top.bind "Leave", proc{state 'normal'}
+ msg.bind "Leave", proc{state 'normal'}
+ bot.bind "Leave", proc{state 'normal'}
+ Tk.root.bind "ButtonRelease-1", proc{quit 'save'}
+ Tk.root.bind "Return", proc{quit 'save'}
+ }
+}
+TkButton.new(bot) {
+ text "Quit Anyway"
+ command "quit 'quit'"
+ pack('side'=>'left', 'expand'=>'yes', 'padx'=>10)
+}
+TkButton.new(bot) {
+ text "Return To Editor"
+ command "quit 'return'"
+ pack('side'=>'left', 'expand'=>'yes', 'padx'=>10)
+}
+bot.pack
+root.pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes')
+
+def quit(button)
+ print "aaa\n"
+ print "You pressed the \"#{button}\" button; bye-bye!\n"
+ exit
+end
+
+Tk.mainloop
diff --git a/sample/tkfrom.rb b/sample/tkfrom.rb
new file mode 100644
index 0000000000..b0ef8995ca
--- /dev/null
+++ b/sample/tkfrom.rb
@@ -0,0 +1,126 @@
+#! /usr/local/bin/ruby
+
+require "parsedate"
+require "base64"
+
+include ParseDate
+
+class Mail
+ def Mail.new(f)
+ if !f.kind_of?(IO)
+ f = open(f, "r")
+ me = super(f)
+ f.close
+ else
+ me = super
+ end
+ return me
+ end
+
+ def initialize(f)
+ @header = {}
+ @body = []
+ while f.gets()
+ $_.chop!
+ next if /^From / # skip From-line
+ break if /^$/ # end of header
+ if /^(\S+):\s*(.*)/
+ @header[attr = $1.capitalize] = $2
+ elsif attr
+ sub(/^\s*/, '')
+ @header[attr] += "\n" + $_
+ end
+ end
+
+ return if ! $_
+
+ while f.gets()
+ break if /^From /
+ @body.push($_)
+ end
+ end
+
+ def header
+ return @header
+ end
+
+ def body
+ return @body
+ end
+
+end
+
+if ARGV.length == 0
+ if ENV['MAIL']
+ ARGV[0] = ENV['MAIL']
+ elsif ENV['USER']
+ ARGV[0] = '/usr/spool/mail/' + ENV['USER']
+ elsif ENV['LOGNAME']
+ ARGV[0] = '/usr/spool/mail/' + ENV['LOGNAME']
+ end
+end
+
+require "tk"
+list = scroll = nil
+TkFrame.new{|f|
+ list = TkListbox.new(f) {
+ yscroll proc{|idx|
+ scroll.set *idx
+ }
+ relief 'raised'
+# geometry "80x5"
+ width 80
+ height 5
+ setgrid 'yes'
+ pack('side'=>'left','fill'=>'both','expand'=>'yes')
+ }
+ scroll = TkScrollbar.new(f) {
+ command proc{|idx|
+ list.yview *idx
+ }
+ pack('side'=>'right','fill'=>'y')
+ }
+ pack
+}
+root = Tk.root
+TkButton.new(root) {
+ text 'Dismiss'
+ command proc {exit}
+ pack('fill'=>'both','expand'=>'yes')
+}
+root.bind "Control-c", proc{exit}
+root.bind "Control-q", proc{exit}
+root.bind "space", proc{exit}
+
+$outcount = 0;
+for file in ARGV
+ next if !File.exist?(file)
+ f = open(file, "r")
+ while !f.eof
+ mail = Mail.new(f)
+ date = mail.header['Date']
+ next if !date
+ from = mail.header['From']
+ subj = mail.header['Subject']
+ y = m = d = 0
+ y, m, d = parsedate(date) if date
+ from = "sombody@somewhere" if ! from
+ subj = "(nil)" if ! subj
+ from = decode_b(from)
+ subj = decode_b(subj)
+ list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj)
+ $outcount += 1
+ end
+ f.close
+ list.see 'end'
+end
+
+limit = 10000
+if $outcount == 0
+ list.insert 'end', "You have no mail."
+ limit = 2000
+end
+Tk.after limit, proc{
+ exit
+}
+Tk.mainloop
diff --git a/sample/tkhello.rb b/sample/tkhello.rb
new file mode 100644
index 0000000000..1ff1403e71
--- /dev/null
+++ b/sample/tkhello.rb
@@ -0,0 +1,13 @@
+require "tk"
+
+TkButton.new {
+ text 'hello'
+ command proc{print "hello\n"}
+ pack('fill'=>'x')
+}
+TkButton.new {
+ text 'quit'
+ command 'exit'
+ pack('fill'=>'x')
+}
+Tk.mainloop
diff --git a/sample/tkline.rb b/sample/tkline.rb
new file mode 100644
index 0000000000..63d763a680
--- /dev/null
+++ b/sample/tkline.rb
@@ -0,0 +1,46 @@
+
+$tk_thread_safe = TRUE
+require "tkclass"
+
+$tkline_init = FALSE
+def start_random
+ return if $tkline_init
+ $tkline_init = TRUE
+ if defined? Thread
+ Thread.start do
+ loop do
+ sleep 2
+ Line.new($c, rand(400), rand(200), rand(400), rand(200))
+ end
+ end
+ end
+end
+
+$c = Canvas.new
+$c.pack
+$start_x = start_y = 0
+
+def do_press(x, y)
+ $start_x = x
+ $start_y = y
+ $current_line = Line.new($c, x, y, x, y)
+ start_random
+end
+def do_motion(x, y)
+ if $current_line
+ $current_line.coords $start_x, $start_y, x, y
+ end
+end
+
+def do_release(x, y)
+ if $current_line
+ $current_line.coords $start_x, $start_y, x, y
+ $current_line.fill 'black'
+ $current_line = nil
+ end
+end
+
+$c.bind("1", proc{|e| do_press e.x, e.y})
+$c.bind("B1-Motion", proc{|x, y| do_motion x, y}, "%x %y")
+$c.bind("ButtonRelease-1", proc{|x, y| do_release x, y}, "%x %y")
+Tk.mainloop
diff --git a/sample/tktimer.rb b/sample/tktimer.rb
new file mode 100644
index 0000000000..34377e2f39
--- /dev/null
+++ b/sample/tktimer.rb
@@ -0,0 +1,50 @@
+#!/usr/local/bin/ruby
+# This script generates a counter with start and stop buttons.
+
+require "tk"
+$label = TkLabel.new {
+ text '0.00'
+ relief 'raised'
+ width 10
+ pack('side'=>'bottom', 'fill'=>'both')
+}
+
+TkButton.new {
+ text 'Start'
+ command proc {
+ if $stopped
+ $stopped = FALSE
+ tick
+ end
+ }
+ pack('side'=>'left','fill'=>'both','expand'=>'yes')
+}
+TkButton.new {
+ text 'Stop'
+ command proc{
+ exit if $stopped
+ $stopped = TRUE
+ }
+ pack('side'=>'right','fill'=>'both','expand'=>'yes')
+}
+
+$seconds=0
+$hundredths=0
+$stopped=TRUE
+
+def tick
+ if $stopped then return end
+ Tk.after 50, proc{tick}
+ $hundredths+=5
+ if $hundredths >= 100
+ $hundredths=0
+ $seconds+=1
+ end
+ $label.text format("%d.%02d", $seconds, $hundredths)
+end
+
+root = Tk.root
+root.bind "Control-c", proc{root.destroy}
+root.bind "Control-q", proc{root.destroy}
+Tk.root.focus
+Tk.mainloop
diff --git a/sample/trojan.rb b/sample/trojan.rb
new file mode 100644
index 0000000000..2024da0908
--- /dev/null
+++ b/sample/trojan.rb
@@ -0,0 +1,14 @@
+#! /usr/local/bin/ruby
+path = ENV['PATH'].split(/:/)
+
+for dir in path
+ if File.d(dir)
+ for f in d = Dir.open(dir)
+ fpath = dir+"/"+f
+ if File.f(fpath) && (File.stat(fpath).mode & 022) != 0
+ printf("file %s is writable from other users\n", fpath)
+ end
+ end
+ d.close
+ end
+end
diff --git a/sample/tsvr.rb b/sample/tsvr.rb
new file mode 100644
index 0000000000..fbc6545bb5
--- /dev/null
+++ b/sample/tsvr.rb
@@ -0,0 +1,23 @@
+# socket example - server side using thread
+# usage: ruby tsvr.rb
+
+require "socket"
+require "thread"
+
+gs = TCPserver.open(0)
+addr = gs.addr
+addr.shift
+printf("server is on %d\n", addr.join(":"))
+
+while TRUE
+ ns = gs.accept
+ print(ns, " is accepted\n")
+ Thread.start do
+ s = ns # save to dynamic variable
+ while s.gets
+ s.write($_)
+ end
+ print(s, " is gone\n")
+ s.close
+ end
+end
diff --git a/sample/uumerge.rb b/sample/uumerge.rb
new file mode 100644
index 0000000000..297b08f26a
--- /dev/null
+++ b/sample/uumerge.rb
@@ -0,0 +1,37 @@
+#!/usr/local/bin/ruby
+
+if ARGV[0] == "-c"
+ out_stdout = 1;
+ ARGV.shift
+end
+
+while gets()
+ if /^begin\s*(\d*)\s*(\S*)/
+ $mode, $file = $1, $2
+ $sawbegin+=1
+ break
+ end
+end
+
+fail "missing begin" if ! $sawbegin;
+
+if out_stdout
+ out = STDOUT
+else
+ out = open($file, "w") if $file != "";
+end
+
+while gets()
+ if /^end/
+ $sawend+=1
+ break
+ end
+ sub(/[a-z]+$/, ""); # handle stupid trailing lowercase letters
+ next if /[a-z]/
+ next if !(((($_[0] - 32) & 077) + 2) / 3 == $_.length / 4)
+ out << $_.unpack("u");
+end
+
+fail "missing end" if !$sawend;
+File.chmod $mode.oct, $file if ! out_stdout
+exit 0;